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

Delay 232 output

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



Joined: 08 Sep 2003
Posts: 16

View user's profile Send private message

Delay 232 output
PostPosted: Mon Jan 12, 2004 10:12 am     Reply with quote

I have working code below to measure the speed of a conveyor belt in FPM but would like to output that speed every second instead of constant output. Everything I have tried to output at one second intervals has screwed up the output. Any sugestions would be greatly appreciated.

Code:

#include <16f873.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

byte i,j,k,flag,state,bcd_in,no_targets,roll_dia;
long counter,pulse_ms;
long ptics[5];
float current_speed,pi_value,roll_circ,fpm,pps;
short First_Edge = FALSE;                                   // first edge flag

// ********** INTERRUPT ROUTINES *********************************************************************

#INT_EXT
void edge_detect_isr(void)
{
   if(First_Edge) // Falling edge
   {
      ext_int_edge(H_to_L);
      SET_TIMER2(0);
      Counter = 0;

      First_Edge = FALSE;
   }
   else  // Rising edge
   {
      First_Edge = TRUE;
      ext_int_edge(H_to_L);
      pulse_ms = counter;

      //next 5 lines average the pulses 5 times
      ptics[j++] = pulse_ms;                                 // store new value
      if ( j==5 ) j = 0;                                    // reset
      current_speed = 0;                                    // init for average value calculation
      for ( k=0; k<5; ) current_speed += ptics[k++];        // sum the 5 values
      current_speed /= 5.0;                                 // devide by 5 for pulse average

   }
}

#INT_TIMER2
void timer2_isr(void)
{
   counter++;
}

// ********** START OF MAIN PROGRAM ******************************************************************

main() {

   setup_adc_ports(NO_ANALOGS);
   setup_timer_2 ( T2_DIV_BY_4,250,5);
   enable_interrupts(INT_TIMER2);                           // enable interrupt for timer 2
   enable_interrupts(INT_EXT);                              // enable external interrupt (B0)
   ext_int_edge(H_to_L);                                    // interrupt on high to low pulse edge
   enable_interrupts(GLOBAL);                               // enable global interrupts
   roll_dia = 5;
   no_targets = 2;
   pi_value = 3.14159;
   roll_circ = ((roll_dia * pi_value)/no_targets);

   for (i=0; i<5; ) ptics[i++] = pulse_ms;                  // fill rolling average values
   i=0;                                                     // set i to 0

   do                                                       // start main loop
   {
      pps = (1000/current_speed);
      fpm = ((pps * roll_circ / 12) * 60);
      printf("%7.2f\n\r", fpm);

   } while (true);                                          // end of main loop

}
ttelmah
Guest







Re: Delay 232 output
PostPosted: Mon Jan 12, 2004 10:33 am     Reply with quote

wmeade wrote:
I have working code below to measure the speed of a conveyor belt in FPM but would like to output that speed every second instead of constant output. Everything I have tried to output at one second intervals has screwed up the output. Any sugestions would be greatly appreciated.

Code:

#include <16f873.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

byte i,j,k,flag,state,bcd_in,no_targets,roll_dia;
long counter,pulse_ms;
long ptics[5];
float current_speed,pi_value,roll_circ,fpm,pps;
short First_Edge = FALSE;                                   // first edge flag

// ********** INTERRUPT ROUTINES *********************************************************************

#INT_EXT
void edge_detect_isr(void)
{
   if(First_Edge) // Falling edge
   {
      ext_int_edge(H_to_L);
      SET_TIMER2(0);
      Counter = 0;

      First_Edge = FALSE;
   }
   else  // Rising edge
   {
      First_Edge = TRUE;
      ext_int_edge(H_to_L);
      pulse_ms = counter;

      //next 5 lines average the pulses 5 times
      ptics[j++] = pulse_ms;                                 // store new value
      if ( j==5 ) j = 0;                                    // reset
      current_speed = 0;                                    // init for average value calculation
      for ( k=0; k<5; ) current_speed += ptics[k++];        // sum the 5 values
      current_speed /= 5.0;                                 // devide by 5 for pulse average

   }
}

#INT_TIMER2
void timer2_isr(void)
{
   counter++;
}

// ********** START OF MAIN PROGRAM ******************************************************************

main() {

   setup_adc_ports(NO_ANALOGS);
   setup_timer_2 ( T2_DIV_BY_4,250,5);
   enable_interrupts(INT_TIMER2);                           // enable interrupt for timer 2
   enable_interrupts(INT_EXT);                              // enable external interrupt (B0)
   ext_int_edge(H_to_L);                                    // interrupt on high to low pulse edge
   enable_interrupts(GLOBAL);                               // enable global interrupts
   roll_dia = 5;
   no_targets = 2;
   pi_value = 3.14159;
   roll_circ = ((roll_dia * pi_value)/no_targets);

   for (i=0; i<5; ) ptics[i++] = pulse_ms;                  // fill rolling average values
   i=0;                                                     // set i to 0

   do                                                       // start main loop
   {
      pps = (1000/current_speed);
      fpm = ((pps * roll_circ / 12) * 60);
      printf("%7.2f\n\r", fpm);

   } while (true);                                          // end of main loop

}


Do something like this:
//Add another counter 'downcount' as an int16.
//In timer2, add:

if (downcount)--downcount;

//Then in the main code loop, add:

downcount=1000;
while (downcount) ;

//Now print the value, and loop again (reloading 'downcount' as you do so).

Best Wishes
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Mon Jan 12, 2004 10:35 am     Reply with quote

If you have an interupt on low to high and set a timer to zero it will be a free running counter untill the next low to high. You can play around with the prescaler or create an overflow counter for long periods. This will give you the instant speed measurement. From here you have an analog value that should be filtered over time. You can read the filtered value at any time. Without filtering the reading is going to be jumping around.
wmeade



Joined: 08 Sep 2003
Posts: 16

View user's profile Send private message

Thanks for the help
PostPosted: Mon Jan 12, 2004 12:05 pm     Reply with quote

Thank you Neuton and ttelmah for the quick replies. Using your sugestions I was able to transmit once a second and get everything working just the way it should.
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