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

Add BluetoothSerial library #1144

Merged
merged 6 commits into from
Mar 5, 2018
Merged

Add BluetoothSerial library #1144

merged 6 commits into from
Mar 5, 2018

Conversation

copercini
Copy link
Contributor

A simple UART to Classical Bluetooth bridge for ESP32

A simple UART to Classical Bluetooth bridge for ESP32
@copercini
Copy link
Contributor Author

@me-no-dev To future versions, it will be necessary to compile the core with the options Classic Bluetooth and SPP Profile of bluedroid in make menuconfig

As workaround, I included my compiled version of btlib in the commit for testing

@beegee-tokyo
Copy link
Contributor

@copercini I pulled your BluetoothSerial library into my existing installation (ESP32 staging), including the libbt.a
When I add

#include "BluetoothSerial.h"
...
BlueToothSerial SerialBT;
...
SerialBT.begin("ESP32");

I get

In file included from C:\users\beegee\.platformio\packages\framework-arduinoespressif32\libraries\BluetoothSerial\src/BluetoothSerial.h:28:0,
from src\bt_serial.cpp:2:
C:\users\beegee\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\bt/bt.h:2:2: warning: #warning "This header is deprecated, please use functions defined in esp_bt.h instead." [-Wcpp]
#warning "This header is deprecated, please use functions defined in esp_bt.h instead."
^
In file included from src/setup.h:50:0,

I recplaced bt.h with esp_bt.h and the warning went away.
And BluetoothSerial works as expected with the example.

@copercini
Copy link
Contributor Author

copercini commented Feb 23, 2018

@beegee-tokyo Thanks for report, I already replaced this by default

@beegee-tokyo
Copy link
Contributor

Playing around with this, I run into a problem. If I send several strings (size between 80 to 100 bytes) immediately after each other, I get a [I][BluetoothSerial.cpp:87] esp_spp_cb(): ESP_SPP_CONG_EVT error thrown. If I add a delay(250) between the calls to SerialBT.write() it works fine, a delay(100) still gives me sometimes the congestion error. I guess the problem is on IDF side, but I wanted to mention it here.

@copercini copercini mentioned this pull request Mar 2, 2018
@lyusupov
Copy link
Contributor

lyusupov commented Mar 3, 2018

@copercini : I have my sketch size of 719018 bytes

Sketch uses 719018 bytes (54%) of program storage space. Maximum is 1310720 bytes.
Global variables use 48444 bytes (16%) of dynamic memory, leaving 246468 bytes for local variables. Maximum is 294912 bytes.

When I add these three lines:

#include "BluetoothSerial.h"
...
BlueToothSerial SerialBT;
...
SerialBT.begin("ESP32");

The size becomes almost twice bigger than before and exceeds maximum allowed limit:

Sketch uses 1371690 bytes (104%) of program storage space. Maximum is 1310720 bytes.
Global variables use 99724 bytes (33%) of dynamic memory, leaving 195188 bytes for local variables. Maximum is 294912 bytes.
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.

Seems to be too high "price" for just one SPP function, isn't it :-)
Do you know how to work this out?

@beegee-tokyo
Copy link
Contributor

It is not the SPP function that increases the sketch size, it is the complete Bluetooth stack behind it. Even for BLE you might need to change your partition size

@lyusupov
Copy link
Contributor

lyusupov commented Mar 3, 2018

@beegee-tokyo: Thank's a lot! Upon edit of partitions.csv and boards.txt the build goes fine and
first connect to SPP works great!

Is it possible to fix esp32 crash upon SPP reconnect somehow?

msys32/home/Note/esp/esp-idf/components/bt/bluedroid/osi/list.c", line 82, function: list_front
abort() was called at PC 0x4014cf47 on core 0

Backtrace: 0x4008b340:0x3ffdf260 0x4008b43f:0x3ffdf280 0x4014cf47:0x3ffdf2a0 0x400eb982:0x3ffdf2d0 0x400f0c56:0x3ffdf2f0 0x400ec59a:0x3ffdf340

Rebooting...

@copercini
Copy link
Contributor Author

@lyusupov It's an IDF bug, that Espressif guys will fix next week espressif/esp-idf#1537

@lyusupov
Copy link
Contributor

lyusupov commented Mar 3, 2018

@copercini Thank you for the library and information!

@me-no-dev
Copy link
Member

good job! Please fix the sketch!

@copercini
Copy link
Contributor Author

