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 support@ccsinfo.com

Find the rising edge of a sinus like signal

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







Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 6:15 am     Reply with quote

Hello.
I have a 11Mhz crystal that the PIC16F877 runs on. I have to find the rising edge of a 10-bit sinus like signal with noise.

I'm currently using this code:

T1=1023
do{
T2=T1;
T1=Read_ADC();
delay_ms(10);
} while (T1 < T2);

But this code only finds the rising edge 50\% of the time. I've tried several different programs, but nothing seems to give me the rising edge all the time. I'm sampling at a frequecy from 1Hz to 5Hz.

Does somone have a better idea?

Thanks for any ansver!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514841
Felix Althaus



Joined: 09 Sep 2003
Posts: 67
Location: Winterthur, Switzerland

View user's profile Send private message

Re: Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 7:25 am     Reply with quote

Hello

1)As I read your code you also count the edge if the new value is only 1 higher then the old one. You wrote, you had a noisy signal so, I would recommend to check if the difference of the samples is higher than a constant value (thats the way I'm doing it) and then count the edge.
2) You sample from 1Hz to 5Hz, whats the frequency of the sine wave?


mfg
Felix
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514843
SKROTNISSE
Guest







Re: Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 8:03 am     Reply with quote

Thank you for the answer!
I'm getting a sine wave of 1Hz to 5Hz.The value of the signal is from 16 to 50 so it's a narrow difference.

Is the test you are thinking of something like this:

T1=1023;
do{
T2=T1;
T1=Read_ADC();
delay_ms(2);
diff=(T2-T1);
} while ((T1 < T2) && (diff > 5));

I have tried so many approaches that I'm totally confused of the whole thing!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514845
Tomi
Guest







Re: Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 8:46 am     Reply with quote

As you wrote you have to find the rising edge of the sine wave. But your current program tries to catch the maximum value. (The rising edge is defined as the positive inflexion point of the sine. You know, that 45° part when the ideal sine crosses the x axis.)
To find the right edge maybe you have to concern to calculate the average value of the input. Then the inflexion point is there when the previous sample is less than this average and the current sample is greater than.

:=Hello.
:=I have a 11Mhz crystal that the PIC16F877 runs on. I have to find the rising edge of a 10-bit sinus like signal with noise.
:=
:=I'm currently using this code:
:=
:=T1=1023
:=do{
:=T2=T1;
:=T1=Read_ADC();
:=delay_ms(10);
:=} while (T1 < T2);
:=
:=But this code only finds the rising edge 50\% of the time. I've tried several different programs, but nothing seems to give me the rising edge all the time. I'm sampling at a frequecy from 1Hz to 5Hz.
:=
:=Does somone have a better idea?
:=
:=Thanks for any ansver!
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514847
Felix Althaus



Joined: 09 Sep 2003
Posts: 67
Location: Winterthur, Switzerland

View user's profile Send private message

Re: Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 8:49 am     Reply with quote

Hello

:=T1=1023;
:=do{
:=T2=T1;
:=T1=Read_ADC();
:=delay_ms(2);
:=diff=(T2-T1);
:=} while ((T1 < T2) && (diff > 5));

Shouldn't it be (diff < 5)? I think you want to loop till a rising edge with (T2-T1 > 5) is detected (but may I'm wrong).

What type has the diff variable (you may get problems if its unsigned, and the difference is negative)

Perhaps you can post your whole code(?)

mfg
Felix
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514848
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Find the rising edge of a sinus like signal
PostPosted: Thu May 29, 2003 11:18 am     Reply with quote

:=Hello.
:=I have a 11Mhz crystal that the PIC16F877 runs on. I have to find the rising edge of a 10-bit sinus like signal with noise.
:=
:=But this code only finds the rising edge 50\% of the time. I've tried several different programs, but nothing seems to give me the rising edge all the time. I'm sampling at a frequecy from 1Hz to 5Hz.
:=
---------------------------------------------------------------

You're trying to do everything in a PIC. That might be
possible, but I think it's easier if you use an external
signal conditioning circuit.

You can use two opamps. The first one is an inverting
amplifier. It should amplify the signal up to 3v p/p or so.
You can put a small capacitor in parallel with the feedback
resistor on this opamp, to roll-off the gain at a fairly
low frequency. This will get rid of most of your noise
problems. If you're using a single (+5v) supply for the
opamp, then couple the signal into the opamp circuit with
a capacitor. Bias the + input of the opamp with a resistor
divider, to give +2.5v on that pin. The sine wave goes to
the - pin.

Then use the next opamp as a comparator. This will turn
your sine wave into a square wave. If you use a LM358 or
LM358A, the Voh level will not be high enough for the CMOS
input of a 5v PIC. So you will need a 74AHCT14 chip after
the opamp to create a rail-to-rail (Vol = 0v, Voh = 5v)
square wave. You can use a single-gate package (SOT23-5)
for the 74AHCT14.

Finally, put this square-wave into the PIC. You now have
a clean waveform that the PIC can easily work with.
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514854
SKROTNISSE
Guest







