|
|
View previous topic :: View next topic |
Author |
Message |
wmeade
Joined: 08 Sep 2003 Posts: 16
|
Delay 232 output |
Posted: Mon Jan 12, 2004 10:12 am |
|
|
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 |
Posted: Mon Jan 12, 2004 10:33 am |
|
|
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
|
|
Posted: Mon Jan 12, 2004 10:35 am |
|
|
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
|
Thanks for the help |
Posted: Mon Jan 12, 2004 12:05 pm |
|
|
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. |
|
|
|
|
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
|