A dual-mode HID telephony device using an ESP32-S3 microcontroller that combines USB HID keyboard functionality with multi-client Bluetooth Low Energy for status updates. Designed for seamless integration with video conferencing applications like Google Meet.
Learn more about the design of this project in this blog post: No More ‘Sorry, I Was on Mute’: How I built a DIY hardware solution for Google Meet with ESP32-S3
For developers interested in building their own telephony HID implementations, this project includes a usb_telephony_quick_start.ino file that demonstrates how to use telephony descriptors with HID. This simplified example provides a foundation for creating custom telephony control devices using standard USB HID telephony usage pages.
- Dual-Mode HID Connectivity: USB HID for sending commands and BLE HID for receiving status updates
- Multi-Client Bluetooth: Connect to multiple host devices simultaneously via BLE
- Universal Compatibility: Works with Windows, macOS, Linux, and mobile devices
- Multiple Input Methods: Touch sensor, mechanical buttons, and rotary encoder
- Visual Status Feedback: RGB LED strip indicates mute status with customizable brightness
- Smart State Management: Internal mute state tracking when no Bluetooth devices connected
- Auto-Reconnection: Automatically reconnects to previously paired devices
- Left Button (GPIO 13):
- Single click: Send
Ctrl+Shift+F1keyboard command (Used by Chroome extension to focus on the call tab) - Long press: Send hang up/drop call command
- Single click: Send
- Right Button (GPIO 14): Send
Ctrl+Alt+Hkeyboard command
- Rotation Left: Previous slide (Left Arrow key) / Volume Down
- Rotation Right: Next slide (Right Arrow key) / Volume Up
- Single Click: Toggle between volume control and slides control
- Double-Click: Toggle push-to-talk mode
- Long Press: Activate Bluetooth pairing mode
| MUTED | UNMUTED |
|---|---|
![]() |
![]() |
- PlatformIO development platform
- Arduino framework for ESP32
- Install Visual Studio Code
- Install the PlatformIO extension
- Clone this repository:
git clone <repository-url> cd google-meet-yapper
- Open the project in VS Code with PlatformIO
- Connect your ESP32-S3 device via USB
- Build and upload:
- Press
Ctrl+Shift+Pand run "PlatformIO: Upload" - Or use the PlatformIO toolbar buttons
- Press
- Enter Pairing Mode: Long press the rotary encoder to enable BLE advertising
- On Host Device:
- Go to Bluetooth settings
- Search for new devices
- Look for "ESP32 Mute Control" in the device list
- Select and pair
- Multi-Device Support: Repeat the pairing process for additional host devices
- Mute Control: Use touch sensor in toggle or push-to-talk mode
- Call Control: Use mechanical buttons for various telephony functions
- Brightness Adjustment: Send serial commands to adjust LED brightness
- Volume/Slide Control: Use rotary encoder to adjust volume or navigate slides
- Mode Switching: Single click on rotary encoder to switch between volume and slide control
- Push-to-Talk: Double-click rotary encoder to enable/disable push-to-talk mode
- Calibration: Send serial command to calibrate touch sensor sensitivity
- Status Feedback: LED strip provides visual confirmation of mute status
| Component | Function | Pin/Terminal | ESP32-S3 GPIO | Notes |
|---|---|---|---|---|
| Left Button | Mute Toggle | Terminal 1 | GPIO 13 | Internal pull-up enabled |
| Terminal 2 | GND | |||
| Right Button | Call Drop/Hang Up | Terminal 1 | GPIO 14 | Internal pull-up enabled |
| Terminal 2 | GND | |||
| Rotary Encoder | Channel A (CLK) | CLK | GPIO 5 | Internal pull-up enabled |
| Channel B (DT) | DT | GPIO 6 | Internal pull-up enabled | |
| Push Switch | SW | GPIO 7 | Internal pull-up enabled | |
| LED Strip (APA102) | Data Line | DI | GPIO 11 | SPI Data |
| Clock Line | CI | GPIO 12 | SPI Clock | |
| Touch Sensor | Touch Input | Signal | GPIO 4 | Touch-capable pin |
ESP32BLEHID/
├── src/ # Source code
│ ├── main.cpp # Main application logic
│ ├── communication/ # Bluetooth and HID handlers
│ ├── core/ # Device controller logic
│ └── hardware/ # Hardware abstraction layer
└── include/ # Header files
├── config.h # Configuration constants
├── hidmap.h # HID key mappings
└── logger.h # Logging utilities
- Button Label Icons: For custom button labels and hardware modifications, refer to the Google Docs file with button icons that includes printable icons and labels for the various control functions.
- 3D Models: For 3D printable models of the enclosure and keycaps, check out the thingiverse and OnShape links in the Attributions section below.
platformio.ini- PlatformIO project configurationinclude/config.h- Hardware pin definitions and constantsinclude/hidmap.h- HID key mapping definitions
We welcome contributions to improve the project! Please follow these guidelines:
- Fork the Repository: Create your own fork of the project
- Create a Feature Branch:
git checkout -b feature/your-feature-name
- Make Changes: Implement your improvements
- Test Thoroughly: Ensure your changes work across different scenarios
- Follow Code Style: Maintain consistency with existing code
- Submit Pull Request: Include a clear description of changes
- Use the GitHub Issues tracker
- Include hardware configuration details
- Provide steps to reproduce any bugs
- Include relevant log output when possible
This project is released under the BSD 3-Clause License. See the LICENSE file for details.
For information about third-party dependencies and their licenses, see THIRD_PARTY_LICENSES.md.
This project builds upon inspiration and code from various open-source projects:
- ESP32 BLE HID Implementation: Based on examples from esp-hid-device
- Hardware Mute Button Concepts: Inspired by Gergely Imreh's USB mute button
- 3D Models:
- Macropad by jagoan
- Knurled Knob by jagoan
- Relegendable Keycap by Mc_gee
- Relegendable Keycap Slim Stem
- My own modifications available in OnShape: Yapper for Google Meet Enclosure
- Mold for silicon button included
You can find me on Steam, Discord, LinkedIn and Reddit!
If you like this project, please consider a small donation.
Made with ❤️


