-
The version using deep sleep does currently not connect via Bluetooth:
#include <BleKeyboard.h> #include "esp_sleep.h" BleKeyboard bleKeyboard("Justus Music Page Turner"); #define BUTTON_PIN 2 // Analog-capable pin for pressure/button input const int threshold = 3000; // Analog threshold const int time_pressed = 300; // Time in ms to switch between 'A' and 'B' bool isAboveThreshold = false; unsigned long pressStartTime = 0; bool hasSentKey = false; void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); // Can stay for analog-capable pin // Allow wake every 50 ms to poll esp_sleep_enable_timer_wakeup(50 * 1000); // microseconds bleKeyboard.begin(); } void loop() { // Light sleep allows BLE to stay connected esp_light_sleep_start(); int analogValue = analogRead(BUTTON_PIN); // Serial.println(analogValue); if (!bleKeyboard.isConnected()) return; if (analogValue > threshold) { if (!isAboveThreshold) { isAboveThreshold = true; pressStartTime = millis(); hasSentKey = false; } else if (!hasSentKey) { unsigned long heldTime = millis() - pressStartTime; if (heldTime >= time_pressed) { bleKeyboard.write('B'); Serial.println("Sent 'B'"); hasSentKey = true; } } } else { if (isAboveThreshold && !hasSentKey) { unsigned long heldTime = millis() - pressStartTime; if (heldTime < time_pressed) { bleKeyboard.write('A'); Serial.println("Sent 'A'"); } } // Reset for next input isAboveThreshold = false; hasSentKey = false; } }
Edited by Simon Markus Haller-Seeber -
Folgendes hat mir mal ChatGPT nach eingiem hin und her zum probieren vorgeschlagen
#include <NimBLEDevice.h> #include "HIDTypes.h" #include "BLEHIDDevice.h" BLEHIDDevice* hid; BLECharacteristic* input; class MyCallbacks : public NimBLEServerCallbacks { void onConnect(NimBLEServer* pServer) { Serial.println("Device connected"); } void onDisconnect(NimBLEServer* pServer) { Serial.println("Device disconnected"); NimBLEDevice::startAdvertising(); } }; void setup() { Serial.begin(115200); // Init BLE NimBLEDevice::init("Page-Turner"); // Disable BLE security NimBLEDevice::setSecurityAuth(false, false, false); NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT); NimBLEServer* pServer = NimBLEDevice::createServer(); pServer->setCallbacks(new MyCallbacks()); hid = new BLEHIDDevice(pServer); input = hid->inputReport(1); // ID = 1 // Basic HID descriptor for a keyboard (can also be adapted to presenter) const uint8_t reportMap[] = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x06, // Usage (Keyboard) 0xA1, 0x01, // Collection (Application) 0x05, 0x07, // Usage Page (Key Codes) 0x19, 0xe0, // Usage Minimum (224) 0x29, 0xe7, // Usage Maximum (231) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x08, // Report Count (8) 0x81, 0x02, // Input (Data, Variable, Absolute) ;Modifier byte 0x95, 0x01, // Report Count (1) 0x75, 0x08, // Report Size (8) 0x81, 0x01, // Input (Constant) ;Reserved byte 0x95, 0x05, // Report Count (5) 0x75, 0x01, // Report Size (1) 0x05, 0x08, // Usage Page (LEDs) 0x19, 0x01, // Usage Minimum (1) 0x29, 0x05, // Usage Maximum (5) 0x91, 0x02, // Output (Data, Variable, Absolute) ;LED report 0x95, 0x01, // Report Count (1) 0x75, 0x03, // Report Size (3) 0x91, 0x01, // Output (Constant) ;LED report padding 0x95, 0x06, // Report Count (6) 0x75, 0x08, // Report Size (8) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x65, // Logical Maximum(101) 0x05, 0x07, // Usage Page (Key codes) 0x19, 0x00, // Usage Minimum (0) 0x29, 0x65, // Usage Maximum (101) 0x81, 0x00, // Input (Data, Array) 0xC0 // End Collection }; hid->manufacturer()->setValue("ESP Manufacturer"); hid->pnp(0x02, 0xe502, 0xa111, 0x0210); // vendorID source, vendorID, productID, version hid->hidInfo(0x00, 0x01); hid->reportMap((uint8_t*)reportMap, sizeof(reportMap)); hid->startServices(); NimBLEAdvertising* advertising = NimBLEDevice::getAdvertising(); advertising->setAppearance(HID_GENERIC); advertising->addServiceUUID(hid->hidService()->getUUID()); advertising->start(); Serial.println("BLE HID ready!"); } void loop() { // Simulate "Next Slide" (Right Arrow) every 10 seconds delay(10000); Serial.println("Sending RIGHT ARROW"); uint8_t key[] = { 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Right Arrow input->setValue(key, sizeof(key)); input->notify(); delay(20); // key press duration uint8_t release[] = { 0x00 }; input->setValue(release, 1); // release input->notify(); }
Edited by Simon Markus Haller-Seeber -
#include <BleKeyboard.h> // ==== BLE Keyboard Settings ==== BleKeyboard bleKeyboard("Music-Page-Turner", "JP", 100); // ==== Pin Assignments ==== #define BUTTON_PIN 2 #define BATTERY_PIN 35 // ==== ADC Settings ==== const float ADC_MAX = 4095.0; // 12-bit ADC const float ADC_REF_VOLTAGE = 3.3; // ESP32 ADC reference const int pressThreshold = 30; // pressed if analog < this const int releaseThreshold = 80; // must rise above to count as released const int time_pressed = 300; // long press threshold (ms) const int debounceTime = 50; // debounce time (ms) // ==== Button State ==== bool isPressed = false; unsigned long pressStartTime = 0; bool hasSentKey = false; unsigned long lastChangeTime = 0; // ==== Battery Percentage Calculation (rounded to nearest 5%) ==== int batteryPercentRounded(float volts) { int pct; if (volts >= 3.95) pct = 100; else if (volts <= 3.2) pct = 0; else pct = (int)((volts - 3.2) / (3.95 - 3.2) * 100); int remainder = pct % 5; if (remainder >= 3) pct += (5 - remainder); else pct -= remainder; return constrain(pct, 0, 100); } // ==== Battery Voltage Reading with Averaging ==== float readBatteryVoltage() { long sum = 0; const int samples = 20; for (int i = 0; i < samples; i++) { sum += analogRead(BATTERY_PIN); delay(2); } int raw = sum / samples; float voltageAtPin = (raw / ADC_MAX) * ADC_REF_VOLTAGE; return voltageAtPin * 2; // voltage divider correction } // ==== Button Handling ==== void handleButton() { int analogValue = analogRead(BUTTON_PIN); unsigned long now = millis(); // Debounce if (now - lastChangeTime < debounceTime) return; if (!isPressed && analogValue < pressThreshold) { // Button just pressed isPressed = true; pressStartTime = now; hasSentKey = false; lastChangeTime = now; Serial.println("Pressed"); } else if (isPressed && analogValue > releaseThreshold) { // Button just released unsigned long heldTime = now - pressStartTime; if (!hasSentKey && heldTime < time_pressed) { bleKeyboard.write(KEY_RIGHT_ARROW); Serial.println("Short press"); } isPressed = false; lastChangeTime = now; Serial.println("Released"); } else if (isPressed && !hasSentKey) { // Still held, check for long press unsigned long heldTime = now - pressStartTime; if (heldTime >= time_pressed) { bleKeyboard.write(KEY_LEFT_ARROW); Serial.println("Long press"); hasSentKey = true; } } } void setup() { Serial.begin(115200); pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(BATTERY_PIN, INPUT); analogReadResolution(12); analogSetPinAttenuation(BATTERY_PIN, ADC_11db); // Start BLE bleKeyboard.begin(); } void loop() { if (!bleKeyboard.isConnected()) { delay(50); return; } // ---- Battery Reporting ---- static unsigned long lastBatteryPrint = 0; if (millis() - lastBatteryPrint >= 1000) { float batteryVoltage = readBatteryVoltage(); int batteryPct = batteryPercentRounded(batteryVoltage); bleKeyboard.setBatteryLevel(batteryPct); Serial.print("Battery Voltage: "); Serial.print(batteryVoltage, 1); Serial.print(" V ("); Serial.print(batteryPct); Serial.println("%)"); lastBatteryPrint = millis(); } // ---- Button Handling ---- handleButton(); delay(20); }
Edited by Simon Markus Haller-Seeber
Please register or sign in to comment