The whole code.
PostPosted: Thu May 29, 2003 5:17 pm     Reply with quote

Here is the whole code: I hope you can get something out of it!
Thanks!


#include "16F877.h"
#use delay(clock=11000000)
#fuses HS,NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use rs232(baud=9600, xmit=PIN_C6)
#include "lcd.c"
void utregn_O2();
long maxr,minr,maxir,maxirone,maxir2,maxirthree,maxirfour,maxirfourtwo,minir,maxir3,maxir4,maxir5,maxir6,maxir7;
long Tick,Time,Time2,Tick2,Rounds,Rounds1,Loop;

#int_timer2
void tick_handler(void) {
Tick++;
Tick2++;
}
//////////////////////////////////////////// Main program ////////////////////////////////////////////////
main()
{
int offset,offset_red,irflag;
long i=0;
long value,T1,T2;
long difftest,average1,average,average2,average3;
int a,b,c,d;
lcd_init();

setup_psp(PSP_DISABLED);
setup_timer_2(T2_DIV_BY_1,215,13);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);





setup_adc_ports(RA0_RA1_RA3_ANALOG); //Setup the A/D converter. The setup_adc function also turns the A/D on.
setup_adc(ADC_CLOCK_DIV_32); // Use 32 * Tosc, with our 11 MHz clock
Loop=0;

while(TRUE){

Loop++;

minir=1023;
maxir=0;
maxirthree=1023;
maxirfour=0;
irflag=0;
average=0;
average1=0;
a=0;
b=0;
maxir2=0;
maxir3=0;
maxir4=0;
maxir5=0;
maxir6=0;
maxir7=0;
average2=0;
average3=0;
c=0;
d=0;
maxirfour=0;
maxirfourtwo=0;

SET_ADC_CHANNEL(0);
output_high(PIN_E0);
output_low(PIN_C1);
output_high(PIN_C0);
delay_ms(30);
output_low(PIN_E0);

delay_ms(1470);
/////////////////////////////////////////////START TEST PROGRAM/////////////////////////

///////////////////////METHOD ONE////////////////////////////////////
/*
Test: T1=Read_ADC();
delay_ms(2);
T2=Read_ADC();
if(T1 > T2)
goto Test;
else if(T1 < T2)
goto Start;
else
goto Test;
*/


///////////////////////METHOD TWO////////////////////////////////////
/*
T1=0;
T2=0;
do{
for(a=0 ; a < 20 ; a++) {
value = Read_ADC();
T1 += value;
delay_ms(2);
}

for(b=0 ; b < 20 ; b++) {
value = Read_ADC();
T2 += value;
delay_ms(2);
}

average=(T1 / 20);
average1=(T2 / 20);



}while(average > average1);


*/
///////////////////////METHOD THREE////////////////////////////////////



T1=1023;
do{
T2=T1;
T1=Read_ADC();
delay_ms(2);
diff=(T2-T1);
} while ((T1 < T2) && (diff < 5));

/*
T1=1023;

do{
T2=T1;
T1=Read_ADC();
delay_ms(2);
} while ((T1 < T2) && (diff < 5));

*/



value= Read_ADC();
printf("\r\n VERDI INN I LOOOP \%ld",value);
Time=0;
Tick2=0;

///////////////////////////////START LOOP FOR TESTING////////////////////////////


do{
i++;
value = Read_ADC();
printf("\r\n VERDI I LOOOP \%ld",value);

if(irflag==0){

maxir3=0;
maxir2=0;

do{ maxir3=maxir2;
value = Read_ADC();
if(value > maxir2)
maxir2=value;
}while(maxir2 > maxir3);

delay_ms(5);
value = Read_ADC();

if(value > maxir2)
maxir2=value;
do{
maxir3=maxir2;
value = Read_ADC();
if(value > maxir2)
maxir2=value;
}while(maxir2 > maxir3);


delay_ms(5);
value = Read_ADC();

if(value > maxir2)
maxir2=value;
do{
maxir3=maxir2;
value = Read_ADC();
if(value > maxir2)
maxir2=value;
}while(maxir2 > maxir3);


if(value < maxir3){
Tick=0;
irflag=1;
printf("\r\n Maxir first = \%ld",maxir3);
maxir2=0;
maxir3=0;
Rounds=i;
}
}

//////////////////////////////////////////////TEST NEXT VALUES///////////////////////////

if(value < minir)
minir=value;

if(value > maxir)
maxir=value;


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

}


if((irflag==1) && (value > maxirthree) ){
irflag=2;
// printf("\r\n Starter max4 telling");
printf("\r\n maxirthree flagg satt : \%ld",maxirthree);
printf("\r\nTid når max tree blir satt : \%ld",Tick);
}


if(irflag==2){


backtwo: for(c=1 ; c < 6 ; c++) {
value = Read_ADC();
maxirfour += value;
delay_ms(1);
}

for(d=1 ; d < 6 ; d++) {
value = Read_ADC();
maxirfourtwo += value;
delay_ms(1);
}

average2=(maxirfour / 5);
// printf("\r\n Maxirfour Average1: \%ld",average2);
average3=(maxirfourtwo / 5);
// printf("\r\n Maxirfour Average2: \%ld",average3);

if(average2 < average3){
maxirfour=0;
maxirfourtwo=0;
average2=0;
average3=0;
goto backtwo;
}

if(average2 >= average3){
Time=Tick;
irflag=3;
Rounds1=i;
printf("\r\n Maxirfour Average2: \%ld",average3);
}
}

delay_ms(20);
}while(Tick2 <=1500);
Time2=Tick2;


