CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Can anyone have a look at this code?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
SKROTNISSE
Guest







Can anyone have a look at this code?
PostPosted: Sat May 24, 2003 11:48 pm     Reply with quote

Hello people.
I'm trying to find max value from pulse 1 and max value from pulse 2 to find the time between them. But my program seems to do whatever it wanna do. And not what I think I have wrote!
I'm getting a sinus wave and I'm waiting for the pulse to go upvards befor I start meassuring. So any comments on this program will help me, because I'm totally stuck!


while(TRUE){

printf("\n\rStarter loop");

minir=1023;
maxir=0;
maxirtwo=0;
maxirthree=1023;
maxirfour=0;
irflag=0;

SET_ADC_CHANNEL(0);
output_high(PIN_C0);
output_low(PIN_C1);
delay_ms(1500);

Test: T1 = Read_ADC();
printf("\r\n T1= \%ld",T1);
delay_ms(1);
T2 = Read_ADC();
printf("\r\n T2= \%ld",T2);
if(T1 > T2){
goto Test;
}
else if(T1 < T2){
goto Start;
}
else{
goto Test;
}

Start:

for(i=1;i<=20000;i++)
{

value = Read_ADC();

if(value < minir)
minir=value;

if(value > maxir)
maxir=value;

if((value >= maxirtwo) && (irflag==0)){
maxirtwo=value;
printf("\r\n maxirtwo 1: \%ld",maxirtwo);
}

if((value < maxirtwo) && (irflag==0) && (maxirtwo >= maxir) ){
Tick=0;
irflag=1;
printf("\r\n maxirtwo setter tid: \%ld",maxirtwo);
}

if((irflag==1) && (value <= maxirthree)){
maxirthree=value;
printf("\r\n maxirthree 1: \%ld",maxirthree);
}


if((irflag==1) && (value > maxirthree) && (maxirthree <= minir)){
irflag=2;
printf("\r\n value: \%ld",value);
printf("\r\n maxirthree flagg satt : \%ld",maxirthree);
}

if((irflag==2) && (value >= maxirfour)){
maxirfour=value;
printf("\r\n maxirfour 1: \%ld",maxirfour);
}

if((value < maxirfour) && (irflag==2) && (maxirfour >= maxir)){
Time=Tick;
irflag=3;
printf("\r\n maxirfour: \%ld",maxirfour);
}

//difftest= (maxir-minir);

//delay_ms(1);

}



Thanks for all help you can give me!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514742
R.J.Hamlett
Guest







Re: Can anyone have a look at this code?
PostPosted: Sun May 25, 2003 5:06 am     Reply with quote

:=Hello people.
:=I'm trying to find max value from pulse 1 and max value from pulse 2 to find the time between them. But my program seems to do whatever it wanna do. And not what I think I have wrote!
:=I'm getting a sinus wave and I'm waiting for the pulse to go upvards befor I start meassuring. So any comments on this program will help me, because I'm totally stuck!
:=
:=
First question. What sort of frequency are you dealing with?. Seriously, to guarantee that you 'sample reasonably close to the peak, you need to be sampling at perhaps 20* the incoming frequency as a minimum. In the initial loop, you are sampling once, waiting 1mSec, then sampling again, then allmost immediately sampling again (if the code loops), taking a few uSec to do this. Hence the approach would perhaps be reasonable for an incoming rate up to about 40Hz, but not much higher.
Second question is the signal 'pure', or does it contain higher frequency signals as well. I suspect this is going to be the main problem. If you have some higher frequency noise on the signal, your code can detect this, and result in an incorrect trigger at both the start, and the finish...
Next comment. Why not let C handle the looping for you. The GOTO construct, is a mess...
Something like:
long last;
long new=1023;

do {
last=new;
new=Read_adc();
delay_ms(1);
} while (new>last);

Which will give a faster loop, and exit as soon as the value rises, with 'new' containing the latest value read.

I suspect you will actually need to approach things slightly differently. I'd suggest having a 'timer' interrupt, ticking at perhaps 4KHz, and taking the AD reading, inside the interrupt handler, writing the value into a buffer, containing perhaps four values. Then have the external loop, monitor the counter used to access this buffer, and when it changes to 3 (which will happen every mSec), generate the average of the four values, and reset the counter to zero. Use this 'average' reading, as your AD value. Depending on the amount of noise on the signal, you might even have to push to averaging 8 or perhaps 16 samples. Done like this, your code has a chance of dealing with noise on the signal, which is I suspect the main problem.

:=while(TRUE){
:=
:= printf("\n\rStarter loop");
:=
:= minir=1023;
:= maxir=0;
:= maxirtwo=0;
:= maxirthree=1023;
:= maxirfour=0;
:= irflag=0;
:=
:= SET_ADC_CHANNEL(0);
:= output_high(PIN_C0);
:= output_low(PIN_C1);
:= delay_ms(1500);
:=
:=Test: T1 = Read_ADC();
:= printf("\r\n T1= \%ld",T1);
:= delay_ms(1);
:= T2 = Read_ADC();
:= printf("\r\n T2= \%ld",T2);
:= if(T1 > T2){
:= goto Test;
:= }
:= else if(T1 < T2){
:= goto Start;
:= }
:= else{
:= goto Test;
:= }
:=
:=Start:
:=
:= for(i=1;i<=20000;i++)
:= {
:=
:= value = Read_ADC();
:=
:= if(value < minir)
:= minir=value;
:=
:= if(value > maxir)
:= maxir=value;
:=
:= if((value >= maxirtwo) && (irflag==0)){
:= maxirtwo=value;
:= printf("\r\n maxirtwo 1: \%ld",maxirtwo);
:= }
:=
:= if((value < maxirtwo) && (irflag==0) && (maxirtwo >= maxir) ){
:= Tick=0;
:= irflag=1;
:= printf("\r\n maxirtwo setter tid: \%ld",maxirtwo);
:= }
:=
:= if((irflag==1) && (value <= maxirthree)){
:= maxirthree=value;
:= printf("\r\n maxirthree 1: \%ld",maxirthree);
:= }
:=
:=
:= if((irflag==1) && (value > maxirthree) && (maxirthree <= minir)){
:= irflag=2;
:= printf("\r\n value: \%ld",value);
:= printf("\r\n maxirthree flagg satt : \%ld",maxirthree);
:= }
:=
:= if((irflag==2) && (value >= maxirfour)){
:= maxirfour=value;
:= printf("\r\n maxirfour 1: \%ld",maxirfour);
:= }
:=
:= if((value < maxirfour) && (irflag==2) && (maxirfour >= maxir)){
:= Time=Tick;
:= irflag=3;
:= printf("\r\n maxirfour: \%ld",maxirfour);
:= }
:=
:= //difftest= (maxir-minir);
:=
:= //delay_ms(1);
:=
:=}
:=
:=
:=
:=Thanks for all help you can give me!

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514743
SKROTNISSE
Guest







Answers to your questions and ...
PostPosted: Mon May 26, 2003 6:54 pm     Reply with quote

First I will thank you for the exelent answer! Thank you so much!

I'm dealing with signals from 1 to 8 Hz. So very low frequency.
I used your program, and it worked fine! I just had to change the way you set the > . I needed to find the rising edge not the falling edge. Im getting a sinus wave now so the signal should be pure. I always find the right max and min value. But the problem is that my if criteria some times just jump into the start timer even if the value is only 4 or something. And the loop doesn't work without the printf sentenses. I've tryed with delay who should be the same as the printf sentense but then everyting just go crazy.

So if you have some ideas or program sample I can use I would be very grateful!

Cheers

kristian
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514768
R.J.Hamlett
Guest







Re: Answers to your questions and ...
PostPosted: Tue May 27, 2003 2:40 am     Reply with quote

:=First I will thank you for the exelent answer! Thank you so much!
:=
:=I'm dealing with signals from 1 to 8 Hz. So very low frequency.
:=I used your program, and it worked fine! I just had to change the way you set the > . I needed to find the rising edge not the falling edge. Im getting a sinus wave now so the signal should be pure. I always find the right max and min value. But the problem is that my if criteria some times just jump into the start timer even if the value is only 4 or something. And the loop doesn't work without the printf sentenses. I've tryed with delay who should be the same as the printf sentense but then everyting just go crazy.
:=
:=So if you have some ideas or program sample I can use I would be very grateful!
:=
:=Cheers
I spotted I had reversed the test, after I posted. Glad you spotted it... :-)
I still think the problem is probably noise. If you think about it, at the near level parts of the waveform (near the top, and the bottom), it only takes one bit of sampling error, or a very few mV of electrical noise to trigger the start incorrectly. The chances of a signal being genuinely 'noise free' at this sort of level are low. Hence using averaging would be my recommendation, or repeating the test over a couple of samples.
If you setup a timer to tick at a frequency like 4KHz, and in the timer interrupt do something like:

int tick;
long values[4];

void timersub(void){
values[tick]=read_adc(ADC_READ_ONLY);
tick=++tick & 3;
read_adc(ADC_START_ONLY);
}

This way on each interrupt, the last reading will be taken, and the ADC, triggered to take a new reading.

Then in the main code, instead of using the 'delay_ms' wait, use:

while(tick!=0) ;
adval=(values[0]+values[1]+values[2]+values[3])>>2;

Then do your arithmetic, and before returning to the loop, execute:

while(tick==0) ;

With this, the code will wait for the 'tick' value to have moved off the zero value.
If the interrupt is at 4KHz, the loop will execute every mSec.
If you still get problems, then you should either consider increasing the size of the array (and the number of ticks), or possibly throwing away the low bits of the AD result. You may well also be able to improve things by adding a capacitor directly to the analog input pin.

Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514770
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group