Arduino-0012 microsecond timing

Timing the width of the IR pulses is critical to interpreting the bits. @ 38kHz the period is 26us, but standard Arduino functions don’t support anything better than ms. The AVR chips themselves are fully capable of us timing though. So the community has developed a way called hptick(). I’d call it a library, but that would imply that this was a published final product with documentation. It isn’t.

There is a lot of older code out there on microsecond timing. They don’t work! Arduino-0012 deprecated alot of the necessary aspects, for better or worse. This one at least compiles in -0012; I haven’t had a chance to test it out yet.

int emitterPin = 4;              // IR emitter
int sensePin = 2;                // This is the INT0 Pin of the ATMega8
volatile boolean value = false;  // Sense value
volatile boolean ready = false;  // Whether bit is ready for loop()
volatile unsigned long start;    // temp value to determine pulse width
volatile unsigned long width;    // Width of IR pulse in microseconds

void setup() {
Serial.begin(9600);
pinMode(emitterPin, OUTPUT); // sets the digital pin as output
pinMode(sensePin, INPUT); // read from the sense pin
attachInterrupt(0, rise, RISING); // configure interrupt
Serial.println("OK");
}

void loop() { }

void rise() {
ready = false; start = hpticks();
digitalWrite(emitterPin, HIGH);
attachInterrupt(0, fall, FALLING);
}

void fall() {
ready = true; width = (hpticks() - start)*4;
digitalWrite(emitterPin, LOW);
attachInterrupt(0, rise, RISING);
}

// below are the custom functions (libraries)
// needed for microsecond timing for Arduino - 0012
// from Don Kinzer on the Arduino forums
extern "C" // defined in wiring.h
{ extern unsigned long timer0_clock_cycles;
extern unsigned long timer0_millis; };

// define the timer interrupt flag register if necessary
#if !defined(TIFR0)
#if defined(TIFR)
#define TIFR0 TIFR
#else
#error AVR device not supported
#endif
#endif

unsigned long hpticks(void) { uint8_t sreg = SREG; cli();
uint16_t t0 = (uint16_t)TCNT0;
if ((TIFR0 & _BV(TOV0)) && (t0 == 0)) t0 = 256;
unsigned long clock_cycles = timer0_clock_cycles;
unsigned long millis = timer0_millis; SREG = sreg;
unsigned long timer0_ticks =
(((millis * (F_CPU / 1000L)) + clock_cycles) / 64) + t0;
return(timer0_ticks); }
Works cited:

Explore posts in the same categories: arduino

Leave a comment