|
|
View previous topic :: View next topic |
Author |
Message |
uN_Eof
Joined: 17 May 2010 Posts: 29 Location: I live in Spain, with the toros, paella and tortilla
|
Timing between 2 input pins. |
Posted: Wed Jun 09, 2010 1:52 pm |
|
|
Hi all,
I want to know how much time (in uS) takes an object to go between 2 points. The PIC knows when the object passes the points with 2 phototransistors, or, digital 1 in 2 pins.
I wanted to use timers, but I don't get to use them... so i need some help.
Thanks in advance. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 09, 2010 2:04 pm |
|
|
Quote: |
The PIC knows when the object passes the points with 2 phototransistors.
|
CCS has an example file for this. It uses the ADCs to read the
photodiodes, and it uses Timer1 to count the time duration:
Quote: | c:\program files\picc\examples\ex_speed.c |
Here is a similar example, except it uses the CCP modules.
Quote: | c:\program files\picc\examples\ex_ccpmp.c |
This example polls an i/o pin and times it with the RTCC (Timer0):
Quote: | c:\program files\picc\examples\ex_pulse.c |
|
|
|
uN_Eof
Joined: 17 May 2010 Posts: 29 Location: I live in Spain, with the toros, paella and tortilla
|
|
Posted: Wed Jun 09, 2010 3:06 pm |
|
|
Thanks for the reply.
I've checked the code and I think this should work. The computer I use to program pics is broken so I don't know if this would work.
Code: |
#include <16f628.h>
#fuses INTRC,nowdt,put,noprotect, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_B1,rcv=PIN_B2)
#define TIMER1_FREQUENCY (XTAL_FREQUENCY / 4)
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte PORTA = 0x05
#byte PORTB = 0x06
void main(void) {
byte counter_us = 0;
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
/////////////MAIN LOOP
while (1) {
if (input(PIN_A1)) {
set_timer1(0);
}
if (input(PIN_A2)) {
counter_us = get_timer1();
}
}
}
|
A question I have, if I read the timer, does the timer stop counting and reset? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jun 09, 2010 11:07 pm |
|
|
Quote: | A question I have, if I read the timer, does the timer stop counting and reset? |
Why should it? This action wouldn't be generally wanted. You have to organize all required actions in your code. The first point, that should be added is edge detection of the input signals. I guess, you want to set the timer on a PIN_A1 event rather than permanently? The general method to achieve this is to remember the previous pin state and compare with the actual. Or implement a state machine: If the active pins state is detected, start the timer and advance the state.
You should also take a look at the timer CCP (capture and compare) function provided with may PIC chips. Unfortunately, a PIC16 has only one CCP unit. A PIC18 with two independant CCP units is able to perform the intended time measurement "in hardware", if programmed correctly. |
|
|
uN_Eof
Joined: 17 May 2010 Posts: 29 Location: I live in Spain, with the toros, paella and tortilla
|
|
Posted: Sat Jun 12, 2010 10:47 am |
|
|
Code: | #include <16f628.h>
#fuses INTRC,nowdt,put,noprotect, NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, UART1, PARITY=N, BITS=8, STOP=1)
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte PORTA = 0x05
#byte PORTB = 0x06
#INT_TIMER1
void T1INT() {
output_high(PIN_B0);
delay_ms(1000);
output_low(PIN_B0);
}
void main(void) {
byte counter_us = 0;
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
/*******************MAIN LOOP******************/
while (1) {
while(!input(PIN_A1));
output_high(PIN_B3);
set_timer1(0);
while(!input(PIN_A2));
output_LOW(PIN_B3);
counter_us = get_timer1();
printf("Timer1: %u\n", counter_us);
delay_ms(100);
}
} |
This is the code I'm using now. I wonder why it overflows at 255... any idea? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 12, 2010 11:13 am |
|
|
Timer1 is 16 bits, but 'counter_us' is declared as only 8 bits. Fix that, and
then you also will need to change the printf() format declaration to "%lu"
to display the 16-bit variable (That's a lower-case 'L' in "%lu"). |
|
|
uN_Eof
Joined: 17 May 2010 Posts: 29 Location: I live in Spain, with the toros, paella and tortilla
|
|
Posted: Sat Jun 12, 2010 1:03 pm |
|
|
I've fixed what you said. But I dont know why is this not working....
Code: | #include <16f628.h>
#fuses INTRC,nowdt,put,noprotect, NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, UART1, PARITY=N, BITS=8, STOP=1)
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte PORTA = 0x05
#byte PORTB = 0x06
#include <stdlib.h>
void main(void) {
int16 counter_us = 0;
int16 counter_ms = 0;
float mmbts = 0;
char mmbts_[6];
float sfps = 0;
float skmh = 0;
float smps = 0;
printf("Distancia entre sensores en mm:\r\n");
gets(mmbts_);
mmbts = atof(mmbts_);
printf("Distancia: %u mm\r\n",mmbts);
/*******************MAIN LOOP******************/
while (1) {
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
while(!input(PIN_A1));
output_high(PIN_B3);
set_timer1(0);
while(!input(PIN_A2));
output_LOW(PIN_B3);
counter_us = get_timer1();
setup_timer_1( T1_DISABLED );
printf("Time in uS: %lu\n", counter_us);
counter_ms = counter_us / 1000;
smps = mmbts / counter_ms;
skmh = smps * 3.6;
sfps = smps * 3.28;
printf("Speed:\n%3.2f m/s\n%3.2f Km/h\n%3.2f FPS\n\n", smps, skmh, sfps);
delay_ms(100);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sat Jun 12, 2010 2:51 pm |
|
|
Several comments.
First, is your distance always going to be less than 9999mm. If not, you need to make the buffer larger, and whatever size it is, use the 'get_string' function (in input.c), rather than 'gets'. Problem is that 'gets', will keep on accepting data, and potentially overflow memory, if something 'wrong' is typed.
Then, mmbts, is a 'float' value, but you print it as 'unsigned'. Wrong.
Then, you don't need to redo the timer setup in the loop. Do it once in the initialisation code.
Then, what happens, if pin A1, is not low when you arrive into the loop?. Invalid values.
Then 'counter_ms' is an integer. If you have a count of (say) 3500uSec, it is goint to be '3'. Invalid values for the calculations from this point.
Then back to the problem with the level on pin A1, when you loop....
Best Wishes |
|
|
uN_Eof
Joined: 17 May 2010 Posts: 29 Location: I live in Spain, with the toros, paella and tortilla
|
|
Posted: Sat Jun 12, 2010 3:30 pm |
|
|
It never exits from the while until you put something in the first sensor. It's what is supposed to do.
The problem is that when I type in the terminal the distance in mm the program seems to stop.
New code:
Code: |
#include <16f628.h>
#fuses INTRC,nowdt,put,noprotect, NOLVP
#use delay(clock=4000000)
#use rs232(baud=2400, UART1, PARITY=N, BITS=8, STOP=1)
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte PORTA = 0x05
#byte PORTB = 0x06
#include <stdlib.h>
void main(void) {
int16 counter_us = 0;
float counter_ms = 0;
float mmbts = 0;
char mmbts_[6];
float sfps = 0;
float skmh = 0;
float smps = 0;
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
printf("Distancia entre sensores en mm:\r\n");
gets(mmbts_);
mmbts = atof(mmbts_);
printf("Distancia: %f mm\r\n",mmbts);
/*******************MAIN LOOP******************/
while (1) {
while(!input(PIN_A1));
output_high(PIN_B3);
set_timer1(0);
while(!input(PIN_A2));
output_LOW(PIN_B3);
counter_us = get_timer1();
setup_timer_1( T1_DISABLED );
printf("Time in uS: %lu\n", counter_us);
counter_ms = counter_us / 1000;
smps = mmbts / counter_ms;
skmh = smps * 3.6;
sfps = smps * 3.28;
printf("Speed:\n%3.2f m/s\n%3.2f Km/h\n%3.2f FPS\n\n", smps, skmh, sfps);
delay_ms(100);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 13, 2010 1:47 pm |
|
|
Quote: |
The problem is that when I type in the terminal the distance in mm the
program seems to stop.
|
What number are you typing in, when the program seems to stop ?
Post the number exactly. Are you typing "mm" at the end of the
number ? Are you pressing the Enter key after you finish typing it ?
Post all the keys that you press when you type in the distance. |
|
|
|
|
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
|