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);
}