ESP32 SPP send throughput
-
- Posts: 13
- Joined: Thu Mar 29, 2018 11:22 pm
ESP32 SPP send throughput
I am trying sending data from ESP32 via esp_spp_write over a SPP handle to an Android device. The ESP32 does esp_spp_write() of 510 bytes packet and then sleep 84ms in a loop. This implies a 1000/84*510=6KB/s.
The puzzle point is that I got quite a few ESP_SPP_CONG_EVT during the process. What exactly does it mean? I didn't see data loss at receiver side though. does the CONG event means that SPP is not able to carry 6KB/s throughput?
The puzzle point is that I got quite a few ESP_SPP_CONG_EVT during the process. What exactly does it mean? I didn't see data loss at receiver side though. does the CONG event means that SPP is not able to carry 6KB/s throughput?
-
- Posts: 22
- Joined: Fri Mar 02, 2018 3:24 pm
Re: ESP32 SPP send throughput
The ESP_SPP_CONG_EVT can have different reasons ranging from filled queues, out of heap to flow control.
In the callback however, the reason for the congestion is not reported to the app, which complicates things as on congestion data can be lost or not, depending on that reason.
In my case, I found flow control to be the reason for ESP_SPP_CONG_EVTs in situations that I didn't expect. I found credit based flow control enabled for all (my) SPP connections while I don't know, if that can be configured (on the acceptor or/and on the initiator side).
Anyway, I have the impression that after calling esp_spp_write() a few times, the server runs out of credits which triggers the congestion event. As far as I understand the stack then requests more credits from the peer and congestion is cleared as soon the peer sends these credits. Then the server continues sending data to the peer, no data is lost (given esp_spp_write() was not called while congested.
I made a test by by commenting out the line p_port->tx.peer_fc = TRUE; in function rfc_dec_credit in rfc_utils.c to brute force disable tx flow control. In my case data transmission was faster, no packets lost, no congestion events any more. Thats just a primitive test, not a solution of course.
Is this a bug? A wrong configuration? Client dependant? How to handle correctly? - sorry, I don't know.
Best,
Markus
In the callback however, the reason for the congestion is not reported to the app, which complicates things as on congestion data can be lost or not, depending on that reason.
In my case, I found flow control to be the reason for ESP_SPP_CONG_EVTs in situations that I didn't expect. I found credit based flow control enabled for all (my) SPP connections while I don't know, if that can be configured (on the acceptor or/and on the initiator side).
Anyway, I have the impression that after calling esp_spp_write() a few times, the server runs out of credits which triggers the congestion event. As far as I understand the stack then requests more credits from the peer and congestion is cleared as soon the peer sends these credits. Then the server continues sending data to the peer, no data is lost (given esp_spp_write() was not called while congested.
I made a test by by commenting out the line p_port->tx.peer_fc = TRUE; in function rfc_dec_credit in rfc_utils.c to brute force disable tx flow control. In my case data transmission was faster, no packets lost, no congestion events any more. Thats just a primitive test, not a solution of course.
Is this a bug? A wrong configuration? Client dependant? How to handle correctly? - sorry, I don't know.
Best,
Markus
-
- Posts: 13
- Joined: Thu Mar 29, 2018 11:22 pm
Re: ESP32 SPP send throughput
Thank you Marcus, it is good to know that I am not alone. In my case, there is no peer verification since it is an one-way data collecting usage pattern.
-
- Posts: 22
- Joined: Fri Mar 02, 2018 3:24 pm
Re: ESP32 SPP send throughput
hmm, I'm not sure, if that was clear enough. Flow control can affect all SPP connections and is organized "under the hood" within the stack, so that might well affect your use case as well. "Credit based flow control" is a mechanism for SPP, which is negotiated between acceptor and initiator when the connection is established.
Anyway, right now I'm rather happy with SPP. I get reasonable transmission rates and stable communication. Maybe, you might want to have a look into the pull request I placed on github.
Best,
Markus
Anyway, right now I'm rather happy with SPP. I get reasonable transmission rates and stable communication. Maybe, you might want to have a look into the pull request I placed on github.
Best,
Markus
Re: ESP32 SPP send throughput
I have the same issue with arduino ESP32 core (BluetoothSerial.h) and my android app but not with win10 Realterm. The ESP_SPP_CONG_EVT appears on all terminal apps that I have tested, in android, after one single write command performed. The read operation after a write operation becomes slow, broken and completely useless. The problem with read operation is normalized only after a disconnect/connect operation from android side. With windows terminal, the operation performs flawlessly.
Regards from Brazil.
Regards from Brazil.
- gunar.kroeger
- Posts: 143
- Joined: Fri Jul 27, 2018 6:48 pm
Re: ESP32 SPP send throughput
Still waiting for an answer for this.
Looks like a bug to me.
Looks like a bug to me.
"Running was invented in 1612 by Thomas Running when he tried to walk twice at the same time."
Re: ESP32 SPP send throughput
For what it's worth we are struggling with sending files over BT SPP as well. We think we are checking and waiting for congestion to clear in every case and still occasionally a complete buffer write goes missing (900 byte buffers in our case but tried smaller). 10 ms or 300ms waits between buffer writes seems to behave about the same.
Re: ESP32 SPP send throughput
Spent some more time on our SPP tx throughput issue. Sure seems there is something weird going on. A lowly $50 Kindle Fire seems to work great. I'm seeing 380Kb/s using a 20mS delay loop when while congestion is set on 256 byte buffers. I tx-ed about 350MB from esp32 to tablet error free using that timing. With a Galaxy S7 it seems about 100KB can be sent at about the same 380Kb/s rate and then congestion becomes far more prevalent and things drop to a miserable 1-4Kb/s. I seem to be getting some success if we start seeing congestion lasting more than 100mS (5 iterations of the 20 mS delay) if I increase timing delays between writes I can maintain a 50Kb/s rate without loosing data.
Re: ESP32 SPP send throughput
For future reference... the issue is still relevant. I've just created another thread not knowing what I was dealing with before: viewtopic.php?f=13&t=7586
The good news is that Markus Beckers workaround still works as well. Since I'm not a huge fan of tinkering with code inside the IDF framework itself I've decided to rather manipulate the transmission credit count right before each SPP transfer.
The rfc_cb instance is declared in the header "rfc_int.h". Since you pull quite a lot of dependencies in I also had to add the following includes in order to get the code to compile:
With this (hopefully temporary) fix I've just sent multiple MB files around with 1MBaud and not a single byte went missing.
The good news is that Markus Beckers workaround still works as well. Since I'm not a huge fan of tinkering with code inside the IDF framework itself I've decided to rather manipulate the transmission credit count right before each SPP transfer.
Code: Select all
for (auto i{0}; i < MAX_RFC_PORTS; ++i)
rfc_cb.port.port[i].credit_tx = 10;
// esp_spp_write here
Code: Select all
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/"
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/common/include/"
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/stack/include/"
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/api/include/"
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/osi/include/"
CPPFLAGS += -I"/opt/esp/esp-idf/components/bt/bluedroid/stack/rfcomm/include/"
-
- Posts: 7
- Joined: Wed Nov 07, 2018 3:47 am
Re: ESP32 SPP send throughput
Hi all,
There is one thing that needs attention here. We can't call esp_spp_write() multiple times in succession. We should wait for ESP_SPP_WRITE_EVT, then call esp_spp_write() again.
So, when do you call esp_spp_write()?If you call it multiple times in succession, please change it and test again.
Thanks.
There is one thing that needs attention here. We can't call esp_spp_write() multiple times in succession. We should wait for ESP_SPP_WRITE_EVT, then call esp_spp_write() again.
So, when do you call esp_spp_write()?If you call it multiple times in succession, please change it and test again.
Thanks.
Who is online
Users browsing this forum: Bing [Bot] and 335 guests