Error during runtime after wrapping code in classes (Arduino IDE)
Posted: Mon Aug 05, 2019 12:12 pm
I am trying to write a Bluetooth LE Mouse library that works with the Arduino IDE.
Initially I had this code which worked just fine:
Then I tried to make a library out of that code which can be used like this:
The full code can be found here: https://github.com/T-vK/ESP32-BLE-Mouse
(But I'll also add it to the end of the post to make it easier.)
The example form above gets compiled and uploaded without any errors, but at soon as I try to connect to it via Bluetooth, the ESP32 prints the following error to the serial console:
After decoding it looks like this:
Any ideas how I could fix this? I guess it must be related to line 9 of the onConnect method in BleConnectionStatus.cpp because it says:
"0x400d13ed: BleConnectionStatus::onConnect(BLEServer*) at /home/fedora/Arduino/libraries/ESP32-BLE-Mouse/BleConnectionStatus.cpp line 9"
The code for the library:
BleMouse.h
BleMouse.cpp
BleConnectionStatus.h
BleConnectionStatus.cpp
Initially I had this code which worked just fine:
Code: Select all
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#include <driver/adc.h>
#include "sdkconfig.h"
BLEHIDDevice* hid;
BLECharacteristic* inputMouse;
bool connected = false;
class MyCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer){
connected = true;
BLE2902* desc = (BLE2902*)inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
}
void onDisconnect(BLEServer* pServer){
connected = false;
BLE2902* desc = (BLE2902*)inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(false);
}
};
void taskServer(void*) {
BLEDevice::init("Flip-O-Matic");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyCallbacks());
hid = new BLEHIDDevice(pServer);
inputMouse = hid->inputReport(1); // <-- input REPORTID from report map
std::string name = "chegewara";
hid->manufacturer()->setValue(name);
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
hid->hidInfo(0x00,0x02);
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
const uint8_t reportMapMouse[] = {
USAGE_PAGE(1), 0x01,
USAGE(1), 0x02,
COLLECTION(1), 0x01,
REPORT_ID(1), 0x01,
USAGE(1), 0x01,
COLLECTION(1), 0x00,
USAGE_PAGE(1), 0x09,
USAGE_MINIMUM(1), 0x1,
USAGE_MAXIMUM(1), 0x3,
LOGICAL_MINIMUM(1), 0x0,
LOGICAL_MAXIMUM(1), 0x1,
REPORT_COUNT(1), 0x3,
REPORT_SIZE(1), 0x1,
0x80|0x01, 0x2, // (Data, Variable, Absolute), ;3 button bits
REPORT_COUNT(1), 0x1,
REPORT_SIZE(1), 0x5,
0x80|0x01, 0x1, //(Constant), ;5 bit padding
USAGE_PAGE(1), 0x1, //(Generic Desktop),
USAGE(1), 0x30,
USAGE(1), 0x31,
LOGICAL_MINIMUM(1), 0x81,
LOGICAL_MAXIMUM(1), 0x7f,
REPORT_SIZE(1), 0x8,
REPORT_COUNT(1), 0x2,
0x80|0x01, 0x6, //(Data, Variable, Relative), ;2 position bytes (X & Y)
END_COLLECTION(0),
END_COLLECTION(0)
};
hid->reportMap((uint8_t*)reportMapMouse, sizeof(reportMapMouse));
hid->startServices();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_MOUSE);
pAdvertising->addServiceUUID(hid->hidService()->getUUID());
pAdvertising->start();
hid->setBatteryLevel(7);
ESP_LOGD(LOG_TAG, "Advertising started!");
delay(portMAX_DELAY);
};
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
xTaskCreate(taskServer, "server", 20000, NULL, 5, NULL);
}
void loop() {
if(connected) {
Serial.println("Scroll Up by 1 unit");
uint8_t msg[] = { 0x00, 0x00, 0x00, 0x01 };
inputMouse->setValue(msg,4);
inputMouse->notify();
}
delay(2000);
}
Code: Select all
/**
* This example turns the ESP32 into a Bluetooth LE mouse that scrolls down every 2 seconds.
*/
#include <BleMouse.h>
BleMouse bleMouse;
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
bleMouse.init();
}
void loop() {
if(bleMouse.isConnected()) {
Serial.println("Scroll Down by 1 unit");
bleMouse.scrollDown(1);
}
delay(2000);
}
(But I'll also add it to the end of the post to make it easier.)
The example form above gets compiled and uploaded without any errors, but at soon as I try to connect to it via Bluetooth, the ESP32 prints the following error to the serial console:
Code: Select all
Starting BLE work!
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400d39b8 PS : 0x00060130 A0 : 0x800d2722 A1 : 0x3ffd5a90
A2 : 0x00000018 A3 : 0x2e5470b4 A4 : 0xf0000000 A5 : 0x003ffe46
A6 : 0xb03ffb00 A7 : 0x0001fe46 A8 : 0x3ffc607c A9 : 0x3ffd5ad0
A10 : 0x3ffe914c A11 : 0x0000001c A12 : 0x3ffe950c A13 : 0x3ffe9554
A14 : 0x00000002 A15 : 0x3ffd87e0 SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000024 LBEG : 0x4000c349 LEND : 0x4000c36b LCOUNT : 0xffffffff
Backtrace: 0x400d39b8:0x3ffd5a90 0x400d271f:0x3ffd5af0 0x400d13ed:0x3ffd5b30 0x400d6019:0x3ffd5b70 0x400d3bd9:0x3ffd5bd0 0x400e440a:0x3ffd5bf0 0x400df23e:0x3ffd5c30 0x40090461:0x3ffd5c60
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:1100
load:0x40078000,len:9232
load:0x40080400,len:6400
entry 0x400806a8
Code: Select all
PC: 0x400d39b8: BLEDescriptorMap::getByUUID(BLEUUID) at /home/fedora/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/BLE/src/BLEDescriptorMap.cpp line 33
EXCVADDR: 0x00000024
Decoding stack results
0x400d39b8: BLEDescriptorMap::getByUUID(BLEUUID) at /home/fedora/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/BLE/src/BLEDescriptorMap.cpp line 33
0x400d271f: BLECharacteristic::getDescriptorByUUID(BLEUUID) at /home/fedora/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/BLE/src/BLECharacteristic.cpp line 135
0x400d13ed: BleConnectionStatus::onConnect(BLEServer*) at /home/fedora/Arduino/libraries/ESP32-BLE-Mouse/BleConnectionStatus.cpp line 9
0x400d6019: BLEServer::handleGATTServerEvent(esp_gatts_cb_event_t, unsigned char, esp_ble_gatts_cb_param_t*) at /home/fedora/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/BLE/src/BLEServer.cpp line 171
0x400d3bd9: BLEDevice::gattServerEventHandler(esp_gatts_cb_event_t, unsigned char, esp_ble_gatts_cb_param_t*) at /home/fedora/.arduino15/packages/esp32/hardware/esp32/1.0.2/libraries/BLE/src/BLEDevice.cpp line 129
0x400e440a: btc_gatts_cb_handler at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c line 54
0x400df23e: btc_task at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bt/bluedroid/btc/core/btc_task.c line 110
0x40090461: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143
"0x400d13ed: BleConnectionStatus::onConnect(BLEServer*) at /home/fedora/Arduino/libraries/ESP32-BLE-Mouse/BleConnectionStatus.cpp line 9"
The code for the library:
BleMouse.h
Code: Select all
#ifndef ESP32_BLE_MOUSE_H
#define ESP32_BLE_MOUSE_H
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include "BleConnectionStatus.h"
#include "BLEHIDDevice.h"
#include "BLECharacteristic.h"
class BleMouse {
public:
BleMouse();
void init();
bool isConnected();
void scrollDown(char units);
void scrollUp(char units);
void rawAction(uint8_t msg[], char msgSize);
private:
BleConnectionStatus* connectionStatus;
BLEHIDDevice* hid;
BLECharacteristic* inputMouse;
static void taskServer(void* pvParameter);
};
#endif // CONFIG_BT_ENABLED
#endif // ESP32_BLE_MOUSE_H
Code: Select all
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#include <driver/adc.h>
#include "sdkconfig.h"
#include "BleConnectionStatus.h"
#include "BleMouse.h"
#if defined(CONFIG_ARDUHAL_ESP_LOG)
#include "esp32-hal-log.h"
#define LOG_TAG ""
#else
#include "esp_log.h"
static const char* LOG_TAG = "BLEDevice";
#endif
BleMouse::BleMouse() {
this->connectionStatus = new BleConnectionStatus(this->inputMouse);
}
void BleMouse::init() {
xTaskCreate(this->taskServer, "server", 20000, (void *)this, 5, NULL);
}
void BleMouse::taskServer(void* pvParameter) {
BleMouse* bleMouseInstance = (BleMouse *) pvParameter; //static_cast<BleMouse *>(pvParameter);
BLEDevice::init("ESP32-BLE-Mouse");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(bleMouseInstance->connectionStatus);
bleMouseInstance->hid = new BLEHIDDevice(pServer);
bleMouseInstance->inputMouse = bleMouseInstance->hid->inputReport(1); // <-- input REPORTID from report map
std::string name = "chegewara";
bleMouseInstance->hid->manufacturer()->setValue(name);
bleMouseInstance->hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
bleMouseInstance->hid->hidInfo(0x00,0x02);
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
const uint8_t reportMapMouse[] = {
USAGE_PAGE(1), 0x01,
USAGE(1), 0x02,
COLLECTION(1), 0x01,
REPORT_ID(1), 0x01,
USAGE(1), 0x01,
COLLECTION(1), 0x00,
USAGE_PAGE(1), 0x09,
USAGE_MINIMUM(1), 0x1,
USAGE_MAXIMUM(1), 0x3,
LOGICAL_MINIMUM(1), 0x0,
LOGICAL_MAXIMUM(1), 0x1,
REPORT_COUNT(1), 0x3,
REPORT_SIZE(1), 0x1,
0x80|0x01, 0x2, // (Data, Variable, Absolute), ;3 button bits
REPORT_COUNT(1), 0x1,
REPORT_SIZE(1), 0x5,
0x80|0x01, 0x1, //(Constant), ;5 bit padding
USAGE_PAGE(1), 0x1, //(Generic Desktop),
USAGE(1), 0x30,
USAGE(1), 0x31,
USAGE(1), 0x38,
LOGICAL_MINIMUM(1), 0x81,
LOGICAL_MAXIMUM(1), 0x7f,
REPORT_SIZE(1), 0x8,
REPORT_COUNT(1), 0x3,
0x80|0x01, 0x6, //(Data, Variable, Relative), ;2 position bytes (X & Y)
END_COLLECTION(0),
END_COLLECTION(0)
};
bleMouseInstance->hid->reportMap((uint8_t*)reportMapMouse, sizeof(reportMapMouse));
bleMouseInstance->hid->startServices();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_MOUSE);
pAdvertising->addServiceUUID(bleMouseInstance->hid->hidService()->getUUID());
pAdvertising->start();
bleMouseInstance->hid->setBatteryLevel(7);
ESP_LOGD(LOG_TAG, "Advertising started!");
vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);
}
bool BleMouse::isConnected() {
return this->connectionStatus->connected;
}
void BleMouse::rawAction(uint8_t msg[], char msgSize) {
this->inputMouse->setValue(msg, msgSize);
this->inputMouse->notify();
}
void BleMouse::scrollDown(char unit) {
if(this->isConnected()) {
uint8_t msg[] = { 0x00, 0x00, 0x00, -unit };
this->rawAction(msg, 4);
}
}
void BleMouse::scrollUp(char unit) {
if(this->isConnected()) {
uint8_t msg[] = { 0x00, 0x00, 0x00, unit };
this->rawAction(msg, 4);
}
}
Code: Select all
#ifndef ESP32_BLE_CONNECTION_STATUS_H
#define ESP32_BLE_CONNECTION_STATUS_H
#include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED)
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLECharacteristic.h"
class BleConnectionStatus : public BLEServerCallbacks {
public:
BleConnectionStatus(BLECharacteristic* inputMouse);
bool connected = false;
void onConnect(BLEServer* pServer);
void onDisconnect(BLEServer* pServer);
private:
BLECharacteristic* inputMouse;
};
#endif // CONFIG_BT_ENABLED
#endif // ESP32_BLE_CONNECTION_STATUS_H
Code: Select all
#include "BleConnectionStatus.h"
BleConnectionStatus::BleConnectionStatus(BLECharacteristic* inputMouse) {
this->inputMouse = inputMouse;
}
void BleConnectionStatus::onConnect(BLEServer* pServer) {
this->connected = true;
BLE2902* desc = (BLE2902*)this->inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
}
void BleConnectionStatus::onDisconnect(BLEServer* pServer) {
this->connected = false;
BLE2902* desc = (BLE2902*)this->inputMouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(false);
}