@me-no-dev Done =)

@me-no-dev me-no-dev merged commit b4b9a79 into espressif:master Mar 5, 2018
@me-no-dev
Copy link
Member

merged :)

Curclamas pushed a commit to Curclamas/arduino-esp32 that referenced this pull request Aug 21, 2018
* Add BluetoothSerial library

A simple UART to Classical Bluetooth bridge for ESP32

* Create README.md

* Fix typos

* Replace deprecated header and small fixes

* Add coexistence with BLE

* Add missing semicolon
@lucastaonline
Copy link

Hi @copercini .
Got two questions...

I'm sending and receiving a string representing a JSON object through the SerialBT and i noticed that when I receive any data the write speed becomes slower.
This happens on the test sketch (SerialtoSerialBT) too.

In the exact moment that I receive some data the ESP keeps fast, but after almost 2 seconds it becomes slower.

If i receive something again the write gets back it's fast speed and the process repeat itself.

When I disconnect and Android phone from the bluetooth the sketch stops (sometimes) . Is there any way to disconnect and reconnect without stopping the loop() ?

Im using Arduino IDE and Esp32 DevKit v1.

@requeijaum

@copercini
Copy link
Contributor Author

copercini commented Nov 19, 2018

Olá @1uuc4asb,

There is an internal flow control where the first 512 bytes will be read from android and queued till you call SerialBT.read();. When this queue is full, it will stop of receive data until you have some space in this queue, slowing down next bytes... So you can increase the queue or read it faster, removing this delay

About the disconnect and reconnect issue, seems this one: #2009 it will be fix probably in the next IDF compilation

@lucastaonline
Copy link

@copercini
I'm using this lib in other code without delay and, the slowness continues.
Ok, i didn't understand just one thing.
How can the receive queue affect the send speed?

I put the core debug level to "verbose" (using the SerialtoSerialBT sketch) and i noticed that:
from the moment that i receive any data (and with any i mean "hi" or "." ; short strings) the event


[V][BluetoothSerial.cpp:182] esp_spp_cb(): ESP_SPP_CONG_EVT: CONGESTED
[V][BluetoothSerial.cpp:190] esp_spp_cb(): ESP_SPP_WRITE_EVT: 17 CONGESTED

is triggered almost everytime that i send something(thing that only was happening sometimes before).
And in these moments that this event is fired, the slowness happen.

Why when i receive, the sending slow?
There's some way to make this faster?

@chegewara
Copy link
Contributor

CONGEST event means that radio is too busy to send messages with this rate and is queuing messages or just drop it (im not sure).

@lucastaonline
Copy link

@chegewara
It makes sense, but why the radio is busy?

The situation is:
Sending data
Sending data
Sending data
Sending data
Sending data
Congest.
(Repeat)

But if a receive something.

Sending data.
Receive data.
Sending data
Congest
Sending data
Sending data
Congest
Sending data
Congest
Sending data
Sending data
Congest.

This happen after a few seconds.

@chegewara
Copy link
Contributor

Try to add small delay in send loop (3-5ms).

Last few days ive been trying to trigger congest event with ble on esp-idf with no luck. I am able to send notifications 5-6 times per ms and no congest. My speed rate with ble is about 500-600 kbit per second now.

@requeijaum
Copy link

requeijaum commented Nov 21, 2018 via email

@chegewara
Copy link
Contributor

I would suggest to ask this question on forum or esp-idf repo.

@chegewara
Copy link
Contributor

@copercini Thats weird, because like i said earlier i am able to achieve 500-600kbits between esp32 and android smartphone nRF connect in ble app, which should be slower that classic bt. Of course it is app with master esp-idf, not arduino.

@lucastaonline
Copy link

@copercini idk if you noticed, but i'm receiving the string in one 'x' speed.
When i send any data to the esp from the terminal, this speed decreases.
(This happens when i send the string ' { "s": 16 } ' at 0:14 sec)
If i send something again, the speed back to normal and, after a short time, decreases again.
(This happens when i send the string ' { "s": 0 } ' at 0:27 sec and string ' { "s": 2 } ' at 0:44)

Watch closely https://drive.google.com/file/d/1QY0NHfPhY9ilQ5AZLfnezPnzOmbexTMk/view?usp=drivesdk

