@timx, the dallas library is essentially a bit-banged FSM to read the temperature via the onewire library. For me, the issue here is that the 9-bit temperature should take no more than 95ms to obtain and the timer callback which calls the dallas code should behave like it does in loop(). What I find most interesting is that with threading disabled, the temperature reads correctly 50% of the time but with threading enabled, it never reads correctly. This behaviour is important for me to understand how software timer callbacks work within the timer task context. Based on what I learn and from feedback from @mdma (I hope!), I can write some guidelines for what can and canât be done with software timers.
I've tried your code and reproduced the errors. From experimenting, loop() code seems to interrupt timers (interleaves) even though multiple timer tasks queue behind each other. Making this change to the code (even with SYSTEM_THREAD(ENABLED)), based on the suggestion from the link below, and I got 100% success:
volatile float tempCheck;
SINGLE_THREADED_BLOCK() {
temp.requestTemperaturesByIndex(0);
tempCheck = temp.getTempCByIndex(0);
};
Ref posting by @MrZane:
@timx, got the same results as you. I hate blocking threads for 95ms though but thatâs what happens when you use time-sensitive bit-banging code!
The RTOS is continually time-slicing between threads every millisecond, or more often when a thread starts but then signals it has no work to do.
Using the SINGLE_THREADED_BLOCK()
is the way to go to protect timing critical regions of code, or they can be rewritten to use hardware timers, which avoids busy waits.
I would imagine that the 95ms delay doesnât need to be protected by a single thread block, but rather itâs the bit banging code inside the Dallas library that needs protecting.