다른 명령
| (같은 사용자의 중간 판 하나는 보이지 않습니다) | |||
| 114번째 줄: | 114번째 줄: | ||
} | } | ||
</SOURCE> | </SOURCE> | ||
# 예제2 (단축키 입력 ) | |||
#:<SOURCE LANG=C> | |||
#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]); | |||
} | |||
} | |||
} | |||
} | |||
</SOURCE> | |||
=== '''예제3(USB 연결)''' === | |||
<source lang=c> | |||
#include <USB.h> | |||
#include <USBHIDKeyboard.h> | |||
USBHIDKeyboard usbKeyboard; | |||
const int keyPins[4] = {10, 5, 6, 7}; | |||
bool lastState[4] = {false, false, false, false}; | |||
unsigned long lastChange[4] = {0, 0, 0, 0}; | |||
const unsigned long DEBOUNCE_MS = 5; | |||
void sendMacro(int idx) { | |||
switch (idx) { | |||
case 0: | |||
usbKeyboard.press(KEY_LEFT_CTRL); | |||
usbKeyboard.press(KEY_INSERT); | |||
usbKeyboard.releaseAll(); | |||
break; | |||
case 1: | |||
usbKeyboard.press(KEY_LEFT_CTRL); | |||
usbKeyboard.press(KEY_F12); | |||
usbKeyboard.releaseAll(); | |||
break; | |||
case 2: | |||
usbKeyboard.press(KEY_LEFT_CTRL); | |||
usbKeyboard.press(KEY_LEFT_ALT); | |||
usbKeyboard.press(KEY_INSERT); | |||
usbKeyboard.releaseAll(); | |||
break; | |||
case 3: | |||
usbKeyboard.press(KEY_LEFT_CTRL); | |||
usbKeyboard.press(KEY_F11); | |||
usbKeyboard.releaseAll(); | |||
break; | |||
} | |||
} | |||
void setup() { | |||
for (int i = 0; i < 4; i++) pinMode(keyPins[i], INPUT_PULLUP); | |||
USB.begin(); | |||
usbKeyboard.begin(); | |||
delay(1000); | |||
} | |||
void loop() { | |||
unsigned long now = millis(); | |||
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); | |||
} | |||
} | |||
} | |||
</source> | |||
=== 사용법 === | === 사용법 === | ||
2026년 8월 19일 (수) 08:47 기준 최신판
2x2 매크로 키보드 만들기
- 준비물
- ESP32 C3 Supermini
- 1N4148 다이오드 (저항)
ESP32 C3 칩 구성도 (gpio)
- (뒷면) ESP32-C3 Supermini
┌─────────────┐
│ 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]); } } } }
예제3(USB 연결)
#include <USB.h>
#include <USBHIDKeyboard.h>
USBHIDKeyboard usbKeyboard;
const int keyPins[4] = {10, 5, 6, 7};
bool lastState[4] = {false, false, false, false};
unsigned long lastChange[4] = {0, 0, 0, 0};
const unsigned long DEBOUNCE_MS = 5;
void sendMacro(int idx) {
switch (idx) {
case 0:
usbKeyboard.press(KEY_LEFT_CTRL);
usbKeyboard.press(KEY_INSERT);
usbKeyboard.releaseAll();
break;
case 1:
usbKeyboard.press(KEY_LEFT_CTRL);
usbKeyboard.press(KEY_F12);
usbKeyboard.releaseAll();
break;
case 2:
usbKeyboard.press(KEY_LEFT_CTRL);
usbKeyboard.press(KEY_LEFT_ALT);
usbKeyboard.press(KEY_INSERT);
usbKeyboard.releaseAll();
break;
case 3:
usbKeyboard.press(KEY_LEFT_CTRL);
usbKeyboard.press(KEY_F11);
usbKeyboard.releaseAll();
break;
}
}
void setup() {
for (int i = 0; i < 4; i++) pinMode(keyPins[i], INPUT_PULLUP);
USB.begin();
usbKeyboard.begin();
delay(1000);
}
void loop() {
unsigned long now = millis();
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);
}
}
}