Firmware that turns an M5Stack Chain DualKey into a Google Meet mute/hang-up controller with true LED state sync — no software installed on the computer. The device is a USB telephony HID peripheral using Meet's native call control.
| Control | Action | LED |
|---|---|---|
| Key 1 | Toggle mic mute | Red = muted, green = live (state driven by Meet — follows host-mutes too) |
| Key 2 | Hold 3 s to leave the meeting (red ramp while holding) | Breathing blue = in a meeting, off = idle |
- Chrome or Chromium (WebHID). Firefox/Safari are not supported by Meet call control.
- USB connection (Meet call control does not support Bluetooth on macOS/Windows/Linux).
- Plug the DualKey in via USB-C (power switch not in the middle position).
- Pair the device — nothing works until you do this once: in a Meet green room or call, open Settings → Audio → scroll to Call control → Connect device → choose MeetMute DualKey (the HID interface itself is labeled "MeetMute Call Control", which may show up instead in some chooser UIs). Chrome remembers the pairing for future meetings.
LEDs dark and buttons doing nothing in a call? That is the unpaired state — Meet never talks to the device until Call control is connected. Do step 2.
source ~/esp/esp-idf/export.sh # ESP-IDF v5.5.1
cd firmware
idf.py set-target esp32s3
idf.py build
Flashing (the firmware owns the USB port, so use ROM download mode):
power switch to middle, hold Key 1, plug in USB, then
idf.py -p /dev/cu.usbmodem* flash, then power-cycle.
Debug logs stream over the built-in USB serial console:
screen /dev/cu.usbmodem* 115200.
- Core behavior is in
firmware/main/app_logic.c, unit-tested on the host:cd test/host && make test. tools/webhid_test.html(open in Chrome) simulates Meet for hardware-in-the-loop testing: shows the device's input reports and lets you set the LED output report.- Background research and architecture decisions:
RESEARCH.md.