Skip to content

Instantly share code, notes, and snippets.

@ctmakro
Last active April 28, 2020 18:01
Show Gist options
  • Save ctmakro/59b0b1841b09777f13ae87255d865e7d to your computer and use it in GitHub Desktop.
Save ctmakro/59b0b1841b09777f13ae87255d865e7d to your computer and use it in GitHub Desktop.
Correct way to do precisely timed routine task on Arduino
/*
With an Arduino,
If you want to:
1) execute a function precisely every N microseconds (or precisely 1,000,000/N times every second),
REGARDLESS of the running time of that function
2) obtain a precision of +-4 microseconds with NO ACCUMULATION OF ERROR
3) use no 3rd party libraries
Then this is for you.
*/
// every time toggle() is called, we flip pin 13 (LED).
unsigned char j = 0;
void toggle() {
j = 1 - j;
digitalWrite(13, j ? HIGH : LOW);
}
typedef unsigned long ul;
class Every {
ul last_t;
public:
ul interval; void(*callback)();
Every(ul itvl, void(*cb)()) : interval(itvl), callback(cb) {}
// interval(microseconds) should be an unsigned long (uint32) less than or equals 2^30.
void update() {
if ((ul)(micros() - last_t) >= interval) {
callback(); last_t += interval;
}
}
};
Every e(1000, toggle);
// run toggle() every 1000us. (equivalent to running toggle() at 1000Hz)
// by running toggle() at 1000Hz one can obtain a 500Hz square wave on pin 13.
// actual frequency may vary by the oscillator used (crystal vs ceramic vs internal)
// by changing 1000 to 10000, the frequency of the square wave should drop to
// precisely 1/10 of the original frequency when measured with a frequency meter.
void setup() {
pinMode(13, OUTPUT);
}
void loop() {
e.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment