ESP32 ESP32C3 board newer than 2.0.0 has BLE bug, but 2.0.0 is OK.
Posted: Fri Sep 02, 2022 5:26 am
Hi.
I have a weird problem with BLE. If anyone can help, it would be greatly appreciated.
The issues is ONLY found on any Arduino ESP32 board drivers newer than Version 2.0.0, but 2.0.0 works perfectly. So, the latest 2.0.4 shows the bug. Is there a coding workaround?
My unique application sends a tiny amount of variable data periodically in the Device Name. Long story, but there is a reason for doing this but not using a beacon. So for example a device can be "Gadget 001" in the device ID advertisement shown on nRF Connect. Then after an event, a new device "Gadget 002" will appear and so-on.
The application is perfectly fit-for-purpose woth ESP32 board driver 2.0.0. No bugs, no issues.
Then, when I updated the Arduino board driver to esp32 2.0.4, it stopped working. In fact any version never than 2.0.0 fails. The symptom is the first advertisement works fine, then when an event happens, there is no update to the advertisement on a BLE device.
It is clear the problem is that, unlike with 2.0.0, the BLE device does not de-initialize and then re-intialise. Here is the code. The area of interest is line 107 to line 116...
I have a weird problem with BLE. If anyone can help, it would be greatly appreciated.
The issues is ONLY found on any Arduino ESP32 board drivers newer than Version 2.0.0, but 2.0.0 works perfectly. So, the latest 2.0.4 shows the bug. Is there a coding workaround?
My unique application sends a tiny amount of variable data periodically in the Device Name. Long story, but there is a reason for doing this but not using a beacon. So for example a device can be "Gadget 001" in the device ID advertisement shown on nRF Connect. Then after an event, a new device "Gadget 002" will appear and so-on.
The application is perfectly fit-for-purpose woth ESP32 board driver 2.0.0. No bugs, no issues.
Then, when I updated the Arduino board driver to esp32 2.0.4, it stopped working. In fact any version never than 2.0.0 fails. The symptom is the first advertisement works fine, then when an event happens, there is no update to the advertisement on a BLE device.
It is clear the problem is that, unlike with 2.0.0, the BLE device does not de-initialize and then re-intialise. Here is the code. The area of interest is line 107 to line 116...
- #include <BLEDevice.h>
- #include <BLEUtils.h>
- #include <BLEServer.h>
- #include "Gizmo.h"
- /* Timer variables */
- hw_timer_t * timer = NULL;
- volatile uint16_t timerTick1ms = 0;
- uint32_t timeStamp = 0;
- /* Timer ISR */
- void ARDUINO_ISR_ATTR onTimer(){
- /* Flash Blue LED every 2s for 5ms as heartbeat */
- timerTick1ms++;
- if (timerTick1ms >= 1995) {
- digitalWrite(BLUE_LED_PIN,HIGH);
- }
- else {
- digitalWrite(BLUE_LED_PIN,LOW);
- }
- if (timerTick1ms > 2000) {
- timerTick1ms = 0;
- }
- }
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
- char advertText[] = {'G','i','z','m','o',' ','0',' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- char inChar = 0;
- char i = 0, j = 8;
- uint8_t advertCounter = '0';
- const int button = 9;
- void setup() {
- Serial.begin(9600); // Default baud rate
- pinMode(button, INPUT);
- pinMode(BLUE_LED_PIN, OUTPUT);
- pinMode(GREEN_LED_PIN, OUTPUT);
- /* Flash Blue LED three times on POR */
- for (i=0; i<3; i++) {
- digitalWrite(BLUE_LED_PIN, HIGH);
- delay(100);
- digitalWrite(BLUE_LED_PIN, LOW);
- delay(100);
- }
- /* Set up 1ms timer */
- //timerSemaphore = xSemaphoreCreateBinary(); // Create semaphore to inform us when the timer has fired
- timer = timerBegin(0, 80, true);// Use 1st timer of 4 (counted from zero), 80 prescaler.
- timerAttachInterrupt(timer, &onTimer, true); // Attach onTimer function to our timer.
- timerAlarmWrite(timer, 1000, true); // Set alarm to 1ms (in microseconds) & repeat the alarm (third parameter)
- timerAlarmEnable(timer);
- /* Advertise empty data when starting up */
- advertText[5] = VERSION;
- BLEDevice::init(advertText);
- BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
- pAdvertising->addServiceUUID(SERVICE_UUID);
- pAdvertising->setScanResponse(true);
- pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
- pAdvertising->setMinPreferred(0x12);
- BLEDevice::startAdvertising();
- delay(500);
- /* Get rid of any extraneous serial data on startup */
- Serial.flush();
- while(Serial.available()) Serial.read();
- }
- void loop() {
- /* RESET IF BUTTON IS PRESSED */
- if (digitalRead(button) == LOW) { // Reboot if button is pressed
- ESP.restart();
- delay(1000);
- }
- /* PROCESS EACH INCOMING CHARACTER FROM THE WEIGHING MACHINE */
- if (Serial.available() > 0) // A character has been received
- {
- digitalWrite(GREEN_LED_PIN, HIGH); // Flash of green LED
- inChar = Serial.read();
- if((inChar != '\n') && (inChar != '\r') && (j <= MAX_ADVERT_CHARS)) // Ignore the CRLF characters and truncate if too many characters
- {
- advertText[j]= inChar;
- }
- digitalWrite(GREEN_LED_PIN, LOW);
- if (inChar == '\n') { // Linefeed is the end of the incoming string
- if ((millis() - timeStamp) > 750) // Only transmit at a maximum of once per second (750ms + adv setup time) to avoid buffer overrun screwing up the adverts.
- {
- /* One-digit advertisement counter (1 to 9, then repeat) */
- advertCounter++;
- if (advertCounter > '9')
- {
- advertCounter = '1';
- }
- advertText[6] = advertCounter;
- /* Update the BLE advertisement */
- BLEDevice::deinit(false);
- delay(20);
- BLEDevice::init(advertText);
- BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
- pAdvertising->addServiceUUID(SERVICE_UUID);
- pAdvertising->setScanResponse(true);
- pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
- pAdvertising->setMinPreferred(0x12);
- BLEDevice::startAdvertising();
- //delay(5);
- /* Advert has gone out, so re-initialise advert to null characters */
- for (j=8; j<=MAX_ADVERT_CHARS; j++)
- {
- advertText[j] = 0;
- }
- j=8; // We start collecting incoming data at the ninth character in the entire advertisement, eg: after "GadgetA1 "
- timeStamp = millis();
- }
- }
- else j++; // Data is still coming in prior to advert going out.
- }
- }