// This function does low-lovel setups to achieve a call to an interrupts function every 20uS void setup_timer_interrupt() { //set timer1 interrupt at 10Hz TCCR1A = 0;// set entire TCCR1A register to 0 TCCR1B = 0;// same for TCCR1B TCNT1 = 0;//initialize counter value to 0 // set compare match register for 1hz increments // OCR1A = 40. This results is 16MHz / 8 / 40 = 20 uS between interrupts OCR1A = 40; // turn on CTC mode TCCR1B |= (1 << WGM12); // Set CS12:CS10 to 010 = /8 prescaler TCCR1B |= (1 << CS11); // enable timer compare interrupt TIMSK1 |= (1 << OCIE1A); } // 20uS timer interrupt function // 48810 int/sec = 20.487605 uS ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) { static unsigned char currValue = 0; static unsigned short samples = 0; static unsigned short newSamples = 0; // Sample the pin value unsigned char value = digitalRead(rxPinA); if ( value == currValue ) { samples++; samples += newSamples; newSamples = 0; } else { newSamples++; } // We wait until we have sampled 3 equal states before actually accepting that we have received a new pulse if ( newSamples == 3 ) { uint16_t queSamples = (uint16_t)((samples * 20 > 60000) ? 60000 : samples * 20); // Calc the time in uS rcvEnQueue(queSamples); // Send the received pulse to the queue. Max 46000 samples = newSamples; newSamples = 0; currValue = value; } }