Skip to content

Instantly share code, notes, and snippets.

@gpsnmeajp
Last active May 26, 2024 03:13
Show Gist options
  • Save gpsnmeajp/2637025fa3744e2d371121b17a687cb2 to your computer and use it in GitHub Desktop.
Save gpsnmeajp/2637025fa3744e2d371121b17a687cb2 to your computer and use it in GitHub Desktop.
外部スイッチをATOM Liteを使ってBLE Keyboardに変換するやつ
// 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