2x2 매크로 키보드 만들기
- ESP32 C3 Supermini
- 1N4148 다이오드 (저항)
ESP32 C3 칩 구성도 (gpio)
┌─────────────┐
│ USB-C │
└─────────────┘
┌───────────────────┐
5V ● │ │ ● IO5
GND ● │ │ ● IO6
3V3 ● │ │ ● IO7
IO4 ● │ ESP32-C3 │ ● IO8
IO3 ● │ │ ● IO9
IO2 ● │ │ ● I1O
IO1 ● │ │ ● I20
IO0 ● │ │ ● I21
└───────────────────┘
납땜
ROW0 ── GPIO4
ROW1 ── GPIO5
COL0 ── GPIO6
COL1 ── GPIO7
- 1N4148 다이오드 (검은 몸통에 흰 띠 있는 부분 = 캐소드)
COL0 COL1
│ │
SW1 ────┼──● SW2──┼──●
│ │ │ │
[D1]│(캐소드→ROW0) [D2]│(캐소드→ROW0)
│ │ │ │
└──┴───── ROW0 ────────┴──┘
SW3 ────┼──● SW4──┼──●
│ │ │ │
[D3]│(캐소드→ROW1) [D4]│(캐소드→ROW1)
│ │ │ │
└──┴───── ROW1 ────────┴──┘
펌웨어 플래싱
- ESP32-C3 + BLE HID (Arduino)
Arduino + BLE Keyboard 라이브러리 (추천)
- 준비물
- - Arduino IDE 설치
- - ESP32 보드 패키지 설치
- - ESP32-BLE-Keyboard 라이브러리 (T-vK 제작)
- Arduino IDE 설정
- Arduino IDE 설치 => https://www.arduino.cc/en/software/
파일 → 환경설정 → 추가 보드 매니저 URL에 입력:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
도구 → 보드 → 보드매니저 → "esp32" 검색 후 설치
도구 → 보드 → ESP32C3 Dev Module 선택
- 라이브러리 설치
스케치 → 라이브러리 포함하기 → 라이브러리 관리
검색: "ESP32 BLE Keyboard" (by T-vK) 설치
- 예제 (2x2 매크로패드)
#include <BleKeyboard.h>
BleKeyboard bleKeyboard("Macro Pad", "DIY", 100);
// 행/열 핀 설정 (ESP32-C3 Supermini 기준 예시)
const int rowPins[2] = {4, 5};
const int colPins[2] = {6, 7};
void setup() {
Serial.begin(115200);
bleKeyboard.begin();
for (int i = 0; i < 2; i++) {
pinMode(rowPins[i], OUTPUT);
digitalWrite(rowPins[i], HIGH);
}
for (int i = 0; i < 2; i++) {
pinMode(colPins[i], INPUT_PULLUP);
}
}
void loop() {
if (bleKeyboard.isConnected()) {
for (int r = 0; r < 2; r++) {
digitalWrite(rowPins[r], LOW);
for (int c = 0; c < 2; c++) {
if (digitalRead(colPins[c]) == LOW) {
handleKey(r, c);
delay(200); // 디바운스
}
}
digitalWrite(rowPins[r], HIGH);
}
}
}
void handleKey(int row, int col) {
if (row == 0 && col == 0) bleKeyboard.write('1');
if (row == 0 && col == 1) bleKeyboard.write('2');
if (row == 1 && col == 0) bleKeyboard.write('3');
if (row == 1 && col == 1) bleKeyboard.write('4');
}
- 예제2 (단축키 입력 )
#include <BleKeyboard.h>
BleKeyboard bleKeyboard("MacroPad", "DIY", 100);
const int keyPins[4] = {10, 5, 6, 7};
const int LED_PIN = 8;
bool lastState[4] = {false, false, false, false};
unsigned long lastChange[4] = {0, 0, 0, 0};
const unsigned long DEBOUNCE_MS = 5;
unsigned long ledOffAt = 0;
void ledBlink(int ms) {
digitalWrite(LED_PIN, LOW); // LOW = 켜짐
ledOffAt = millis() + ms;
}
void sendMacro(int idx) {
switch (idx) {
case 0: // GPIO10 : Ctrl + Insert
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_INSERT);
bleKeyboard.releaseAll();
break;
case 1: // GPIO5 : Ctrl + F12
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_F12);
bleKeyboard.releaseAll();
break;
case 2: // GPIO6 : Ctrl + Alt + Insert
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_LEFT_ALT);
bleKeyboard.press(KEY_INSERT);
bleKeyboard.releaseAll();
break;
case 3: // GPIO7 : Ctrl + F11
bleKeyboard.press(KEY_LEFT_CTRL);
bleKeyboard.press(KEY_F11);
bleKeyboard.releaseAll();
break;
}
}
// sendMacro를 잠시 이걸로 교체해서 테스트
// void sendMacro(int idx) {
// bleKeyboard.print(idx + 1); // 메모장에 1,2,3,4가 찍힘
// }
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH); // HIGH = 꺼짐
for (int i = 0; i < 4; i++) {
pinMode(keyPins[i], INPUT_PULLUP);
}
bleKeyboard.begin();
// 부팅 완료 신호: 3회 깜빡
for (int i = 0; i < 3; i++) {
digitalWrite(LED_PIN, LOW); delay(100);
digitalWrite(LED_PIN, HIGH); delay(100);
}
}
void loop() {
unsigned long now = millis();
if (ledOffAt && now > ledOffAt) {
digitalWrite(LED_PIN, HIGH);
ledOffAt = 0;
}
if (!bleKeyboard.isConnected()) {
if (now % 1000 < 50) digitalWrite(LED_PIN, LOW);
else if (!ledOffAt) digitalWrite(LED_PIN, HIGH);
return;
}
for (int i = 0; i < 4; i++) {
bool pressed = (digitalRead(keyPins[i]) == LOW);
if (pressed != lastState[i] && (now - lastChange[i]) > DEBOUNCE_MS) {
lastChange[i] = now;
lastState[i] = pressed;
if (pressed) {
sendMacro(i);
ledBlink(50);
Serial.printf("KEY%d (GPIO%d)\n", i + 1, keyPins[i]);
}
}
}
}
사용법