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
.
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:
- 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.
- 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).
- 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");
}