A 2-button USB HID microphone controller built on the nullbits Bit-C PRO (ATmega32U4) microcontroller. Each button supports tap-to-toggle and hold-for-push-to-talk (PTT). A mode switch selects between keyboard and gamepad HID output modes. Dual LEDs reflect the active state of each microphone button.
- Dual-mode HID output: Switch between keyboard (Scroll Lock / Pause keys) and gamepad (buttons 8–9) modes
- Tap-to-toggle: Press once to activate a microphone latch that persists until toggled off
- Push-to-talk (PTT): Hold a button to send a signal only while physically held; releases on button release
- LED indicators: Each button has an LED that reflects its active state
- Serial debug output: Status messages at 9600 baud
- MCU: ATmega32U4 (Arduino Leonardo-compatible)
- Board: nullbits Bit-C PRO
| Signal | Pin | Notes |
|---|---|---|
| Button 1 | D2 | Connect to GND; internal pull-up enabled |
| Button 2 | D3 | Connect to GND; internal pull-up enabled |
| LED 1 | D4 | Connect through ~220 Ω resistor to GND |
| LED 2 | D5 | Connect through ~220 Ω resistor to GND |
| Mode switch | D15 | LOW (to GND) = keyboard mode; HIGH/floating = gamepad mode |
- Arduino IDE (latest) or
arduino-cli - Board package: Arduino AVR (built-in)
| Library | Source |
|---|---|
Keyboard |
Built-in (Arduino AVR core) |
HID |
Built-in (Arduino AVR core) |
Gamepad output uses the AVR core's HIDSubDescriptor directly — no third-party joystick library needed.
./compile-upload.sh # Compile and upload
./compile-upload.sh compile # Compile only
./compile-upload.sh upload # Upload onlyThe script:
- Auto-installs
dfu-programmerif missing (apt or dnf) - Compiles with custom USB identifiers (VID
0x1209, PID0x0001) - Uses
dfu-programmerfor flashing: erase → flash → reset - Stores build artifacts in
.build/
- Open MicrophoneController.ino
- Select Tools → Board → Arduino AVR Boards → Arduino Leonardo
- Compile:
Ctrl+R - Upload:
Ctrl+U
| Action | Behavior |
|---|---|
| Tap | Toggle microphone latch state; LED tracks latch |
| Hold (≥50 ms) | Push-to-talk: signal active only while held; clears on release |
Default key assignments:
- Button 1:
Scroll Lock(0xCF) - Button 2:
Pause / Break(0xE1)
| Action | Behavior |
|---|---|
| Tap | Toggle joystick button latch state; LED tracks latch |
| Hold (≥50 ms) | Push-to-talk: joystick button active only while held; clears on release |
Button assignments:
- Button 1: Joystick button 8
- Button 2: Joystick button 9
Keys are hardcoded compile-time constants. Edit MicrophoneController.ino:
uint8_t MIC_KEYS[2] = { KEY_SCROLL_LOCK, KEY_PAUSE };Change to any key from Arduino's Keyboard.h (e.g. KEY_F13, KEY_F14), then recompile and upload.
A web configuration page exists in web/ (jQuery + WebUSB) but WebUSB is not yet implemented in the firmware. Keys can only be changed by editing the source and re-flashing.
All firmware logic is in a single sketch file: MicrophoneController.ino.
| Constant | Default | Purpose |
|---|---|---|
HOLD_MS |
50 |
Milliseconds held before press is treated as PTT |
DEBOUNCE_MS |
10 |
Debounce window (ms) |
MIC_KEYS[2] |
{ KEY_SCROLL_LOCK, KEY_PAUSE } |
Keyboard keys per button |
JOY_BTN[2] |
{ 7, 8 } |
0-indexed joystick button slots |
| Field | Purpose |
|---|---|
pressed |
Current debounced press state |
hold |
True once hold threshold crossed |
latch |
Latched active state (toggled by tap, set/cleared by hold) |
pressStart |
millis() at press start |
lastDebounce |
millis() at last debounce check |
setSignal(idx, active)— press/release key (keyboard) or set joystick bit (gamepad)setMode()— reads mode pin, switches mode if changed, releases all outputshandleButton(idx)— debounce, press/hold/release detection, latch management, LED updategamepadSetButton(index, state)— sets/clears single bit in 32-bit button stategamepadSend()— sends current button state as raw HID report (report ID 3)initVariant()— registers custom 32-button HID descriptor before USB enumeration
The device prints status messages at 9600 baud:
- Mode changes:
Switched to mode: keyboard
View with Arduino IDE Serial Monitor or screen /dev/ttyACM0 9600.
#include errors for Keyboard.h / HID.h are IntelliSense path issues only — code compiles correctly.
Fix: Command palette → Arduino: Board Config → select Leonardo → Arduino: Rebuild IntelliSense Configuration.
- Verify a data cable (not power-only) is used
- Check Tools → Board → Arduino Leonardo
- If needed: disconnect, hold reset, reconnect, upload immediately
- Check mode pin (D15) wiring
- Test with a different application
- Open Serial Monitor to verify mode detection
- Check button wiring with a multimeter (should short to GND when pressed)