When to use send callbacks in ESP-Now

Long time no post, I've been kind of away from microcontroller project work recently. Having picked up coding again I've come across an interesting issue with ESP-Now on ESP8266.

It's not really an issue as such, but might catch you out.

Most of the time, when you send ESP-Now packets with...

esp_now_send(uint8 *da, uint8 *data, uint8 len);
...there's a temptation to assume they will always be sent.

However packets are not sent until the core gets around to it.

If your code does some slow blocking work after asking for the packet to be sent, the core will abandon sending the packet silently. You should instead register a callback function with... 

esp_now_register_send_cb(esp_now_send_cb_t cb);
...and only continue with other activity, especially slow blocking activity, once that occurs.

My code was registering callbacks but as all it seemed they did was confirm a send I didn't really need confirming, the functions were stub ones where I'd commented out everything of note.

Most of the time this won't catch you out, but the timeout before the core abandons sending is rather short. A very dirty workaround might be to delay/yield for a short while after sending, but flagging the send as successful or not in the callback is the better option.

I had been struggling with unexplained packet drops in certain parts of my big ESP application and waiting for the send callbacks has eliminated these. A less I/O heavy application would probably never experience them.

No comments: