-1

I am trying to calculate time between two serial events. Using Arduino UNO R3 with 16MHz default clock source. I am using timer 1 with pre-scale of 64 to get time per one count = 4000ns. This i am choosing at random without any specific reason. Sending character 'o' to start the timer and character 'k' to stop it and hence calculate the time in between. The ISR routine calculates how much times the timer overflows. The code is:

    unsigned int t;
unsigned int c;
char r;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  TIMSK1 = (1<<TOIE1);//enable timer overflow interrupt
  sei();
  //SREG = (1<<8);//enable global inteerupt
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()>0)
  {
    r=Serial.read();
  if(r=='o')
  {
    TCNT1=0;
    TCCR1B |= (1<<CS11)|(1<<CS10);//64 pre-scale & start
    Serial.println(TCNT1);
  }
  else if(r=='k')
  {
    Serial.println(TCNT1);
    TCCR1B = 0;//stop timer
    t=TCNT1+(c*65536);
    t=t*(4*10^(-9));
    Serial.print("overflows = ");
    Serial.println(c);
    Serial.print("time = ");
    Serial.println(t);
    c=0;
    t=0;
  }
  }
}//loop

ISR(TIMER1_OVF_vect)
{
  c++;
}//isr

But, on serial monitor only the block of if(Serial.read()=='o').... is executing. The flow does not enter the second else if block.

What is wrong with this code? How long does the Serial buffer hold its vale ?

EDIT: I got the code working for checking for 'k'. But the timer value it calculates is very less than compared to what it should be. Is anything wrong with the timer settings. Setting CS10=CS11=1 gets the pre-scaler value to 64.

Hence, the time for 1 count should be = 1/(16MHz/64) .

Is anything wrong with this?

  • You can get more accurate timing by connecting a GPIO to the RX line. Then use a pin change interrupt to capture the start bit of both serial characters. I don't have any code example, sorry – portforwardpodcast Apr 5 '15 at 12:25
0

I'd read the result of Serial.read() to a variable and check this variable, because otherwise the first Serial.read() will have already read the 'k'. I reckon you can remove the Serial.available() check.

void loop() {
    int chr = Serial.read();
    if(chr=='o')
    {
        TCNT1=0;
        TCCR1B |= (1<<CS11)|(1<<CS10);//64 pre-scale & start
    }
    else if(chr=='k')
    {
        t=TCNT1;
        TCCR1B = 0;//stop timer
        t=t+(c*65536);
        c=0;
        Serial.println(t);
        t=0;
    }
}//loop
  • Yes. thank you. Just found that Serial.read() clears the Serial receive buffer. Thats why it will never enter the else if block. I will try with a separate variable as you said. – Dave127 Apr 4 '15 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.