If you want to measure times longer than 70 minutes with
micros()
, you will have to use uint64_t
, and there is nothing
wrong with that.
The code needs to run with as little interruptions as possible [...]
You don't need to do the 64-bit arithmetic within the ISR. You could
very well implement an interrupt-driven 32-bit version, and then extend
it to 64 bits in non-interrupt context. Example:
// Your ISR-based implementation.
uint32_t micros32();
// Extend to 64 bits.
uint64_t micros64() {
static uint32_t low32, high32;
uint32_t new_low32 = micros32();
if (new_low32 < low32) high32++;
low32 = new_low32;
return (uint64_t) high32 << 32 | low32;
}
This should work as long as you call micros64()
often enough.
Presumably, you will have something like
if (micros64() - lastTime > period) { ... }
within your loop, so this should be no issue as long as you never block
your loop.
Actually, you can push this idea even further. If you can guarantee that
micros64()
will be called at least once every 65.5 ms, then you
could have your ISR increment only a 16-bit counter.
millis()
if you are timing rather long periods? – Nick Gammon♦ Apr 3 '18 at 4:12ISR(TIMER0_OVF_vect)
there is a single variable increment. The code needs to run with as little interruptions as possible and I want to be able to run something with irregular long intervals. – Vasil Kalchev Apr 3 '18 at 5:27