Page 1 of 2
ESP32 SPP send throughput
Posted: Sat May 05, 2018 2:24 am
by peterlspot
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?
Re: ESP32 SPP send throughput
Posted: Sat May 05, 2018 2:27 pm
by Markus Becker
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
Re: ESP32 SPP send throughput
Posted: Mon May 07, 2018 11:08 pm
by peterlspot
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.
Re: ESP32 SPP send throughput
Posted: Tue May 08, 2018 10:21 pm
by Markus Becker
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
Re: ESP32 SPP send throughput
Posted: Wed Jul 04, 2018 4:09 am
by brGiba
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.
Re: ESP32 SPP send throughput
Posted: Tue Aug 28, 2018 12:55 pm
by gunar.kroeger
Still waiting for an answer for this.
Looks like a bug to me.
Re: ESP32 SPP send throughput
Posted: Fri Aug 31, 2018 4:54 am
by perryc
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
Posted: Mon Sep 03, 2018 2:30 am
by perryc
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
Posted: Thu Oct 11, 2018 8:09 am
by vinci1989
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.
Code: Select all
for (auto i{0}; i < MAX_RFC_PORTS; ++i)
rfc_cb.port.port[i].credit_tx = 10;
// esp_spp_write here
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:
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/"
With this (hopefully temporary) fix I've just sent multiple MB files around with 1MBaud and not a single byte went missing.
Re: ESP32 SPP send throughput
Posted: Thu Nov 22, 2018 10:01 am
by blueMoodBHD
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.