Teensy 3.6 micros() rate depends on digital output state??

Status
Not open for further replies.

DougMcK

Well-known member
Greetings experts!

I have found something a bit surprising and I thought I'd ask to see if this is a known phenomenon.

I have a program that illuminates a "heartbeat" LED for 120mS every second. While it is doing that, it is also generating some 5kHz square waves using SPI DACs. I'm using millis() and micros() in the usual way (like the "blink without delay" example) to trigger these various events. All is working well.

The strange thing that I am noticing is that the rate of the microsecond counter (and maybe more) seems to change significantly (several percent) depending on whether the heartbeat LED is "on" or "off". If the output in question is "high" the timer rate slows down. The effect is quite clear.

I checked the current draw, and it was < 10mA. I further checked for current related effects by reducing it to ~1mA with a larger series resistor. The power supply is not affected by the LED current. I also checked to make sure my logic wasn't doing something obviously stupid by leaving everything the same and replacing the relevant "HIGH" with a "LOW" so that the LED output isn't taken high. The timer rate does not change.

Because the effect did not seem to be load-dependent, I then tried with an un-connected output pin. I found the same effect.

Is this sort of thing expected/known?

cheers
Doug
 
OK, thanks. I'll dig into it further and strip things down to the minimum. I'll report back either with an explanation or a minimal program.
Doug
 
you may, also, as a test, try digitalWriteFast / digitalReadFast as they are built into teensyduino. also keep in mind, because we cant see your code, you may be resetting the millis/micros counters without compensating for the delay in between the updates
 
I've figured out a bit more about this, but am not understanding what's going on.

I have a very simple "state machine" in checkFancyHBLED which flashes an LED in a more "heartbeat" like way. (My wife pointed out that if I'm going to refer to an indication as a heartbeat, it should at least look like one...)

Anyway, it's very simple, and quite slow. The value of the variable HBState2 somehow seems to mess with the timing of the micros() timer that triggers another output, DCB. Seems very unlikely, but I'm not sure what I'm doing wrong..

First attempt to attach. Here goes...
Doug



View attachment TimingTest.ino
 
Ha!
I reckon I've figured it out. It's fixed now. I believe the problem was simply that the details of the slightly different loop caused us to move over the boundary to the next uS. The quantization of integer microseconds is a little coarse.
The fix was simply to add the interval to the previous test value, rather than to the micros() value that has just been read. This avoids the propagation of quantization errors. For this applications, it seems the right way to do it.
Cheers,
Doug
 
"also keep in mind, because we cant see your code, you may be resetting the millis/micros counters without compensating for the delay in between the updates"

:)
 
Status
Not open for further replies.
Back
Top