I know how to use the delay action. AFAICT, I can use it to wait arbitrarily long amounts of time. I’m trying to figure out how to do the same thing from within a lambda. The backstory is that I have a lambda doing some things in a loop, and I want a delay between iterations of the loop.
I first tried the standard C/C++ sleep() method, but if I sleep more than 4-5 seconds, the ESP32 reboots. I imagine that’s some kind of watchdog timer reset. I’ve also tried splitting it up into a bunch of sleeps of a 1 ms with an esphome::yield call between each of them. Same reboot result. I’m now trying kookier and kookier things to abuse ESPHome APIs, but I think maybe I might be overlooking something simple.
How could I implement the equivalent of “sleep(N)” for arbitrary N in a lambda?
since a lambda is translated into c code (as far is i know), it should be possible to use delay(x) in lambda’s (x in milliseconds). and the “native” delay function should not trigger the WDT
That was my thinking, too, but it didn’t work. I got an ESP32 reboot when I delayed more than 4-5 seconds. It’s possible that I didn’t do it correctly since I was trying a lot of different things in rapid succession. It seems like it should work.
I found a clunky workaround by converting the loop in my lambda into an ESPHome while loop, which means I have a handful of static variables in the lambda to keep track of state and an ESPHome global variable to communicate out of the lambda. This isn’t a style of coding I would recommend to anyone, but it does at least work for this scenario.
Did you try the esphome::delay() functions in your testing?
esphome::delay ( uint32_t ms )
esphome::delay_microseconds_safe ( uint32_t us )
You might be able to use the interval component or the component with the lambda to use set_update_interval (uint32_t update_interval_ms) to dynamically change the trigger interval to get a dynamic delay. Something like this…
In the generated code, there is a #define so that delay() is the same as esphome::delay. I can’t remember if I tried esphome::delay_microseconds_safe, but I remember coming across it. I also saw the use of DelayAction instances in the generated code. That’s probably what I really needed to use instead of the delay function.
I don’t want to stray too far into undocumented territory since a monthly ESPHome release can clobber me. I was really hoping that there was some well-known way to do this that I was just missing. Unless I find that well-known way, I’ll probably stick with the while loop workaround. At least everything there is documented and so should be stable.
I think they idea of changing the value of an interval is probably just a different way of doing that I did in the while loop since it would still mean multiple invocations of my lambda and some static variables inside it to keep track of state.