Skip to content

Instantly share code, notes, and snippets.

@HaxNobody
Last active July 19, 2022 02:23
Show Gist options
  • Save HaxNobody/7bde369d7a41348b8b91c1a4f358ea4a to your computer and use it in GitHub Desktop.
Save HaxNobody/7bde369d7a41348b8b91c1a4f358ea4a to your computer and use it in GitHub Desktop.
Physical mute button for Zoom using an ATTiny85/Digispark and the Micronucleus bootloader to allow programming with the Arduino IDE
/*
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
}
@kingfisher1234
Copy link

I'm trying to get the code to work on a Mac does anyone have example KeyStrokes?

@kingfisher1234
Copy link

Here is the logic for Mute on a Mac
DigiKeyboard.sendKeyStroke(KEY_A, MOD_GUI_LEFT | MOD_CMD_LEFT | MOD_SHIFT_LEFT); // Toggle mute on or off in Zoom

And here is the logic for ending a meeting

  DigiKeyboard.sendKeyStroke(0); // Clear any current key presses
  DigiKeyboard.delay(50);
  DigiKeyboard.sendKeyStroke(KEY_W, MOD_CMD_LEFT);
  DigiKeyboard.delay(500);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  DigiKeyboard.delay(500);

I had to add "#define MOD_CMD_LEFT 0x00000008" for the comand key

And unlike on a PC, there doesn't appear to be a zooms shortcut to bring the window into focus

@kingfisher1234
Copy link

Here is a Mac Version if anyone is looking for it:
https://gist.github.com/kingfisher1234/caf351bed786f9050e1fa28c3352ded9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment