Last active
May 26, 2024 03:13
-
-
Save gpsnmeajp/2637025fa3744e2d371121b17a687cb2 to your computer and use it in GitHub Desktop.
外部スイッチをATOM Liteを使って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
// Based on https://gist.github.com/3110/161e803683fd14f2b6a533ca010ae5c5 | |
// ライブラリに対する変更点について | |
// ・ESP32-BLE-Keyboard-master.zipを導入 | |
// ・BleKeyboard.hの先頭の「#define USE_NIMBLE」コメントを解除 | |
// 注意: NIMBLEを使用しないと、ペアリング直後は動くが、再接続時に動かない問題が発生する。おそらくESP32のSDK起因の問題。 | |
/* | |
// v002 モードの概念を導入 | |
// v003 モードを0始まりにして、操作の一貫性を導入 | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| モード | - | 0 | - | 1 | - | 2 | - | 3 | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| A長押し| - | 撮影 | - | 輝度アップ | - | - | - | - | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| A短押し| Q | 音量UP | W | 曲送り | E | ズームイン | R | モード切替 | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| Fn | Z | モード1→2 | X | モード2→3 | C | モード3→4 | V | モード4→1 | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| B短押し| A | 音量DW | S | 曲戻し | D | ズームアウト | F | 戻る | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
| B長押し| - | 再生・停止 | - | 輝度ダウン | - | - | - | - | | |
+--------+----------+----------+----------+----------+----------+----------+----------+----------+ | |
*/ | |
#define USE_NIMBLE | |
#include <BleKeyboard.h> // https://github.com/T-vK/ESP32-BLE-Keyboard | |
#include <M5Unified.h> // https://github.com/m5stack/M5Unified | |
#include <Debouncer.h> // https://github.com/hideakitai/Debouncer | |
#define SEND_KEY_A_MODE0 'q' | |
#define SEND_KEY_B_MODE0 'a' | |
#define SEND_KEY_FN_MODE0 'z' | |
#define SEND_KEY_A_MODE1 'w' | |
#define SEND_KEY_B_MODE1 's' | |
#define SEND_KEY_FN_MODE1 'x' | |
#define SEND_KEY_A_MODE2 'e' | |
#define SEND_KEY_B_MODE2 'd' | |
#define SEND_KEY_FN_MODE2 'c' | |
#define SEND_KEY_A_MODE3 'r' | |
#define SEND_KEY_B_MODE3 'f' | |
#define SEND_KEY_FN_MODE3 'v' | |
#define LED GPIO_NUM_27 | |
#define SW_A 26 | |
#define SW_B 32 | |
#define SW_FN 25 | |
const int duration_ms = 100; // デバウンス判定時間 | |
Debouncer debouncerA(SW_A, duration_ms); | |
Debouncer debouncerB(SW_B, duration_ms); | |
Debouncer debouncerFn(SW_FN, duration_ms); | |
const std::string DEVICE_NAME("ATOMBLE"); | |
const std::string DEVICE_MANUFACTURER("M5Stack"); | |
BleKeyboard bleKeyboard(DEVICE_NAME, DEVICE_MANUFACTURER); | |
#define MODE_INIT 0 //初期モード | |
int mode = MODE_INIT; //現在モード | |
unsigned long last_action = 0; //最終操作時間 | |
bool actioned = false; // アクション済み | |
#define MODE_TIMEOUT 8000 // 無操作モード復帰時間 | |
void changeModeApply() { | |
// ガード | |
if (mode > 3) { mode = MODE_INIT; } | |
// モード切替時にアクション済みを解除 | |
actioned = false; | |
// 通知音として現在モード通知キーを送信 | |
switch (mode) { | |
case 0: bleKeyboard.write(SEND_KEY_FN_MODE0); break; | |
case 1: bleKeyboard.write(SEND_KEY_FN_MODE1); break; | |
case 2: bleKeyboard.write(SEND_KEY_FN_MODE2); break; | |
case 3: bleKeyboard.write(SEND_KEY_FN_MODE3); break; | |
default: mode = MODE_INIT; break; // 異常避け | |
} | |
// Serial.println(mode); | |
} | |
void setup() { | |
M5.begin(); | |
bleKeyboard.begin(); | |
pinMode(SW_A, INPUT_PULLUP); | |
pinMode(SW_B, INPUT_PULLUP); | |
pinMode(SW_FN, INPUT_PULLUP); | |
neopixelWrite(LED, 0, 0, 0); | |
debouncerFn.subscribe(Debouncer::Edge::FALL, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
if (bleKeyboard.isConnected()) { | |
// アクション済みなら、初期値から加算したい(Fnボタン統一性) | |
if (actioned == true) { | |
mode = MODE_INIT; | |
} | |
// モードを切り替え | |
mode++; | |
changeModeApply(); | |
} | |
}); | |
debouncerFn.subscribe(Debouncer::Edge::RISE, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
}); | |
debouncerA.subscribe(Debouncer::Edge::FALL, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
// アクション済み | |
actioned = true; | |
if (bleKeyboard.isConnected()) { | |
switch (mode) { | |
case 0: bleKeyboard.press(SEND_KEY_A_MODE0); break; | |
case 1: bleKeyboard.press(SEND_KEY_A_MODE1); break; | |
case 2: bleKeyboard.press(SEND_KEY_A_MODE2); break; | |
case 3: bleKeyboard.press(SEND_KEY_A_MODE3); break; | |
default: break; | |
} | |
} | |
}); | |
debouncerA.subscribe(Debouncer::Edge::RISE, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
if (bleKeyboard.isConnected()) { | |
// キーリリースは、意図しないズレ防止のため常に全キー送る | |
bleKeyboard.release(SEND_KEY_A_MODE0); | |
bleKeyboard.release(SEND_KEY_A_MODE1); | |
bleKeyboard.release(SEND_KEY_A_MODE2); | |
bleKeyboard.release(SEND_KEY_A_MODE3); | |
} | |
}); | |
debouncerB.subscribe(Debouncer::Edge::FALL, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
// アクション済み | |
actioned = true; | |
if (bleKeyboard.isConnected()) { | |
switch (mode) { | |
case 0: bleKeyboard.press(SEND_KEY_B_MODE0); break; | |
case 1: bleKeyboard.press(SEND_KEY_B_MODE1); break; | |
case 2: bleKeyboard.press(SEND_KEY_B_MODE2); break; | |
case 3: bleKeyboard.press(SEND_KEY_B_MODE3); break; | |
default: break; | |
} | |
} | |
}); | |
debouncerB.subscribe(Debouncer::Edge::RISE, [](const int state) { | |
// 最終操作時間を記録 | |
last_action = millis(); | |
if (bleKeyboard.isConnected()) { | |
// キーリリースは、意図しないズレ防止のため常に全キー送る | |
bleKeyboard.release(SEND_KEY_B_MODE0); | |
bleKeyboard.release(SEND_KEY_B_MODE1); | |
bleKeyboard.release(SEND_KEY_B_MODE2); | |
bleKeyboard.release(SEND_KEY_B_MODE3); | |
} | |
}); | |
} | |
void loop() { | |
M5.update(); | |
debouncerA.update(); | |
debouncerB.update(); | |
debouncerFn.update(); | |
// 無操作タイムアウトでモードを戻す | |
if ((millis() - last_action > MODE_TIMEOUT) && (mode != MODE_INIT)) { | |
mode = MODE_INIT; | |
changeModeApply(); | |
} | |
// LED | |
bool in_a = debouncerA.read(); | |
bool in_b = debouncerB.read(); | |
bool in_fn = debouncerFn.read(); | |
if (!in_a || !in_b || !in_fn) { | |
// 押下: 消灯 | |
neopixelWrite(LED, 0, 0, 0); | |
} else { | |
bool c = bleKeyboard.isConnected(); | |
if (c) { | |
//接続済み | |
switch (mode) { | |
case 0: neopixelWrite(LED, 50, 50, 50); break; // 白 | |
case 1: | |
neopixelWrite(LED, 0, 50, 0); | |
; | |
break; // 青 | |
case 2: | |
neopixelWrite(LED, 0, 0, 50); | |
; | |
break; // 緑 | |
case 3: | |
neopixelWrite(LED, 50, 50, 0); | |
; | |
break; // 黄 | |
default: break; // 異常避け | |
} | |
} else { | |
// 切断: 白点滅 | |
if (millis() % 1000 > 500) { | |
neopixelWrite(LED, 50, 50, 50); | |
} else { | |
neopixelWrite(LED, 0, 0, 0); | |
} | |
} | |
} | |
delay(10); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment