Possible library conflict on ESP32 (BLE & microSD on SPI)?

Hi,

I hope I selected the correct Category.
I am writing the firmware for a medium complex board that has a Heltec ESP32 WiFi Oled v1 board, as the processor. I know the board has been phased out, but at this prototype stage, it is OK for us.
Now, very late in the project the SD code was added for logging events and BLE was added for wireless hardware configuration purposes.
To have wireless interaction running for a deadline, more simple BluetoothSerial was initially used (only for android), but by only including BluetoothSerial.h, even before any BluetoothSerial functions or objects where called/created, SD would stop working. Removing the include of BluetoothSerial.h would solve the problem. So we arrived at the deadline without BT working but with a "reasonable" explanation :frowning: .
Due to the fact that BLE was always meant as the correct protocol (Android & iOS), and naively hoping it would require less than 800k of flash I migrated the BT code to BLE (Server, services & characteristics), implementing a server to which Android and iOS clients would connect. At the beginning only dealing with generic "LightBlue" and "nRF Connect" Android clients.

These are the BLE and SD links I based my coding on:

This is my compile output:

Linking .pio\build\heltec_wifi_kit_32\firmware.elf
Retrieving maximum program size .pio\build\heltec_wifi_kit_32\firmware.elf
Checking size .pio\build\heltec_wifi_kit_32\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [==        ]  23.2% (used 75860 bytes from 327680 bytes)   
Flash: [========= ]  94.7% (used 1241637 bytes from 1310720 bytes)
Building .pio\build\heltec_wifi_kit_32\firmware.bin
esptool.py v4.5.1
Creating esp32 image...
Merged 25 ELF sections
Successfully created esp32 image.

THE PROBLEM:

  1. If I have an SD card inserted (SD_card.begin() returned true) and I use LightBlue or nRF Connect on Android to inspect the Advertised structure, my esp32 crashes always. If I try to connect after the crash, it crashes again.
  2. If I remove the SD (after boot with a successfull begin() or if I never insert an SD card before booting) everything works fine with BLE and I am able to change an advertised Server characteristic (that was defined as read/write).
  3. If I keep the SD card inserted and ony remove the following 3 BLE statements (No variable or charactersistic that can be inspected or changed from Android):
    pCharacteristic = pService->createCharacteristic(
                                            CHARACTERISTIC_UUID,
                                            BLECharacteristic::PROPERTY_READ |
                                            BLECharacteristic::PROPERTY_WRITE
                                        );
    pCharacteristic->setCallbacks(new BLE_Characteristic_Callback());

    pCharacteristic->setValue((char *)BT_message);

everything works fine (though useless).

Because the project if fairly complex and includes more than 60 files (.h / .cpp) I decided to recreate the problem in a very simple shorter environment to show the issue, but to my surprise it does not crash. A bummer!
In my firmware the crash happens even before any of the 3 Server (onConnect, onDisconnect and onMtuChanged) and the 2 Characteristics (onRead and onWrite) callbacks can print a debug message. So I imagine it crashes the BLE core, but only in the big program and not the reduced one I thought I could shere with somebody willing to help.

MY SETUP:

I am working on a Windows 10 platform, using VSC and PlatformIO IDE as the chosen plugin (pio v3.3.1).

This is the VSC info:

Version: 1.84.2 (user setup)
Commit: 1a5daa3a0231a0fbba4f14db7ec463cf99d7768e
Date: 2023-11-09T10:51:52.184Z
Electron: 25.9.2
ElectronBuildId: 24603566
Chromium: 114.0.5735.289
Node.js: 18.15.0
V8: 11.4.183.29-electron.0
OS: Windows_NT x64 10.0.19045

This is the Platformio.ini file:

[env:heltec_wifi_kit_32]
platform = espressif32
board = heltec_wifi_kit_32
framework = arduino
monitor_speed = 115200
lib_deps = 
	heltecautomation/Heltec ESP32 Dev-Boards@^1.1.1
	fbiego/ESP32Time@^2.0.4
build_flags = -DBLE_42_FEATURE_SUPPORT=TRUE -DBLE_50_FEATURE_SUPPORT=TRUE

The last line "build_flags" I added after reading several posts realed to BLE/SD problems and it seemed to helped with BluetoothSerial, and I did not removed it when changing from BT to BLE.

This is the BLE code:

    BLEDevice::init(BLUETOOTH_BLE_DEVICE);
    pServer = BLEDevice::createServer();
    pService = pServer->createService(SERVICE_UUID);
    pCharacteristic = pService->createCharacteristic(
                                            CHARACTERISTIC_UUID,
                                            BLECharacteristic::PROPERTY_READ |
                                            BLECharacteristic::PROPERTY_WRITE
                                        );
    pServer->setCallbacks(new BLE_Server_Callback());
    pCharacteristic->setCallbacks(new BLE_Characteristic_Callback());
    pCharacteristic->setValue((char *)BT_message);
    pService->start();
    // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
    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();

These are the callbacks:

bool deviceConnected = false;


void BLE_Characteristic_Callback::onRead(BLECharacteristic* pCharacteristic) {
    Serial.printf("Characteristic was read!\n");
}

void BLE_Characteristic_Callback::onWrite(BLECharacteristic* pCharacteristic) {

    BT_message_length = pCharacteristic->getLength();
    Serial.printf("We recieved %d bytes from the app!\n", BT_message_length);
    strncpy((char *)BT_message, (char *)pCharacteristic->getData(), BT_message_length);
    BT_message[BT_message_length] = 0;
    Serial.printf("Text received is '%s'\n", BT_message);
    BT_message_loaded = true;
}

void BLE_Server_Callback::onConnect(BLEServer* pServer) {
    deviceConnected = true;
    Serial.printf("Device connected!\n");
};

void BLE_Server_Callback::onDisconnect(BLEServer* pServer) {
    deviceConnected = false;
    pServer->getAdvertising()->start();
    Serial.printf("Device dis-connected!\n");
}

void BLE_Server_Callback::onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) {

    Serial.printf("MTU changed!\n");
}

I am observing a similar possible conflict between arduino-libraries/ArduinoBLE@^1.1.3 and SD_MMC. I am using ESP32 Cam module. The module works fine without BLE. It initiates SD_MMC, takes photos on SD card. Then I enable the BLE code. The BLE code worked fine a an isolated test that I run with WebBLE API. But enabled together, only the BLE part works. Once the BLE is initialized, I cannot create files on SD Card. it returns E (3111) diskio_sdmmc: sdmmc_read_blocks failed (257).

Now, since ESP32 uses an internal UART to communicate with the BLE module, and they most probably don't share hardware, it still is possible that the BLE library is conflicting with the SD library.

If you think there is a library conflict then it would be a good idea to report it to Espressif as it is they that produce and support the ESP32 plugin for the Arduino IDE.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.