Last active
October 27, 2025 18:22
-
-
Save delfer/57ce2fddcc467fabafd079b927459854 to your computer and use it in GitHub Desktop.
ESP32-C3 6 buttons BLE Keyboard
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Make sure you can use the ESP32 with the Arduino IDE (Installed esp32 by Espressif in Board Manager). | |
| // Install Lib https://github.com/delfer/ESP32-BLE-Keyboard | |
| // Download the latest release of this library from the release page (Source code (zip)). | |
| // In the Arduino IDE go to "Sketch" -> "Include Library" -> "Add .ZIP Library..." and select the file you just downloaded. | |
| //#define DEBUG_MODE // Uncomment to disable debug output | |
| #ifdef DEBUG_MODE | |
| #define DEBUG_PRINTF(...) Serial.printf(__VA_ARGS__) | |
| #else | |
| #define DEBUG_PRINTF(...) | |
| #endif | |
| #include <BleKeyboard.h> | |
| // Create a BleKeyboard object. | |
| BleKeyboard bleKeyboard("ESP32C3-6Keypad", "Delfer", 100); | |
| // --- BUTTON CONFIGURATION --- | |
| // Uncomment the following line to use numpad key codes (KEY_NUM_0..KEY_NUM_5) | |
| // If commented, regular digit keys ('0'..'5') will be used | |
| //#define USE_NUMPAD_KEYS | |
| const int BUTTON_PINS[] = {0, 3, 4, 5, 7, 10}; | |
| #ifdef USE_NUMPAD_KEYS | |
| const uint8_t KEY_CODES[] = { | |
| KEY_NUM_0, | |
| KEY_NUM_1, | |
| KEY_NUM_2, | |
| KEY_NUM_3, | |
| KEY_NUM_4, | |
| KEY_NUM_5}; | |
| #else | |
| const uint8_t KEY_CODES[] = { | |
| '0', | |
| '1', | |
| '2', | |
| '3', | |
| '4', | |
| '5'}; | |
| #endif | |
| const int NUM_BUTTONS = sizeof(BUTTON_PINS) / sizeof(BUTTON_PINS[0]); | |
| // --- DEBOUNCE PARAMETERS --- | |
| // Debounce delay in milliseconds. | |
| const unsigned long DEBOUNCE_DELAY_MS = 50; | |
| // --- STATE VARIABLES FOR POLLING --- | |
| // Last stable (steady) button state | |
| int buttonState[NUM_BUTTONS]; | |
| // Last read button state (may be debounced) | |
| int lastButtonState[NUM_BUTTONS]; | |
| // Time of last button state change (for debouncing) | |
| unsigned long lastDebounceTime[NUM_BUTTONS] = {0}; | |
| void setup() { | |
| #ifdef DEBUG_MODE | |
| Serial.begin(115200); | |
| #endif | |
| // Initialize pins | |
| for (int i = 0; i < NUM_BUTTONS; i++) { | |
| pinMode(BUTTON_PINS[i], INPUT_PULLUP); | |
| // Read initial state | |
| int initialState = digitalRead(BUTTON_PINS[i]); | |
| buttonState[i] = initialState; | |
| lastButtonState[i] = initialState; | |
| } | |
| bleKeyboard.begin(); | |
| Serial.println("BLE Keyboard started. Waiting for connection..."); | |
| } | |
| // ----------------------------------------------------------------- | |
| // MAIN LOOP() - BUTTON POLLING WITH DEBOUNCING | |
| // ----------------------------------------------------------------- | |
| void loop() { | |
| // Iterate through all buttons in each cycle | |
| for (int i = 0; i < NUM_BUTTONS; i++) { | |
| // 1. Read the current pin state | |
| int reading = digitalRead(BUTTON_PINS[i]); | |
| // 2. If the state has changed compared to the previous reading, | |
| // reset the debounce timer. | |
| if (reading != lastButtonState[i]) { | |
| lastDebounceTime[i] = millis(); | |
| } | |
| // 3. Check if enough time has passed since the last change. | |
| if ((millis() - lastDebounceTime[i]) > DEBOUNCE_DELAY_MS) { | |
| // If enough time has passed, the state can be considered stable. | |
| // Check if this stable state differs from the previously | |
| // recorded one. | |
| if (reading != buttonState[i]) { | |
| buttonState[i] = reading; // Update stable state | |
| // 4. Handle press or release event | |
| if (buttonState[i] == LOW) { | |
| // EVENT: PRESS (LOW, because INPUT_PULLUP is used) | |
| DEBUG_PRINTF("✅ Button %d (GPIO%d) PRESSED.\n", i + 1, | |
| BUTTON_PINS[i]); | |
| if (bleKeyboard.isConnected()) { | |
| bleKeyboard.press(KEY_CODES[i]); | |
| } | |
| } else { | |
| // EVENT: RELEASE (HIGH) | |
| DEBUG_PRINTF("❌ Button %d (GPIO%d) RELEASED.\n", i + 1, | |
| BUTTON_PINS[i]); | |
| if (bleKeyboard.isConnected()) { | |
| bleKeyboard.release(KEY_CODES[i]); | |
| } | |
| } | |
| } | |
| } | |
| // 5. Save the current read state for the next iteration | |
| lastButtonState[i] = reading; | |
| } | |
| // No delay() in the loop to ensure fast polling and reaction. | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment