Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EspNow send function not working properly #315

Closed
lorenzodellagiustina opened this issue Nov 12, 2023 · 10 comments
Closed

EspNow send function not working properly #315

lorenzodellagiustina opened this issue Nov 12, 2023 · 10 comments

Comments

@lorenzodellagiustina
Copy link

The send function is not working if something is blocking the receive callback.
For example:

// esp now initialization ...
let queue: Arc<Mutex<VecDeque<...>>> = Arc::new(Mutex::new(VecDeque::new()));
let queue_clone = queue.clone();
espnow.register_recv_cb(move |_mac_address, data| {
            // ...
            let queue_clone_lock = queue_clone.lock().unwrap();
            // ...
        })

let queue_lock = queue.lock().unwrap();

// Here we receive a wifi message from another esp -> the receive callback is called

let espnow.send(...)

// Send function won't send anything but won't return any error, the code will continue to execute

// ...

I know that this isn't the right way to use the receive callback but can't we send messages while the receive callback is being executed?

@Vollbrecht
Copy link
Collaborator

Vollbrecht commented Nov 12, 2023

do not block in the callbacks, its a real bad idea, just try to get the data out as fast as possible, and then try to evaluate the data in a lower priority task/ thread. Keep in mind that both callbacks running directly in the wifi_driver thread context not in your context. So you will kill the wifi essentially if you do this.

you can inject a std::channel in both the recv and send callback and then just work with the data you got in the main thread / lower prio thread .

@lorenzodellagiustina
Copy link
Author

Okay, that's not good practice. But ideally I could send and receive simultaneously, right?

@Vollbrecht
Copy link
Collaborator

the callbacks are not related to the part where you can do stuff, they inform you that 'a your packet was send successfully 'b you got a new packet. So you can call send() whenever you want it has no direct blocking connection. This all have nothing to do with simultaneously.

@Vollbrecht
Copy link
Collaborator

And it has nothing to do with good practice in this case to make it clear. If you block in the callback, the wifi_driver cant do any other work, so potentially catastrophic.

@Vollbrecht
Copy link
Collaborator

Vollbrecht commented Nov 12, 2023

To make your case a bit more clear, you have the main task where you do the work, you aquire a lock in the main task, while you have the lock aquired, the thread gets preamptid into the higher prio wifi_thread task. ( the main task still has the lock) . The callback now is executed inside the wifi_driver, trying to get the lock-> It will wait forever because the task has higher prio. You are in a deadlock

@ivmarkov
Copy link
Collaborator

@Vollbrecht thanks for explaining. Closing.

@github-project-automation github-project-automation bot moved this from Todo to Done in esp-rs Nov 12, 2023
@lorenzodellagiustina
Copy link
Author

I probably explained myself badly. While I shouldn't do lengthy operations in the callback function, even if the receive callback is blocked I should still be able to send messages. I understand the reason why that's happening, I'm just suggesting that this should not happen. The code above is just an explanatory example

@ivmarkov
Copy link
Collaborator

ivmarkov commented Nov 12, 2023

I probably explained myself badly. While I shouldn't do lengthy operations in the callback function, even if the receive callback is blocked I should still be able to send messages. I understand the reason why that's happening, I'm just suggesting that this should not happen. The code above is just an explanatory example

OK I understand your request, but I'm not sure we can do it. If you look at the source code, EspNow is a simple wrapper around the ESP NOW functionality in ESP IDF. So in a way, what you are requesting must be implemented inside ESP IDF itself. I.e. ask them to make the "receive" callback non-blocking w.r.t. send. However given that it is inside the Wifi driver, I'm very skeptical that anybody would pay any attention to this request. After all, there are tons of workarounds you can apply.

@lorenzodellagiustina
Copy link
Author

Alright. I opened this issue because for me it was difficult to find out the reason why the send function was not working in certain conditions. Thanks both for your quick reply

@Vollbrecht
Copy link
Collaborator

Vollbrecht commented Nov 12, 2023

on another note if you are using esp-idf 5, the callback we are providing is something suboptimal, we just implemented a quick fix to have both v4 and v5 working, but with v5 you get some more meta information around esp_now_recv_info_t. I planed but did not have the time to upgrade our api to play more nicely here, but i will revisit it the next days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

3 participants