(You can slow the video's speed to help if u want...)

@copercini
Copy link
Contributor Author

@chegewara here is the problem and workaround: https://www.esp32.com/viewtopic.php?t=5613

@chegewara
Copy link
Contributor

Looks like this link answer all questions from this discussion.

@copercini
Copy link
Contributor Author

@1uuc4asb I compiled a libbt with the workaround proposed in the above link libbt.zip

Try unzip it on C:\Users\%username%\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.0\tools\sdk\lib and test if everything works

@copercini
Copy link
Contributor Author

I opened a new IDF issue about it: espressif/esp-idf#2725

@requeijaum
Copy link

requeijaum commented Nov 22, 2018

I reunited with @1uuc4asb in some fablab here in our city.
So... I downloaded the libbt.zip but I can't get any result. The core 1 crashes miserably.
Any tips?

captura de tela 2018-11-22 as 15 41 49

Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core 1 register dump:
PC      : 0x4000c46c  PS      : 0x00060b36  A0      : 0x800d8914  A1      : 0x3ffb6110  
A2      : 0x3ffb2730  A3      : 0x00000000  A4      : 0x000058d0  A5      : 0x3ffb42c0  
A6      : 0x00000000  A7      : 0x0000058d  A8      : 0x00000000  A9      : 0x3ffb6090  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060f20  A15     : 0x00000000  SAR     : 0x0000000a  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x000003d3  

Backtrace: 0x4000c46c:0x3ffb6110 0x400d8911:0x3ffb6120 0x400d8a9a:0x3ffb6140 0x400d510a:0x3ffb6160 0x400d4a2a:0x3ffb61a0 0x400d22b5:0x3ffb61d0 0x4015a476:0x3ffb6210 0x4008cfc9:0x3ffb6230

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1496
load:0x40078000,len:8596
load:0x40080400,len:6980
entry 0x400806f4

@chegewara
Copy link
Contributor

Debug exception reason: Stack canary watchpoint triggered (loopTask)
try to lover debug level, or check water stack size in setup and/or loop:
uxTaskGetStackHighWaterMark(NULL)

@lucastaonline
Copy link

lucastaonline commented Nov 23, 2018

@chegewara


Rebooting...
[V][esp32-hal-i2c.c:1436] i2cInit(): num=0 sda=21 scl=22 freq=0
[V][esp32-hal-i2c.c:1621] i2cSetFrequency(): Fifo threshold=3
[W][esp32-hal-i2c.c:1363] i2cCheckLineState(): invalid state sda(21)=0, scl(22)=0
[E][esp32-hal-i2c.c:1378] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init sda=0, scl=0
Iniciando <----------------PART OF MY CODE @1uuc4asb ----------------------------------------------------
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered () 
Core 1 register dump:
PC      : 0x4000c46c  PS      : 0x00060b36  A0      : 0x800d9340  A1      : 0x3ffb60c0  
A2      : 0x3ffb2730  A3      : 0x00000000  A4      : 0x000058d0  A5      : 0x3ffb4260  
A6      : 0x00000000  A7      : 0x0000058d  A8      : 0x00000000  A9      : 0x3ffb6040  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060f20  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x000003d9  

Backtrace: 0x4000c46c:0x3ffb60c0 0x400d933d:0x3ffb60d0 0x400d94c6:0x3ffb60f0 0x400d5e14:0x3ffb6110 0x400d5083:0x3ffb6150 0x400d245d:0x3ffb6180 0x4015af06:0x3ffb61b0 0x4008d081:0x3ffb61d0

Rebooting...
[V][esp32-hal-i2c.c:1436] i2cInit(): num=0 sda=21 scl=22 freq=0
[V][esp32-hal-i2c.c:1621] i2cSetFrequency(): Fifo threshold=3
[W][esp32-hal-i2c.c:1363] i2cCheckLineState(): invalid state sda(21)=0, scl(22)=0
[E][esp32-hal-i2c.c:1378] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init sda=0, scl=0
Iniciando
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered () 
Core 1 register dump:
PC      : 0x4000c46c  PS      : 0x00060b36  A0      : 0x800d9340  A1      : 0x3ffb60c0  
A2      : 0x3ffb2730  A3      : 0x00000000  A4      : 0x000058d0  A5      : 0x3ffb4260  
A6      : 0x00000000  A7      : 0x0000058d  A8      : 0x00000000  A9      : 0x3ffb6040  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060f20  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x000003d9  

Backtrace: 0x4000c46c:0x3ffb60c0 0x400d933d:0x3ffb60d0 0x400d94c6:0x3ffb60f0 0x400d5e14:0x3ffb6110 0x400d5083:0x3ffb6150 0x400d245d:0x3ffb6180 0x4015af06:0x3ffb61b0 0x4008d081:0x3ffb61d0

@chegewara
Copy link
Contributor

chegewara commented Nov 23, 2018

This line suggests that error is not related to bluetooth serial:
[E][esp32-hal-i2c.c:1378] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init sda=0, scl=0

What is the code after i2c init?

@lucastaonline
Copy link

@chegewara

Ok. Now i'm using nothing but the Bluetooth.
(SerialtoSerialBT sketch)


Rebooting...
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core 1 register dump:
PC      : 0x4000c46c  PS      : 0x00060b36  A0      : 0x800d5698  A1      : 0x3ffb60c0  
A2      : 0x3ffb2730  A3      : 0x00000000  A4      : 0x000058d0  A5      : 0x3ffb4260  
A6      : 0x00000000  A7      : 0x0000058d  A8      : 0x00000000  A9      : 0x3ffb6040  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060f20  A15     : 0x00000000  SAR     : 0x0000001f  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x000003d9  

Backtrace: 0x4000c46c:0x3ffb60c0 0x400d5695:0x3ffb60d0 0x400d581e:0x3ffb60f0 0x400d2f48:0x3ffb6110 0x400d29db:0x3ffb6150 0x400d226e:0x3ffb6180 0x4015051a:0x3ffb61b0 0x4008c825:0x3ffb61d0


@chegewara
Copy link
Contributor

You have to use tool to decode this:

Backtrace: 0x4000c46c:0x3ffb60c0 0x400d5695:0x3ffb60d0 0x400d581e:0x3ffb60f0 0x400d2f48:0x3ffb6110 0x400d29db:0x3ffb6150 0x400d226e:0x3ffb6180 0x4015051a:0x3ffb61b0 0x4008c825:0x3ffb61d0

https://github.com/me-no-dev/EspExceptionDecoder

@lucastaonline
Copy link

I'm stuck in this.

image

@chegewara
Copy link
Contributor

There is not much i can do or say now. You can find someone with better knowledge than mine or try to create new task in setup and move all your code to that task, because i still believe there is some issue with stack size Debug exception reason: Stack canary watchpoint triggered (loopTask). You have to remember that default task in arduino (loopTask) have about 8kB stack size, so you need to increase it in your own task.

@copercini
Copy link
Contributor Author

copercini commented Nov 23, 2018

Stack canary watchpoint triggered (loopTask) means that your task is out of stack, and it isn't related with BTserial

You can optimize the loop task to use less stack (creating less local variables, less recursion functions, etc), or increase the stack size here from 8192 to a bigger value (may to 12288)

@lucastaonline
Copy link

@copercini
But i'm using the SerialToSerialBT sketch...
Correct me if i'm wrong, but i don't remember any variables or something that coul'd make we run out of stack...

@lucastaonline
Copy link

This happens only when i use the libbt that u compiled...

@chegewara

Ok. Now i'm using nothing but the Bluetooth.
(SerialtoSerialBT sketch)


Rebooting...
Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (loopTask) 
Core 1 register dump:
PC      : 0x4000c46c  PS      : 0x00060b36  A0      : 0x800d5698  A1      : 0x3ffb60c0  
A2      : 0x3ffb2730  A3      : 0x00000000  A4      : 0x000058d0  A5      : 0x3ffb4260  
A6      : 0x00000000  A7      : 0x0000058d  A8      : 0x00000000  A9      : 0x3ffb6040  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000000  A13     : 0x00000001  
A14     : 0x00060f20  A15     : 0x00000000  SAR     : 0x0000001f  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x000003d9  

Backtrace: 0x4000c46c:0x3ffb60c0 0x400d5695:0x3ffb60d0 0x400d581e:0x3ffb60f0 0x400d2f48:0x3ffb6110 0x400d29db:0x3ffb6150 0x400d226e:0x3ffb6180 0x4015051a:0x3ffb61b0 0x4008c825:0x3ffb61d0

@lyusupov
Copy link
Contributor

@1uuc4asb
make sure that you use exactly same environment (Arduino ESP32 revision and ESP-IDF) that @copercini did when he had built the libbt.a library.
There could be an issue if you use "Stable rev. 1.0.0" while @copercini refers to a "bleeding edge" most recent git snapshot.

@gmag11
Copy link

gmag11 commented Jun 1, 2019

I've modified the library to allow master / slave role selection so ESP32 can connect to and use SPP BT devices, like bluetooth GPS receiver, what is my use case.
It is compatible with current library implementation and the only differences in the interface are optional parameters as role and slave address or name in begin () method.
As slave it behaves the same as code on this repository does.
Currently, if role is set to master it tries to connect until it succeed. If connection is lost it retries to connect again automatically.
Do you think it may be useful? I'm going to upload it to my GitHub after I clean the code.

@lyusupov
Copy link
Contributor

lyusupov commented Jun 2, 2019

Can't say for everyone, but I would consider it as a very useful feature.
Current implementation of SPP is asymmetric. Ability to connect to a Bluetooth GPS, another ESP32 or similar device is required in almost 50% cases.

Will be waiting for your upload into your own 'fork' of this repo.

@gmag11
Copy link

gmag11 commented Jun 18, 2019

I've created a repository, this is the link https://github.com/gmag11/BTClassicSPP. Feel free to ask questions there.

@lyusupov
Copy link
Contributor

Germán,

I've applied your code to one of my open source projects where I mostly use SPP in conjunction with ESP32 'slave'.
It works great! I have not tried 'write' operations yet, but 'read's are awesome!
I've intentionally made 'reset' of both parties and connection self recovery had succeed in both cases.

Thank you so much for developing and sharing!

Best regards,
Linar.

@gmag11
Copy link

gmag11 commented Jun 19, 2019

Yes, connection will restart if it is dropped. Thank you for testing

@lyusupov
Copy link
Contributor

I've just noticed that in my environment (ESP32 AC 1.0.1 on both sides) when 'master' reconnects to the 'slave' , the latter makes unwanted self-WDT restart before actual reconnection:

E (73177) task_wdt: Task watchdog got triggered. The following tasks did not re:
E (73177) task_wdt:  - loopTask (CPU 1)
E (73177) task_wdt: Tasks currently running:
E (73177) task_wdt: CPU 0: IDLE0
E (73177) task_wdt: CPU 1: IDLE1
E (73177) task_wdt: Aborting.
abort() was called at PC 0x4015640c on core 0

I wonder of how could I get rid of that restart...

Germán, have you noticed anything similar when you did debugging before the release ?

@gmag11
Copy link

gmag11 commented Jun 20, 2019

I've only tested against a bluetooth GPS receiver. I have not found any problem with watchdog on my side. Try to identify what your code was doing or waiting just before the reboot.

Try to load slave example from IDF repository or this one from Arduino-ESP32 for testing

@lyusupov
Copy link
Contributor

Ok. Thanks for the information!

My ESP32 'slave' gives WDT reset once it gets connected with ESP32 'master'. After the reset, re-established peer-to-peer connection works fine.
When 'master' is an Android phone or other hardware - ESP32 'slave' does not have this WDT reset issue.

Looks like there is an infinite loop somewhere in ESP32 'slave' code but which is triggered only when 'master' is also an ESP32-based device.

@gmag11
Copy link

gmag11 commented Jun 21, 2019

@lyusupov I've been thinking about what's different from first connection to reconnection. Code is the same. Are you using device name or address to start the connection?
If you give device name library first try to resolve device's address using GAP. Maybe you get the error during that process.
Try to start library using your device's mac address.

@gmag11
Copy link

gmag11 commented Jun 21, 2019

@copercini Would you like to add this to your code so that it is native to esp32 Arduino core?

@copercini
Copy link
Contributor Author

@gmag11 sure! for me all the improvements are welcome, please open a pull request to be easier to @me-no-dev manage the code

@lyusupov
Copy link
Contributor

@gmag11

Are you using device name or address to start the connection?

Name.

My 'slave' is this code: https://github.com/lyusupov/SoftRF/blob/master/software/firmware/source/SoftRF/BluetoothHelper.cpp
And my 'master' is that: https://github.com/lyusupov/SoftRF/blob/master/software/firmware/source/SkyView/BluetoothHelper.cpp

Try to start library using your device's mac address.

Will do.
I had no chance to debug the failure yet. I hope, I will do this next week.
Just noticed that when I've disabled WDT 'loop' feature - the 'slave' just hangs on completely and re-connection does not happen at all.

Next week I will try to reproduce this issue using basic BT SPP examples code, same way as you suggested.

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

Successfully merging this pull request may close these issues.

8 participants