Go Down

Topic: Timer1 for pulse period meaurement (ping mem) (Read 1 time) previous topic - next topic

rossco_50

Hi,

I have been trying to settup a programme on an uno board to measure the time between an object passing up to 4 photosensor arrays. Timing would be triggered on the trailing edge of a pulse generated by the object (a tennis ball) passing a first sensor and then stopped on the trailing edge of a pulse geenrated by a sensor approx. 0.4 m away. Timing will be started again by a third sensor and stopped by a fourth. Eventually I will use the values to calculate velocity and trajectory before and after an impact. I started a previous thread regarding the overall concept, but need some help specifically regarding the timer resolution http://arduino.cc/forum/index.php?action=printpage;topic=66505.0

I found some useful code for detecting pulse edge and measuring time between edges using the micros() function http://arduino.cc/forum/index.php/topic,70073.msg520999.html#msg520999 This works as it was intended to, but I am noticing inconsistencies in the values returned, I believe due to the code and timer speed. To create more headroom (calculated velocity error will decrease with improved timer resoultion) I would like to use the input capture unit on pin 8 to get down to micorsecond resolution or better. There are many code examples on the forum (thanks to mem), but most are relating to pulse width, rather than period, measurement and have other complicated features that I do not need. I am finding it dificult to adapt working code from these.

I have searched the forum extensively and am understanding the timer1 operation and registers better than I was and have tried to adapt some of mem's code to work in the way I want it to. http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1201890734/12

So far I have:
Code: [Select]

//adaption of mem's timer1 code to measure time from trailing edge to trailing edge twice.

#define icpPin 8    // this interrupt handler must use pin 8
#define NUMBER_PULSES     4   // number of pulses during one cycle of measurement apparatus
volatile uint8_t  PulseCount=0; // number of pulses counted
int time1;
int time2;


ISR(TIMER1_CAPT_vect){
   if((! bit_is_set(TCCR1B ,ICES1)) && (PulseCount=0)){ // was first falling edge detected ? 
TCNT1 = 0;    // reset the counter
         PulseCount++;             // count first pulse
  }
   
   else {   // trailing edge at 2nd array detected
   if((! bit_is_set(TCCR1B ,ICES1)) && (PulseCount=1)){ // was second falling edge detected ? 
time1=ICR1;    // record time between 1st and 2nd array
         PulseCount++;
   }
   if((! bit_is_set(TCCR1B ,ICES1)) && (PulseCount=2)){ // was third falling edge detected ? 
TCNT1 = 0;    // reset the counter
         PulseCount++;
   }
   if((! bit_is_set(TCCR1B ,ICES1)) && (PulseCount=3)){ // was fourth falling edge detected ? 
time1=ICR1;    // reset the counter
         PulseCount++;     
   }
}
TCCR1B ^= _BV(ICES1);      // toggle bit value to trigger on the other edge   
}
void setup()
{
  Serial.begin(9600); 
  pinMode(icpPin,INPUT);
  PulseCount = 0; 
  TCCR1A = 0x00;    // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
  TCCR1B = 0x02;    // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
  TIMSK1 = _BV(ICIE1);   // enable input capture interrupt for timer 1
}



void loop()    // run over and over again
{

  if(PulseCount  >= NUMBER_PULSES  ){
     Serial.println("time 1:"); 
    Serial.println(time1);
    Serial.println("time 2:"); 
      Serial.println(time2);
}

}


I have been trying to test with a pulse generator, but as soon as the first trailing edge is detected I am getting continuous readings (I am using one shot triggers to get 4 pulses for measurement). So, my PulseCounter and/or If/else statement is not working. I am also a bit usnsure about the line: TCCR1B ^= _BV(ICES1); // I am not sure if I do want toggle TCCR1B. Taking it out doesn't improve the situation.

I am also aware that I have most probably removed some critical code from mem's example, but as a novice I would appreciate any pointers.

Thanks,

Ross


jmknapp

#1
Sep 02, 2011, 05:14 pm Last Edit: Sep 02, 2011, 05:17 pm by jmknapp Reason: 1
I don't see where the pulse counter is ever getting reset to zero in the loop or ISR--it just gets incremented or not. Seems like you need to reset it after recording the time? And what if the ball misses one of the sensors--you probably want to handle such cases with timeouts and such. I'd be inclined to map it out as a state machine.

Joe

rossco_50

Hi Joe,

Thanks for that. I will try resetting after time reads.

Testing with the pulse generator I had left out timeout features, but will look to add those as well.

Excuse my ignorance, but can you point to an example of what "state machine" mapping would entail?

Ross

rossco_50

If I reset the pulsecount to 0 in the loop, the interuppt doesn't execute until a pulse is generated. However, time1 and time2 are returned directly after the first trailing edge i.e. I fire a one shot pulse and the loop completes by printing the same time value for both times.

Can anyone see where the IF statement is going wrong?


jmknapp


If I reset the pulsecount to 0 in the loop, the interuppt doesn't execute until a pulse is generated. However, time1 and time2 are returned directly after the first trailing edge i.e. I fire a one shot pulse and the loop completes by printing the same time value for both times.

Can anyone see where the IF statement is going wrong?


Looks to me in your code you set time1 twice and never set time2. Typo? Also, except for the first if, the next three ifs don't have an else, so I'd think you'd just go through all of them after the second pulse, bingo bango bongo.

Joe

Go Up