|
/* |
|
Thanks to Elliotmade for the inspiration on this project |
|
https://elliotmade.com/2020/04/23/physical-mute-button-for-zoom-meetings/ |
|
|
|
Refactored by HaxNobody to extend functionalty and add comments for my own understanding |
|
|
|
This program will send USB HID keyboard presses to bring the Zoom window into |
|
the foreground and activate microphone and video functions. |
|
* A momentary press on button 1 will toggle mute on or off. |
|
* Press and hold button 1 to activate PTT (Push-to-Talk) functionality. |
|
* A momentary press on button 2 will toggle video on or off. |
|
Unfortunately, exiting a meeting with only key presses is no longer possible in Zoom, so I have removed that feature. |
|
*/ |
|
|
|
#include <DigiKeyboard.h> // Library for sending keystrokes as an HID device over USB |
|
#include <OneButton.h> // Library for button input functions |
|
#include <FastLED.h> // Library for controlling LEDs with high speed math |
|
|
|
#define LedBreatheSpeed 12 // Speed of LED breathing animation in BPM |
|
#define LedMinBrightness 5 // Minimum brightness value |
|
|
|
OneButton button1( |
|
0, // Pin Number |
|
true, // Input is active LOW |
|
true // Enable internal pull-up resistor |
|
); |
|
OneButton button2( |
|
2, // Pin Number |
|
true, // Input is active LOW |
|
true // Enable internal pull-up resistor |
|
); |
|
|
|
void setup() { |
|
button1.attachClick(button1click); // Set up button 1 for Zoom mute toggle function |
|
button1.attachLongPressStart(button1longPressStart); // Set up button 1 for Zoom temporary unmute function |
|
button1.attachLongPressStop(button1longPressStop); // Set up button 1 for Zoom temporary unmute release function |
|
button2.attachClick(button2click); // Set up button 2 for Zoom video toggle function |
|
button1.setPressTicks(300); // Reduce long-press delay for button 1 to make temporary unmute more responsive |
|
|
|
DigiKeyboard.delay(50); // Delay before entering loop |
|
pinMode(1, OUTPUT); // Initialize LED pin |
|
} |
|
|
|
void loop() { |
|
DigiKeyboard.update(); // Maintain USB communication |
|
button1.tick(); // Check status of buttons in a continuous loop |
|
button2.tick(); |
|
analogWrite(1, beatsin8(LedBreatheSpeed, LedMinBrightness)); // Make LED "breathe" |
|
} |
|
|
|
// This function will be called when button 1 is pressed for more than 50ms and less than 300ms. |
|
void button1click() { |
|
DigiKeyboard.sendKeyStroke(0); // Clear any current key presses |
|
DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT); // Bring Zoom into foreground |
|
DigiKeyboard.delay(50); // Give Zoom a chance to get into the foreground |
|
DigiKeyboard.sendKeyStroke(KEY_A, MOD_ALT_LEFT); // Toggle mute on or off in Zoom |
|
} |
|
|
|
// This function will be called when button 2 is pressed for more than 50ms and less than 300ms. |
|
void button2click() { |
|
DigiKeyboard.sendKeyStroke(0); // Clear any current key presses |
|
DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT); // Bring Zoom into foreground |
|
DigiKeyboard.delay(50); // Give Zoom a chance to get into the foreground |
|
DigiKeyboard.sendKeyStroke(KEY_V, MOD_ALT_LEFT); // Toggle video on or off in Zoom |
|
} |
|
|
|
// This function will be called when button 1 is pressed and held down for more than 300ms. |
|
void button1longPressStart() { |
|
DigiKeyboard.sendKeyStroke(0); // Clear any current key presses |
|
DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT); // Bring Zoom into foreground |
|
DigiKeyboard.delay(50); // Give Zoom a chance to get into the foreground |
|
DigiKeyboard.sendKeyPress(KEY_SPACE); // Press and hold the space key to trigger zoom to temporarily unmute |
|
} |
|
|
|
// This function will be called when button 1 is released after being held down. |
|
void button1longPressStop() { |
|
DigiKeyboard.delay(300); // Delay to prevent cutting off the speaker's last word |
|
DigiKeyboard.sendKeyPress(0); // Release space key to re-mute Zoom after temporary unmute |
|
} |
I found out just now that the FastLED library is broken if you use the latest version. If you aren't using that feature, remove it to save space. Otherwise, use version 3.3.2 instead of the latest 3.3.3.
To change the long press behavior to a toggle function instead of a press-and-hold function, use sendKeyStroke instead of sendKeyPress. Also, adjust the value of setPressTicks to change how long of a delay when holding the button down before it takes action.
I think you could completely remove attachLongPressStop and its associated function since you are sending a one-shot keystroke and not holding a button that needs to be released later.