Macro Keypad
What is it?
A macro keypad is physical or touch screen keypad that maps multiple or common used shortcut keys to an individual action, think (un)mute on Zoom which by default is ALT + A
Prior Art
- https://github.com/leobrowning92/numpad-ProMicro - This was the plan for V1.00
- https://there.oughta.be/a/macro-keyboard
- https://handsontek.net/experience-building-free-touch-deck/
Implementation
There are multiple ways this can be done and a common approach is to use a Pro Micro as it has the ability to be programmed as a HID device and emulate both keyboard and mouse however I struggled to do this so ended using an ESP32 and presenting it as a bluetooth keyboard.
V1.00 - Status abandoned couldn't get Pro Micro to program
- Pro micro - generic clone
- 3D Printed case - link from thingiverse goes here
- Cherry MX clone switches - ebay link here
V1.01 - Status working
- ESP32-WROOM Module - "borrowed" from HS
- 3D Printed case - https://www.thingiverse.com/thing:1735671/files
- Cherry MX clone switches - ebay link here
Currently have 2 switched hooked up to ESP32 sending ALT + a to mute and unmute and ALT + v to start and stop video
Uses the blekeyboard library for Arduino from https://github.com/T-vK/ESP32-BLE-Keyboard/
Ver 1 Code
#define UK_KEYBOARD 1
#include <Arduino.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
// Change the below values if desired
#define BUTTON_1_PIN 23
#define BUTTON_2_PIN 22
#define MESSAGE "Hello from ESP32\n"
#define DEVICE_NAME "My Keyboard"
// Forward declarations
void bluetoothTask(void*);
void typeText(const char* text);
bool isBleConnected = false;
void setup() {
Serial.begin(115200);
bleKeyboard.begin();
// configure pin for button
pinMode(BUTTON_1_PIN, INPUT_PULLUP);
pinMode(BUTTON_2_PIN, INPUT_PULLUP);
}
void loop() {
if (bleKeyboard.isConnected() && digitalRead(BUTTON_1_PIN) == LOW) {
// button has been pressed: type message
//Serial.println(MESSAGE);
//typeText(MESSAGE);
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending F3...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('a');
delay(100);
bleKeyboard.releaseAll();
}
if (bleKeyboard.isConnected() && digitalRead(BUTTON_2_PIN) == LOW) {
// button has been pressed: type message
//Serial.println(MESSAGE);
//typeText(MESSAGE);
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending F3...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('v');
delay(100);
bleKeyboard.releaseAll();
}
}
Ver 1.01 Code
/*
* Macro Keypad program for ESP32 acting as a Bluetooth keyboard
*
* Copyright (c) 2021 B Norcutt
*
* 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 defined.
//
// For the setup, a momentary button should be connected to pin 23,22,21, 19 and to ground.
// Pins 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"
//
#define UK_KEYBOARD 1
#include <Arduino.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
// Change the below values if desired
#define BUTTON_1_PIN 23
#define BUTTON_2_PIN 22
#define BUTTON_3_PIN 21
#define BUTTON_4_PIN 19
#define MESSAGE "Hello from ESP32\n"
#define DEVICE_NAME "My Keyboard"
// Forward declarations
void bluetoothTask(void*);
void typeText(const char* text);
bool isBleConnected = false;
int buttonNumber = 0;
void setup() {
Serial.begin(115200);
bleKeyboard.begin();
// configure pins for button
pinMode(BUTTON_1_PIN, INPUT_PULLUP);
pinMode(BUTTON_2_PIN, INPUT_PULLUP);
pinMode(BUTTON_3_PIN, INPUT_PULLUP);
pinMode(BUTTON_4_PIN, INPUT_PULLUP);
}
void loop() {
if (digitalRead(BUTTON_1_PIN) == LOW) {
// button 1 has been pressed:
buttonNumber = 1;
}
else if (digitalRead(BUTTON_2_PIN) == LOW) {
// button 2 has been pressed:
buttonNumber = 2;
}
else if (digitalRead(BUTTON_3_PIN) == LOW) {
// button 3 has been pressed:
buttonNumber = 3;
}
else if (digitalRead(BUTTON_4_PIN) == LOW){
// button 4 has been pressed:
buttonNumber = 4;
}
else {buttonNumber = 0; }
switch (buttonNumber) {
case 1:
//do something when buttonNumber equals 1 and ble connected
//(un)mute mic
if (bleKeyboard.isConnected()) {
// button has been pressed:
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending Alt+A...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('a');
delay(100);
bleKeyboard.releaseAll();
}
break;
case 2:
//do something when buttonNumber equals 2
//Start or Stop video
if (bleKeyboard.isConnected()) {
// button has been pressed:
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending F3...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('v');
delay(100);
bleKeyboard.releaseAll();
}
break;
case 3:
//do something when buttonNumber equals 3
//Start screen sharing
if (bleKeyboard.isConnected()) {
// button has been pressed:
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending F3...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('s');
delay(100);
bleKeyboard.releaseAll();
}
break;
case 4:
//do something when buttonNumber equals 4
//Show Hide chat panel
if (bleKeyboard.isConnected()) {
// button has been pressed:
Serial.println("Sending Ctrl+Alt+Shift...");
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_LEFT_SHIFT);
delay(100);
bleKeyboard.releaseAll();
Serial.println("Sending Alt+A...");
//bleKeyboard.press(KEY_F3);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press('h');
delay(100);
bleKeyboard.releaseAll();
}
break;
default:
// if nothing else matches, do the default
// default is optional
buttonNumber = 0;
break;
}
}