-
Notifications
You must be signed in to change notification settings - Fork 7.6k
BluetoothSerial silently drops bytes to be sent #1537
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
Comments
Pinging @copercini |
could you, please, double check ? I am sending NMEA strings over SPP (> 32 bytes) and everything is fine to me with current Core ( IDF aaf1239 ). |
I'll double check tomorrow - but I am very certain that I saw it with the previous core (before aaf1239) yesterday. I saw this using the Firmata library, which uses So, my guess is that there is a certain limit of outstanding bytes to be transmitted over SPP. Perhaps your connection was stronger, so there was less of a backlog? Or perhaps it matters whether you queue multiple bytes at once, or one-by-one (which was what this Firmata library was doing). |
I just double checked with the new core - still seeing this issue! |
@gohai do you have some code that I can reproduce this issue here? |
Sure - this demonstrates it clearly
This is what I received (I added line breaks to increase readability):
|
I can confirm that:
|
I can confirm too, it's triggering ESP_SPP_CONG_EVT sometimes that is a congestion event
|
I have a project where we (crazy as we are) try to send a short message like I made a small test sketch were I start sending every 100ms, then every 66ms and so on down to every 5ms. Here is the log result:
|
This effect seems gone writing all data with one
or with println:
|
@copercini I like workarounds. Will try tomorrow and give feedback. |
@copercini , tried it and the first one worked for me, together with a reduction of the sending frequency. |
Update: Just informing here, no blaming or complaining! |
You need to factor in your application design also. If you for example use bt serial in the loop and have other threads running on core 1, it's totally possible that the loop does not get to run often enough. If the code is the same, there should not be any performance difference between Arduino and IDF. Since it's totally fine to compile IDF code inside Arduino, can you try your "pure ESP-IDF" code in Arduino and see what happens? use |
@me-no-dev |
as I understood of IDF API when it gets an The problem is that we don't know when it's available again, if it were possible to know that would be easy to make it stop writing when you received an Or even easy, get some bad answer from a bit off topic, @beegee-tokyo do you know how many heap is Bluekitchens BTstack using? |
Actually, thats what I did to detect write errors and congestions. I added flags that reflect the cong status and on next write request I return an error. According to the doc I found the congestion event is called every time the congestion status changes. Did not check that out, because my customer is pressuring and I moved on with BTstack for now. Will check for heap usage tomorrow and report back. |
@beegee-tokyo could you try with the attached libbt.a ? here at least the code provided by @gohai here is running fine now, without any extract it in the folder |
@copercini just to confirm, thats to be applied to Arduino-ESP32? And where can I find the changes that @gohai did? Want to try the same in ESP-IDF and if it works submit a merge request.to ESP-IDF (or better, @gohai does) |
yes, it's for arduino... but for IDF you can just comment this line https://github.com/espressif/esp-idf/blob/be81d2c16d7f4caeea9ceb29fece01510664caf3/components/bt/bluedroid/stack/rfcomm/rfc_utils.c#L468 (tip from Markus Becker on esp32 forum) and should work |
@copercini all below is done on ESP-IDF app without Arduino (not even as a component) Bluedroid output while sending to client
BTstack output while sending to the client:
I can see very rare the Regarding the heap usage of BTstack, here are some measurements done with BTstack and BlueDroid. Each time I connected/disconnected a client 3 times to see how the heap changes.
BTstack second run
BlueDroid first run
BlueDroid second run
Looks like I have around 30k more free heap after initialization of the BT Serial when using BTstack.
|
@beegee-tokyo wow, awesome report! I had thought in use BTstack for BTserial some months ago, even before BlueDroid support, but the commercial use requires a paid license, that is not compatible with this repo idea =( About the congest problem, as you are running everything on IDF, seems to be a problem that goes beyond Arduino Core, so there is more chance that you will have a solution opening an issue on IDF repo, because you can get some official Espressif support, including from who ported BlueDroid to ESP32 |
@copercini will do this some time later. Right now I am too busy with 3 parallel customer projects for AVR Mega, ESP8266 and ESP32 (the one with the crazy Bluetooth requirements). |
I was translating a LoRa GPS tracker program that runs quite happily on an 8Mhz Arduino Pro Mini across to the ESP32. The program sends formatted NMEA strings over Bluetooth to an Android mapping app that sees the Bluetooth as a local GPS. On ESP32 it did notr work, I worked out eventually that the ESP32 was dropping parts (or all) of the NMEA strings. On doing some Goggling I found this issue and applied the suggestion above by @copercini to replace libbt.a, and indeed Bluetooth is now working as expected, so many thanks to @copercini. I suspect I may be seeing something similar when parsing the incoming serial stream from the GPS, it appears to be dropping blocks of incoming characters (so the program does not report a GPS fix) is it possible a similar issue to this Bluetooth serial problem is also affecting the reading of incoming serial data ? |
@beegee-tokyo, Re: heap usage of BTstack, Also, if possible , can you please share this test, I'd like to run it on my ESP32 to check for similar results. |
@Ameritronik |
Fixed! 96822d7 This implements a kinda of software flow control that waits when get a |
In BluetoothSerial.cpp, #define RX_QUEUE_SIZE 512 |
I see @copercini said this was fixed a few years ago, but I am also experiencing a similar issue now when sending byte-by-byte data out over bluetooth serial at higher speeds (~250kb/s), using Arduino to program my ESP32. On the receiving end, there are missing bytes. I am struggling to even find the folder where the libbt.a is to apply the suggested fix. Any help would be appreciated! |
@big-eng:
|
Hello, did it work for you? im still getting congested messages sending every 100ms (max size is 103 bytes per msg), the BT results is very poor. [ 19340][E][BluetoothSerial.cpp:202] _spp_send_buffer(): SPP Write Congested! |
I 've reported this problem to Arduino, and they will use the solution in upcoming ESP32 Version 3.0.0. See also: #8859 void bluetooth_receiveBT(const uint8_t *buffer, size_t size) { void bluetooth_receiveSerial() { while ((len = Serial.read(ReceiveBuffer, sizeof(ReceiveBuffer))) > 0) { |
@italocjs: |
it seems that my issue was being caused by the serial terminal bluetooth app on android. i was testing with it and quickly got the buffer congested (even using 100ms delay between msgs), i have now created my own app and did not have any issues since. My issue was client side. I will try to investigate more and update that issue you mentioned when i have more information. |
Nice that you 've found the problem. |
Wow, i'm not even close to 1kb! can you share an snippet of how you achieved this? Im sending log files over BT, 10 lines per second (each line with exactly 103 bytes) |
Attached some code snippets from my project. Hope you can understand them. |
I forgot the connect function: void bluetooth_connect() { |
Thank you very much!!! i will study your code and implement it here! |
I am using the
BluetoothSerial::write()
method to send single bytes to the host computer. I have discovered that when I am sending more that ~ 32 bytes at a time, the ESP will silently drop the additional bytes. Adding adelay(10);
after each byte fixes this for me, but this is only a stop-gap solution.Oddly,
esp_spp_write
does returnESP_OK
even when it is dropping bytes, so I believe there is a real bug here.I am running
arduino-esp32
at c63d746, with an rebuiltlibbt.a
that has a COD set so that macOS will accept the SPP device (but no other changes).The text was updated successfully, but these errors were encountered: