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

Timing between 2 input pins.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
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

View user's profile Send private message

Timing between 2 input pins.
PostPosted: Wed Jun 09, 2010 1:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 09, 2010 2:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 09, 2010 3:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 09, 2010 11:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 12, 2010 10:47 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 12, 2010 11:13 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 12, 2010 1:03 pm     Reply with quote

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: 19328

View user's profile Send private message

PostPosted: Sat Jun 12, 2010 2:51 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 12, 2010 3:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 13, 2010 1:47 pm     Reply with quote

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