Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ESP32-C3 - Version 3.0 breaks BLEHIDDevice LEDs events (Caps Lock, Num Lock, etc.) #10432

Open
Assignees
Labels
Milestone
@GiyeopKim1993

Description

Board

ESP32-C3

Device Description

Geekble Mini ESP-C3
it should work on any ESP32-C3 with BT connection.

Hardware Configuration

D9 is pullup button.
usb serial connected pc.

Version

v3.0.0

IDE Name

ArduinoIED

Operating System

macOS

Flash frequency

?

PSRAM enabled

yes

Upload speed

115200

Description

LED events work correctly on WINDOWS and ANDROID, but they do not function on macOS.

Please check if this issue is the same as the one where LED events did not work when using USB with QMK, TinyUSB, etc.

Sketch

/* 
 * Sample program for ESP32 acting as a Bluetooth keyboard
 * 
 * Copyright (c) 2019 Manuel Bl
 * 
 * Licensed under MIT License
 * https://opensource.org/licenses/MIT
 */
//
// This program lets an ESP32 act as a keyboard connected via Bluetooth.
// When a button attached to the ESP32 is pressed, it will generate the key strokes for a message.
//
// For the setup, a momentary button should be connected to pin 2 and to ground.
// Pin 2 will be configured as an input with pull-up.
//
// In order to receive the message, add the ESP32 as a Bluetooth keyboard of your computer
// or mobile phone:
//
// 1. Go to your computers/phones settings
// 2. Ensure Bluetooth is turned on
// 3. Scan for Bluetooth devices
// 4. Connect to the device called "ESP32 Keyboard"
// 5. Open an empty document in a text editor
// 6. Press the button attached to the ESP32
#define US_KEYBOARD 1
#include <Arduino.h>
#include "BLEDevice.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
// Change the below values if desired
#define BUTTON_PIN SW_BUILTIN
#define MESSAGE "Hello from ESP32\n"
#define DEVICE_NAME "Geekble Keyboard"
// Forward declarations
void bluetoothTask(void*);
void typeText(const char* text);
bool isBleConnected = false;
void setup() {
 Serial.begin(115200);
 // configure pin for button
 pinMode(BUTTON_PIN, INPUT_PULLUP);
 // start Bluetooth task
 xTaskCreate(bluetoothTask, "bluetooth", 20000, NULL, 5, NULL);
}
void loop() { 
 if (isBleConnected && digitalRead(BUTTON_PIN) == LOW) {
 // button has been pressed: type message
 Serial.println(MESSAGE);
 typeText(MESSAGE);
 }
 delay(100);
}
// Message (report) sent when a key is pressed or released
struct InputReport {
 uint8_t modifiers;	 // bitmask: CTRL = 1, SHIFT = 2, ALT = 4
 uint8_t reserved; // must be 0
 uint8_t pressedKeys[6]; // up to six concurrenlty pressed keys
};
// Message (report) received when an LED's state changed
struct OutputReport {
 uint8_t leds; // bitmask: num lock = 1, caps lock = 2, scroll lock = 4, compose = 8, kana = 16
};
// The report map describes the HID device (a keyboard in this case) and
// the messages (reports in HID terms) sent and received.
static const uint8_t REPORT_MAP[] = {
 USAGE_PAGE(1), 0x01, // Generic Desktop Controls
 USAGE(1), 0x06, // Keyboard
 COLLECTION(1), 0x01, // Application
 REPORT_ID(1), 0x01, // Report ID (1)
 USAGE_PAGE(1), 0x07, // Keyboard/Keypad
 USAGE_MINIMUM(1), 0xE0, // Keyboard Left Control
 USAGE_MAXIMUM(1), 0xE7, // Keyboard Right Control
 LOGICAL_MINIMUM(1), 0x00, // Each bit is either 0 or 1
 LOGICAL_MAXIMUM(1), 0x01,
 REPORT_COUNT(1), 0x08, // 8 bits for the modifier keys
 REPORT_SIZE(1), 0x01, 
 HIDINPUT(1), 0x02, // Data, Var, Abs
 REPORT_COUNT(1), 0x01, // 1 byte (unused)
 REPORT_SIZE(1), 0x08,
 HIDINPUT(1), 0x01, // Const, Array, Abs
 REPORT_COUNT(1), 0x06, // 6 bytes (for up to 6 concurrently pressed keys)
 REPORT_SIZE(1), 0x08,
 LOGICAL_MINIMUM(1), 0x00,
 LOGICAL_MAXIMUM(1), 0x65, // 101 keys
 USAGE_MINIMUM(1), 0x00,
 USAGE_MAXIMUM(1), 0x65,
 HIDINPUT(1), 0x00, // Data, Array, Abs
 REPORT_COUNT(1), 0x05, // 5 bits (Num lock, Caps lock, Scroll lock, Compose, Kana)
 REPORT_SIZE(1), 0x01,
 USAGE_PAGE(1), 0x08, // LEDs
 USAGE_MINIMUM(1), 0x01, // Num Lock
 USAGE_MAXIMUM(1), 0x05, // Kana
 LOGICAL_MINIMUM(1), 0x00,
 LOGICAL_MAXIMUM(1), 0x01,
 HIDOUTPUT(1), 0x02, // Data, Var, Abs
 REPORT_COUNT(1), 0x01, // 3 bits (Padding)
 REPORT_SIZE(1), 0x03,
 HIDOUTPUT(1), 0x01, // Const, Array, Abs
 END_COLLECTION(0) // End application collection
};
BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
const InputReport NO_KEY_PRESSED = { };
/*
 * Callbacks related to BLE connection
 */