//////////////////////////////////START OFFSET JUSTERING IR //////////////////////////////////////

//////////////////////////////////SLUTT OFFSET JUSTERING IR //////////////////////////////////////


minr=1024;
maxr=0;
SET_ADC_CHANNEL(1);
output_high(PIN_E0);
output_low(PIN_C0);
output_high(PIN_C1);
delay_ms(30);
output_low(PIN_E0);

delay_ms(1470);


for(i=0;i<=1500;i++)
{

value = Read_ADC();

if(value < minr)
minr=value;

if(value > maxr)
maxr=value;

delay_ms(1);
}

//////////////////////////////////START OFFSET JUSTERING RØD //////////////////////////////////////


//////////////////////////////////SLUTT OFFSET JUSTERING RØD //////////////////////////////////////


output_low(PIN_C1);
printf("\r\nIR lys MAX er nå etter 1500 målinger: \%ld",maxir);
printf("\r\nIR lys MIN er nå etter 1500 målinger: \%ld",minir);
// printf("\r\nRØD lys MAX er nå etter 1500 målinger: \%ld",maxr);
// printf("\r\nRØD lys MIN er nå etter 1500 målinger: \%ld",minr);
printf("\r\nTid i for loop: \%ld",Time2);
utregn_O2 ();
}
}

/////////////////////////////////////////Calculate SpO2///////////////////////////////////////////

void utregn_O2(){
float Ratio,R1,R2,ACr,DCr,DCir,ACir,pulse;
long SpO2,diff;
float pulse2,pulse1;
long pulse3,pulse4;
ACr = (maxr-minr);
DCr = ((maxr+minr)/2);
ACir = (maxir-minir);
DCir = ((maxir+minir)/2);
R1 = (ACr/DCr);
R2 = (ACir/DCir);
//printf("\r\nDelta IR er nå = \%f",R2);
//printf("\r\nDelta RØD er nå = \%f",R1);
Ratio = (R1/R2);
SpO2 = (110-(25*Ratio));

printf("\n\rOxygen saturation = \%ld",SpO2);
lcd_gotoxy(1,1);
printf(lcd_putc, "\fSpO2: \%ld ",SpO2);
lcd_putc(37);

//diff=(Rounds1- Rounds);
//diff *=50;
//printf("\r\n Runde ved start er: \%ld",Rounds);
//printf("\r\n Runde ved stopp er: \%ld",Rounds1);
//printf("\r\n Differanse mellom runder er: \%ld",diff);
printf("\r\n Tid er: \%ld",Time);
pulse=(Time);

pulse2=(1000/pulse);
pulse1=(pulse2*60);
pulse3=pulse1;
if(pulse3 < 30)
{
lcd_gotoxy(1,1);
printf(lcd_putc, "\fPulse: < 30" );
lcd_gotoxy(1,2);
printf(lcd_putc, "ALARM");
}

if((pulse3 >40 ) && (pulse3 < 241) && (Loop <=4))
pulse4=pulse3;

diff=(pulse4-pulse3);

if(diff > 10)
pulse3=pulse4;

printf("\n\rPulse : \%ld",pulse3);

if(pulse3 > 240){
lcd_gotoxy(1,2);
printf(lcd_putc, "Pulse: Searching");

}
else{
lcd_gotoxy(1,2);
printf(lcd_putc, "Pulse: \%ld ",pulse3);
lcd_putc("Bpm");
}


}

/////////////////////////////////////LOOP FOR NO FINGER////////////////////////////////////////////////

/////////////////////////////////////////END PROGRAM/////////////////////////////////////////////
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514872
John Yaron
Guest







Re: Find the rising edge of a sinus like signal
PostPosted: Sat May 31, 2003 4:19 pm     Reply with quote

:=Hello
:=
:=:=T1=1023;
:=:=do{
:=:=T2=T1;
:=:=T1=Read_ADC();
:=:=delay_ms(2);
:=:=diff=(T2-T1);
:=:=} while ((T1 < T2) && (diff > 5));
:=
:=Shouldn't it be (diff < 5)? I think you want to loop till a rising edge with (T2-T1 > 5) is detected (but may I'm wrong).

Have you tried digitally filtering out the noise before rising edge detection. You should have plenty of time with the low 5hz bandwidth reqt.

:=
:=What type has the diff variable (you may get problems if its unsigned, and the difference is negative)
:=
:=Perhaps you can post your whole code(?)
:=
:=mfg
:=Felix
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514916
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