Timer1 Interrupt and Serial.write()

Hi,

i am working on a new project which is quite simple. The main idea is to count the pulses from pin2 in an UNO board and send the result using Serial.write().

So what i did till now is to prepare the Timer1 interrupt to fire at 100hz. Pin2 pulses are increased in a function which i set using the attachInterrupt(); The Timer1 interrupt function just sends the time in millis and the number of pulses using the serial.write(). What i noticed is that if i used the millis() function in the Timer1 interrupt i could get an increasing value by 10 and every 160~170mS i got an increased value by 9 and the next increased value is 11 and the rest of the values are correctly increasing by 10. So i decided to get the value from millis() at the main loop function and increase it by 10 in the Timer1 interrupt. I forgot to mention that the user has to press a button in order the UNO to start sending data to the computer. So i fixed that time error which i believe is an error of millis(). What i want to ask is if there is a problem using the Serial.write() inside the Timer1 interrupt.

I am showing an example code of the interrupts.

volatile unsigned long ticks = 0;

// pin2 interrupt triggered when signal falls
void rpm_counter()
{
    ticks++;
}

ISR(TIMER1_COMPA_vect)
{
  if (measure == true)
  {
    serialPacket.sensor.time = milliTime;//millis();
    serialPacket.sensor.Ticks = ticks;
    Serial.write(serialPacket.SerialPacket, PACKET_SIZE);
  }
  ticks = 0;
  milliTime += 10;
}

I would like to know if my implementation is correct because sometimes even though the ticks are increasing, the value of ticks in the serialpacket, remains the same as the previous one. The pulses are counted using a hall sensor and 42 "teeth" wheel.

Got any suggestions?

One suggestion is not to issue serial commands in an interrupt service routine.

Serial.write(serialPacket.SerialPacket, PACKET_SIZE);

These use interrupts themselves and a conflict may result.

Interrupts are turned off within an interrupt, so anything that depends on an interrupt won't work at all.

There is never a need to print within an interrupt. Set a global flag variable and exit the interrupt.

jremington: Interrupts are turned off within an interrupt, so anything that depends on an interrupt won't work at all.

There is never a need to print within an interrupt. Set a global flag variable and exit the interrupt.

An atomic global flag, declared volatile.

psyche: i am working on a new project which is quite simple. The main idea is to count the pulses from pin2 in an UNO board and send the result using Serial.write().

So what i did till now is to prepare the Timer1 interrupt to fire at 100hz. Pin2 pulses are increased in a function which i set using the attachInterrupt();

This seems a very strange way to figure out RPM.

One option is to use the rpm_counter() function to record the value of micros() with every pulse and then, in the main program, calculate the speed based on the interval between pulses. This would be my choice.

Another option is for the rpm_counter() function to record the value of millis() after a specified number of pulses.

In either case, the rpm_counter() function should update a flag variable when it has new data for the main part of the program - for example newPulse = true; or hundredPulsesDetected = true; and when the main program sees that it can act on the data.

And in neither case should you print from within an ISR - {a} because printing needs interrupts to be enabled and {b{ because printing is slow.

If you just want to send serial data once per second (or whatever) just use millis() to manage the timing as illustrated in Several Things at a Time

...R