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

[drip rate calculation] measure internal PIC signal duration

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



Joined: 08 Sep 2008
Posts: 84

View user's profile Send private message

[drip rate calculation] measure internal PIC signal duration
PostPosted: Thu May 21, 2009 10:02 pm     Reply with quote

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

View user's profile Send private message

Re: how to count internal PIC signal duration ?
PostPosted: Fri May 22, 2009 4:30 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 22, 2009 12:31 pm     Reply with quote

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 ? Smile


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. Smile

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

View user's profile Send private message

PostPosted: Fri May 22, 2009 2:25 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat May 23, 2009 1:48 pm     Reply with quote

Hi again,

any remark about my code ? Smile
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