메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

2x2 매크로 키보드 만들기: 두 판 사이의 차이

데브카페
 
(같은 사용자의 중간 판 하나는 보이지 않습니다)
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 매크로 키보드 만들기

  • 준비물
  1. ESP32 C3 Supermini
  2. 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 라이브러리 (추천)

  • 가장 검증되고 쉬운 방법입니다.
  1. 준비물
    - Arduino IDE 설치
    - ESP32 보드 패키지 설치
    - ESP32-BLE-Keyboard 라이브러리 (T-vK 제작)
  2. 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 선택
  3. 라이브러리 설치
     스케치 → 라이브러리 포함하기 → 라이브러리 관리
     검색: "ESP32 BLE Keyboard" (by T-vK) 설치
  4. 예제 (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');
    }
  1. 예제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);
    }
  }
}

사용법

Comments