class BleKeyboardCallbacks : public BLEServerCallbacks {
 void onConnect(BLEServer* server) {
 isBleConnected = true;
 // Allow notifications for characteristics
 BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
 cccDesc->setNotifications(true);
 Serial.println("Client has connected");
 }
 void onDisconnect(BLEServer* server) {
 isBleConnected = false;
 // Disallow notifications for characteristics
 BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
 cccDesc->setNotifications(false);
 Serial.println("Client has disconnected");
 }
};
/*
 * Called when the client (computer, smart phone) wants to turn on or off
 * the LEDs in the keyboard.
 * 
 * bit 0 - NUM LOCK
 * bit 1 - CAPS LOCK
 * bit 2 - SCROLL LOCK
 */
 class OutputCallbacks : public BLECharacteristicCallbacks {
 void onWrite(BLECharacteristic* characteristic) {
 OutputReport* report = (OutputReport*) characteristic->getData();
 Serial.print("LED state: ");
 Serial.print((int) report->leds);
 Serial.println();
 }
};
void bluetoothTask(void*) {
 // initialize the device
 BLEDevice::init(DEVICE_NAME);
 BLEServer* server = BLEDevice::createServer();
 server->setCallbacks(new BleKeyboardCallbacks());
 // create an HID device
 hid = new BLEHIDDevice(server);
 input = hid->inputReport(1); // report ID
 output = hid->outputReport(1); // report ID
 output->setCallbacks(new OutputCallbacks());
 // set manufacturer name
 hid->manufacturer()->setValue("Maker Community");
 // set USB vendor and product ID
 hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
 // information about HID device: device is not localized, device can be connected
 hid->hidInfo(0x00, 0x02);
 // Security: device requires bonding
 BLESecurity* security = new BLESecurity();
 security->setAuthenticationMode(ESP_LE_AUTH_BOND);
 // set report map
 hid->reportMap((uint8_t*)REPORT_MAP, sizeof(REPORT_MAP));
 hid->startServices();
 // set battery level to 100%
 hid->setBatteryLevel(100);
 // advertise the services
 BLEAdvertising* advertising = server->getAdvertising();
 advertising->setAppearance(HID_KEYBOARD);
 advertising->addServiceUUID(hid->hidService()->getUUID());
 advertising->addServiceUUID(hid->deviceInfo()->getUUID());
 advertising->addServiceUUID(hid->batteryService()->getUUID());
 advertising->start();
 Serial.println("BLE ready");
 delay(portMAX_DELAY);
};
void typeText(const char* text) {
 int len = strlen(text);
 for (int i = 0; i < len; i++) {
 // translate character to key combination
 uint8_t val = (uint8_t)text[i];
 if (val > KEYMAP_SIZE)
 continue; // character not available on keyboard - skip
 KEYMAP map = keymap[val];
 // create input report
 InputReport report = {
 .modifiers = map.modifier,
 .reserved = 0,
 .pressedKeys = {
 map.usage,
 0, 0, 0, 0, 0
 }
 };
 // send the input report
 input->setValue((uint8_t*)&report, sizeof(report));
 input->notify();
 delay(5);
 // release all keys between two characters; otherwise two identical
 // consecutive characters are treated as just one key press
 input->setValue((uint8_t*)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
 input->notify();
 delay(5);
 }
}

Debug Message

.

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions

    AltStyle によって変換されたページ (->オリジナル) /