![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
SKROTNISSE Guest
|
Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 6:15 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Felix Althaus
Joined: 09 Sep 2003 Posts: 67 Location: Winterthur, Switzerland
|
Re: Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 7:25 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
SKROTNISSE Guest
|
Re: Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 8:03 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Tomi Guest
|
Re: Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 8:46 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Felix Althaus
Joined: 09 Sep 2003 Posts: 67 Location: Winterthur, Switzerland
|
Re: Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 8:49 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: Find the rising edge of a sinus like signal |
Posted: Thu May 29, 2003 11:18 am |
|
|
:=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 |
|
![](templates/subSilver/images/spacer.gif) |
SKROTNISSE Guest
|
The whole code. |
Posted: Thu May 29, 2003 5:17 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
John Yaron Guest
|
Re: Find the rising edge of a sinus like signal |
Posted: Sat May 31, 2003 4:19 pm |
|
|
:=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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|