A tiny BLE HID mouse jiggler firmware for the M5Atom Lite (ESP32-PICO-D4) that prevents your PC from going to sleep or locking the screen — without installing any software on the host or changing OS power settings.
M5Atom Lite を BLE HID マウス として動作させ、定期的に微小なマウス入力を送信することで、PC の自動スリープ/スクリーンロックを回避するファームウェアです。ホストにソフトウェアをインストールせず、OS の電源設定も変更しません。
In some corporate environments installing Caffeine / Amphetamine / PowerToys Awake is blocked by IT policy, yet aggressive screen-lock timeouts disrupt long-running tasks (builds, downloads, presentations). A hardware HID device is invisible to those policies because the OS sees it as just another mouse.
ソフトウェア型のスリープ回避ツール (Caffeine 等) がインストール禁止の環境でも、HID デバイスとして接続するためポリシーの影響を受けにくいのが利点です。
⚠️ Please respect your organization's IT policy. This project is meant for personal devices and authorized use cases. Bypassing security policies on managed machines may violate your employer's rules. 利用にあたっては所属組織の IT ポリシーを必ず確認してください。明示的に禁止されている環境では使用しないでください。
- BLE HID Mouse: pairs once, reconnects automatically after PC sleep/reboot
- 50-second cursor jiggle: moves
+1pxthen−1px— visually imperceptible - One-button control: short press to toggle, long press (3 s) to unpair
- RGB LED status indicator: color-coded device state at a glance
- Pluggable HID driver:
HidMouseDriverabstraction lets you swap BLE for USB HID (e.g. M5AtomS3) without touching the core logic - Unit-tested core: 21 native test cases covering timing, state transitions, and input handling
| Item | Value |
|---|---|
| Board | M5Atom Lite (ESP32-PICO-D4) |
| Power | USB-C (5 V) |
| Button | Built-in (GPIO 39) |
| LED | Built-in WS2812 (GPIO 27) |
| Connection to host | Bluetooth Low Energy (HID profile) |
ESP32-PICO-D4 has no USB OTG, so wired USB HID is not possible on M5Atom Lite. For wired USB HID, see the M5AtomS3 variant note in
docs/M5Atom_HID_KeepAwake_Spec.md§8.
| Color | Pattern | State | 状態 |
|---|---|---|---|
| 🔵 Blue | Blink (1 Hz) | Advertising — waiting for pairing | ペアリング待機中 |
| 🟢 Green | Solid | Active — jiggling every 50 s | 動作中 |
| 🟡 Yellow | Solid | Paused — connected but idle | 一時停止 |
| 🔴 Red | Blink | Error / clearing bond | エラー/ペアリング解除中 |
| ⚫ Off | — | Power off | 電源オフ |
| Action | Effect | 効果 |
|---|---|---|
| Short press | Toggle Active ⇄ Paused | 動作 ON/OFF を切替 |
| Long press (≥ 3 s) | Clear all bonded devices and reboot | ペアリング情報を削除し再起動 |
When resuming from Paused, the jiggle interval restarts from the resume moment — the cursor will not move immediately on button release.
Paused から復帰した直後にカーソルが動かないように、復帰時刻から 50 秒を再カウントします。
1. Install PlatformIO Core
pip install platformiogit clone https://github.com/mtnb/AtomDummyMouse.git
cd AtomDummyMouse
# Flash firmware to a connected M5Atom Lite
pio run -e m5atom_lite -t upload
# View serial logs (optional)
pio device monitor -e m5atom_lite -b 115200- On boot the LED blinks blue — the device is advertising.
- Open Bluetooth settings on your PC and pair with
M5Atom KeepAwake. - The LED turns solid green — the firmware will jiggle the cursor every 50 seconds.
Tune behavior in include/KeepAwakeConfig.h:
struct KeepAwakeConfig {
uint32_t jiggleIntervalMs = 50 * 1000; // 50 s
int jiggleDistancePx = 1; // 1 px
uint32_t jiggleReturnDelayMs = 100; // delay between +dx and -dx
const char* deviceName = "M5Atom KeepAwake";
uint32_t buttonLongPressMs = 3000; // 3 s for unpair
};After changing values, rebuild and reflash:
pio run -e m5atom_lite -t upload.
├── docs/
│ └── M5Atom_HID_KeepAwake_Spec.md # Detailed design spec (Japanese)
├── include/
│ └── KeepAwakeConfig.h # Tunable parameters
├── src/
│ ├── HidMouseDriver.h # Abstract interface (BLE/USB pluggable)
│ ├── BleHidMouseDriver.{h,cpp} # BLE HID implementation (ESP32-BLE-Mouse)
│ ├── KeepAwakeService.{h,cpp} # Tick-based jiggle scheduler & state machine
│ ├── ButtonHandler.{h,cpp} # Short/long press, debounce
│ ├── StatusIndicator.{h,cpp} # State → (color, pattern) pure function
│ └── main.cpp # Arduino entry point
├── test/
│ ├── test_keep_awake_service/ # 11 cases — timing, transitions, reconnect
│ ├── test_button_handler/ # 5 cases — debounce, short/long press
│ └── test_status_indicator/ # 5 cases — LED decision
├── platformio.ini
├── LICENSE
└── README.md
The core logic (service / button / LED decision) is Arduino-independent and runs on your host machine with Unity:
pio test -e nativeAll 21 test cases must pass before flashing.
- Tick-based loop:
KeepAwakeService::tick(nowMs)takes the current time as an argument. Nodelay()in the core, no internal clock — deterministic and fully testable with a fake clock. - Driver abstraction:
HidMouseDriveris a pure-virtual interface. The BLE backend (BleHidMouseDriver) can be swapped for a USB HID backend on M5AtomS3 without touching the service layer. - No singletons: all components are constructed in
main.cppand passed by reference.
See docs/M5Atom_HID_KeepAwake_Spec.md for the full design document.
- Phase 1: BLE HID Mouse PoC
- Phase 2: Tick-based jiggle scheduler
- Phase 3: Button & LED integration
- Phase 4: Unit-tested core (21 cases)
- Phase 5: 24-hour stability test
- Phase 6: M5AtomS3 + USB HID variant (wired, no pairing)
Issues and pull requests are welcome. For larger changes, please open an issue first to discuss the design.
設計上の議論が必要な変更は、先に Issue を立てて方針をすり合わせてください。
MIT © 2026 Nobuhito Muto