Closed TheLostLambda closed 1 year ago
Hmm, sad news... I've err, tried things with a debug build and it seems that (with Embassy as the executor at least), it struggles to keep up with the timing-sensitive protocol?
I'll investigate further (as it looks like Embassy being particularly slow here), but I'd suggest testing with --release if you have any issues!
Double update, this isn't particularly unique to my async version — if I edit the sync version to output a signal on a notify pin (so I can look at latencies with my oscilloscope), it also times out every time...
Might just be something that's best in release mode regardless!
Last few updates! Overloading Embassy with busy tasks means that every .await
encountered in this async driver can be interrupted and bits can be missed, leading to checksum errors!
Currently the whole read takes 22ms, with 18ms of those being a blocking wait! As a side-note (maybe for another PR), the DHT22 only needs a 1ms delay there! That brings the total read time down to 5ms and is definitely something to be implemented here either way!
Additionally, though this would matter most for the DHT11 with that longer initial pull-down, how would you feel about an async version that uses an async wait there (before data transmission), but uses blocking waits for all of the microsecond delays when receiving the data? That way actual data reading can't be interrupted by other tasks (just real interrupts, I suppose).
I don't know if that's the best-practices solution, but a driver that relies on sensitive timing handing over control to literally any task with no guarantee it will hand back control soon (let alone in the next few microseconds) seems a bit silly.
I've had a blast coding all of this up, but I'm wondering if we wouldn't be better off addressing things with just two smaller PRs — one adding async to that initial 18ms wait, and the other making that 18µs into 1µs for the DHT22.
Sorry for that but let me know what you think!
Closing in favor of #18! (But maybe still some interesting information here)
It's a bit messy still because I need some testing and input from @michaelbeaumont , but it works beautifully on my Pi Pico using Embassy!
Here is the example code that works on my Pico:
Pretty much identical to how I was using the sync version before!
Now I suppose I need your help to:
stm32f042
examples<E>
generic on the Error type — it was a source of frustration when implementing theawait_with_timeout()
function and all of my error types wereInfallible
anyways so I removed that bit of information? It's nicer working without the generics everywhere, but it does lose a bit of information and I'm not thrilled with my stop-gap in the syncread.rs
file... If you want that back, I'll add that back and add in some turbofish annotations that I think should fix the issues I ran into inread_async.rs
InputOutputPin<E>
with justInputPin + OutputPin
— kinda tied to point 2 I suppose!crates.io
— currently any cargo commands that build the examples fail because they can't resolve those local paths!cargo tree
below), how would you feel about splitting the library intoblocking
andasync
modules and getting rid of the feature flag? Might help to disentangle things a bit, let's users use both APIs at once (if they ever need to) and shouldn't affect the compile-time much at all!Thanks for the lovely library! Now I just need your help to polish up what's already here!