|
|
View previous topic :: View next topic |
Author |
Message |
Salenko
Joined: 08 Sep 2008 Posts: 84
|
[drip rate calculation] measure internal PIC signal duration |
Posted: Thu May 21, 2009 10:02 pm |
|
|
hi,
I'm designing a drip sensor using PICmicro 16F628 based on algorithmic
description found in the internet and tested with an Atmel AT8905xx
micro. I have chosen 16f628 because I was looking for an analog
comparator and a little number of I/O pins. According to my design, the
output of the comparator (C2OUT), which is not an output pin of the PIC,
become high when a drop passes. A drop has a duration of about 10ms,
time between successive drops depends on the drip rate. For example,
for 300 ml/hour (of perfusion) time between two drops is about 600ms.
So, in order to determine the drip rate, I have to count the time between
two drops, which is : time between successive rising edge of C2OUT.
Is this possible using timers ?
I know that this would be possible if the signal was external with the
Capture mode of the CCP module, unfortunately, this not the case.
Any suggestion?
Thanks in adv.
Last edited by Salenko on Sun May 24, 2009 7:37 am; edited 2 times in total |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: how to count internal PIC signal duration ? |
Posted: Fri May 22, 2009 4:30 am |
|
|
According to the datasheet, it is possible to configure the output of Comparator 2 to drive the RA4 pin (open collector), which could then be connected to RB3/CCP1 for precise capture of changes. However I don't think your application requires that kind of precision. You could much more easily set up a comparator interrupt that occurs whenever there is any change in the comparator state. Then in your interrupt service routine you could explicitly read Timer 1. If the interrupt is enabled all the time and you have no other interrupts running, then the variation in interrupt latency would be only a single instruction cycle. Even with some other small interrupt running, I think you could tolerate a latency variation of a hundred instruction cycles without seriously impacting your measurement precision. After all, you are only measuring a 10 msec. pulse every 600 msec. or so. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
Salenko
Joined: 08 Sep 2008 Posts: 84
|
|
Posted: Fri May 22, 2009 12:31 pm |
|
|
Hi RLScott,
thank you for giving me help,
I wrote a code using two timers interruptions:
timer0 --> to detect the begining of the drop (this timer overflows in 102us)
timer1 --> I used it as a the time base to mesure the duration between two successive drops (overflows every 26.2ms).
Compiler: PCW
Version: 4.057
PICmicro: 16F628
Code: |
#include <16F628.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 10000000)
#use rs232 (baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8)
#include <input.c>
#include <stdlib.h>
#byte CMCON = 0x1F // this register controls the comparator input and output multiplexers.
#define SysClock 10000000
#define led PIN_B0
//========Variables=======
int1 start_drop=0, next_drop=0, mes=0;
unsigned long overflowing_t1 ;
long Long mesure ;
//=============INTERRUPTIONS ROUTINES=================
//==========Comparator==============
#INT_COMP
void COMP_isr()
{
byte b;
b = CMCON; // to clear mismatch condition
if (C2OUT && !next_drop) // first drop
{
start_drop=1;
enable_interrupts(INT_TIMER0);
}
if (C2OUT && next_drop) // second drop
{
next_drop=0;
mes=1;
disable_interrupts(INT_TIMER1);
}
}
//==========Timer 0==============
#int_timer0 // overflows every 102us
void timer0_isr ( )
{
if (C2OUT && start_drop)
{
disable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER1);
start_drop=0;
next_drop=1;
}
}
//==========Timer 1==============
#int_timer1 // overflows every 26.2ms
void timer1_isr ( )
{
++ overflowing_t1 ;
}
|
and here is the main, a LED is lighted and the time measure is displayed in a virtual terminal when a drop passes (in fact, to test the code I used a virtual pulse generator in the inputs of the comparator and I changed its frequency (1, 1.25 Hz etc. to see how my code fuction )
Code: |
//--------------------------THE MAIN-----------------------------
void main()
{
byte b_comp ;
b_comp = CMCON ; // Read the comparator register to clear mismatch condition
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_RDA);
setup_comparator(NC_NC_A1_A2);
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
while(1)
{
if (C2OUT)
output_high(led);
else output_low(led);
if (mes)
{
mesure = overflowing_t1 * 26.2 ;
printf("overflowing_t1 = %Lu, time = %ld ms\n\r",overflowing_t1, mesure) ;
mes=0;
overflowing_t1=0;
}
}
}
|
What do you think about my code ? I set the timer1 to overflow at 26.2 ms, is there an option to reduce it to 20ms or 10ms so that I get a bit more accurate mesure ?
this code worked well in simulation (ISIS), now I'm going to program the PIC and test it in the breadboard with sensor assembly and other components to see what will happen.
If this interests anyone: here is a link to the document that I found in internet and inspired me (using AT89C2051), I did not fully apply the algorithm of page 3 because I will display the drip rate through a serial LCD, insted of two 7-segement LEDs. www.ee.iitb.ac.in/~spilab/Publicatios/bio_vision01_kamble_drip_rate.pdf
and here is a screen capture of the simulation that I made and the circuit I'm goning to make :
thanks in advance.
Last edited by Salenko on Sat May 23, 2009 2:56 am; edited 2 times in total |
|
|
Salenko
Joined: 08 Sep 2008 Posts: 84
|
|
Posted: Fri May 22, 2009 2:25 pm |
|
|
ooops,
Seems that I made a little mistake regarding the display,
in the main :
Code: | printf("overflowing_t1 = %Lu, time = %ld ms\n\r",overflowing_t1, mesure) ; |
takes about 1.75 seconds to display the successive time measurement. In the other side, sometimes the LED miss a blink.
I'll use the PC to display via hyperterminal just during the test stage (cause then I'll use an LCD). This would not affect the code I think. |
|
|
Salenko
Joined: 08 Sep 2008 Posts: 84
|
|
Posted: Sat May 23, 2009 1:48 pm |
|
|
Hi again,
any remark about my code ? |
|
|
|
|
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
|