Zoom Meetings Physical Mute Button

40K281184

Intro: Zoom Meetings Physical Mute Button

If you use zoom meetings for work or school this button is for you!

Press the button to toggle your mute, or hold the button down to leave the meeting (or end it if you are the host).

One great thing about this is that it works even if your Zoom window isn't active... if it's buried under a bunch of spreadsheets and browser windows - no problem - it brings the window to the front and flips your zoom off or on. Quickly un-muting is key to maintaining the impression that you've been paying attention the whole time!

Even better, this all works while you are sharing your screen, so you don't have to do battle with those pesky on-screen controls.

Check the last step for a two-button version that also will toggle your video on and off

STEP 1: How It Works

This device simply emulates a keyboard when you plug it into your computer. We take advantage of the built-in keyboard shortcuts for Zoom:

CTRL+ALT+SHIFT brings focus to the Zoom window

ALT+A toggles the state of mute, if you mute is on it turns it off, and if it's off it turns it on

ALT+Q leaves a meeting or ends it if you are the host

These are the keyboard shortcuts for the windows version of the app - I don't have a mac to test this on, but I'm sure a similar thing will work there perhaps with a couple tweaks if they keystrokes are different.

A short press of the button sends CTRL+ALT+SHIFT followed by ALT+A, while a long press sends CTRL+ALT+SHIFT followed by ALT+Q then ENTER.

I used a Digispark clone board (attiny85 microcontroller) and built off of an example sketch from the Digikeyboard library. I also used this library to deal with the button. I used the Arduino IDE to flash the code below, you will need to add the Digistump boards with the boards manager first.

//Elliotmade 4/22/2020<br>//https://elliotmade.com/2020/04/23/physical-mute-button-for-zoom-meetings/
//https://www.youtube.com/watch?v=apGbelheIzg
//Used a digispark clone

//this will switch to the zoom application and mute it or exit on long press
//momentary button on pin 0 with pullup resistor

//https://github.com/mathertel/OneButton
//button library
#include "OneButton.h"

int button1pin = 0;

#include "DigiKeyboard.h"

//set up buttons
  OneButton button1(button1pin, true);

void setup() {
  // put your setup code here, to run once:

//set up button functions

  button1.attachClick(click1);
  button1.attachLongPressStart(longPressStart1);

  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.delay(500);
  
}
void loop() {
  // put your main code here, to run repeatedly:
  //monitor buttons
  button1.tick();
}

// This function will be called when the button1 was pressed 1 time (and no 2. button press followed).
void click1() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  
  // Type out this string letter by letter on the computer (assumes US-style
  // keyboard)
  DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
  DigiKeyboard.delay(100);
  DigiKeyboard.sendKeyStroke(KEY_A, MOD_ALT_LEFT);

} // click1

// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  
  // Type out this string letter by letter on the computer (assumes US-style
  // keyboard)
  DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
  DigiKeyboard.delay(50);
  DigiKeyboard.sendKeyStroke(KEY_Q, MOD_ALT_LEFT);
  DigiKeyboard.delay(50);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);

} // longPressStart1

STEP 2: Supplies

The core of this is the Digispark microcontroller board and the button, how you assemble this is really up to you. I used a steel tube as the housing for this project because I wanted something with some gravity so that it stays put on my desk. Here is what it took:

  • Digispark microcontroller board
  • 10k resistor
  • Momentary pushbutton
  • Wire
  • Donor USB cable
  • Rectangular steel tube (2" x 1" x 1.5")
  • 3mm plywood cut out to fit in the end

I think there are plenty of easy ways to assemble this - you could do it on a breadboard, or 3D print a small housing, laser cut a box, drill a hole in your desk, whatever you want!

STEP 3: Wiring

I included a couple of photos above... if anyone needs a diagram let me know and I can draw it, but it is very simple.

  1. 10k resistor between the 5V and P0 pins
  2. Wire between GND and one side of the switch
  3. Wire between P0 and the other side of the switch
That's all there is to it! You could actually plug it into your computer as is, but I wanted this to be on a wire, so I snipped the end off of an old USB cable and soldered it directly to the pads as shown.

STEP 4: Jam It All Together

The photo above doesn't show great detail, but the main idea here is to cram everything into whatever enclosure you decided on. I used hot glue to secure the board and wires inside of the steel tube, then filled in the ends with a small piece of laser cut plywood. The whole thing (except the button) was sprayed with clear coat to prevent rusting, then it was sealed up.

STEP 5: Done!


Plug it in to your computer (actually, maybe do this before sealing it up in case you need to troubleshoot the wiring). No drivers are required, it should act like a keyboard right off the bat. Check the video here to see it in action!

I've got a couple extras available on my Etsy store if is something you can't live without.

STEP 6: Easy Free Alternative

If you like this idea but don't sit at a desk with room for more stuff, or if you are on the go and don't want to carry something around just to mute yourself, here is an alternative:

Check out autohotkey, I have this script below mapped to my F12 key. It gives me the same mute-toggle function and it's free!

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

f12::
                Send {Ctrl Down}{Shift Down}{Alt Down}{Ctrl Up}{Shift Up}{Alt Up}
                Sleep 100
                Send !a
Return

STEP 7: Bonus - Two Buttons!

In response to the question below "Do you think you could add a second button for the camera?": Yes! Code is below, picture above. The circuit for this one adds a second switch and pullup resistor on P2.

//Elliotmade 4/27/2020
//https://elliotmade.com/2020/04/23/physical-mute-button-for-zoom-meetings/
//https://www.youtube.com/watch?v=apGbelheIzg
//Used a digispark clone

//this will switch to the zoom application and mute it or exit on long press
//momentary button on pin 0 with pullup resistor
//momentary button on pin 0 with pullup resistor

//https://github.com/mathertel/OneButton
//button library
#include "OneButton.h"

int button1pin = 2;
int button2pin = 0;

#include "DigiKeyboard.h"

//set up buttons
  OneButton button1(button1pin, true);
  OneButton button2(button2pin, true);

void setup() {
  // put your setup code here, to run once:

  //set up button functions

  button1.attachClick(click1);
  button1.attachLongPressStart(longPressStart1);
  button2.attachClick(click2);

  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.delay(500);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  //monitor buttons
  button1.tick();
  button2.tick();
}

// This function will be called when the button1 was pressed 1 time (and no 2. button press followed).
void click1() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  
  // Type out this string letter by letter on the computer (assumes US-style
  // keyboard)
  DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
  DigiKeyboard.delay(100); 
  DigiKeyboard.sendKeyStroke(KEY_A, MOD_ALT_LEFT);

} // click1

// This function will be called when the button2 was pressed 1 time (and no 2. button press followed).
void click2() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  
  // Type out this string letter by letter on the computer (assumes US-style
  // keyboard)
  DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
  DigiKeyboard.delay(100); 
  DigiKeyboard.sendKeyStroke(KEY_V, MOD_ALT_LEFT);

} // click2

// This function will be called once, when the button1 is pressed for a long time.
void longPressStart1() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  
  // Type out this string letter by letter on the computer (assumes US-style
  // keyboard)
  DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
  DigiKeyboard.delay(50);
  DigiKeyboard.sendKeyStroke(KEY_Q, MOD_ALT_LEFT);
  DigiKeyboard.delay(50);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);

} // longPressStart1

94 Comments

Does it matter what ga wire you use?
Ok about to throw the laptop at the wall! Anyone done it with ir sensors yet?
Love this Ible, nice work, very clever! I could not resist making one for my home office and tried to replicate the industrial look. I also wanted to post my code that works for 2 buttons (toggling audio and video) on Teams on a mac. I did my development and flashed the digispark attiny85 from Window10 as I had issues flashing it from my mac. But my final code is inteneded for Microsoft Teams on a mac. I posted more details in my "I made it" post, but here is my code in case it helps anyone. Note that I'm using the mac native Automator utility to try to bring Teams to the foreground if it is in the background. More on that topic in my "I made it" post. Here is my code.

//Modified by matthewtmead to work on mac with Teams 10/5/2020
//Original code:
//Elliotmade 4/27/2020
//https://elliotmade.com/2020/04/23/physical-mute-button-for-zoom-meetings/
//https://www.youtube.com/watch?v=apGbelheIzg
//Used a digispark clone

//this will ATTEMPT to switch to the Teams application and mute it
//momentary button on pin 0 with pullup resistor
//momentary button on pin 2 with pullup resistor

//https://github.com/mathertel/OneButton
//button library
#include "OneButton.h"

int button1pin = 2;
int button2pin = 0;

#include "DigiKeyboard.h"

//set up buttons
OneButton button1(button1pin, true);
OneButton button2(button2pin, true);

void setup() {
// put your setup code here, to run once:

//set up button functions

button1.attachClick(click1);
button2.attachClick(click2);

DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
}

void loop() {
//monitor buttons
button1.tick();
button2.tick();
}

////////////////////////////
// TOGGLE MUTE
////////////////////////////
void click1() {
// this is generally not necessary but with some older systems it seems to
// prevent missing the first character after a delay:
DigiKeyboard.sendKeyStroke(0);

// Using Automator app, using global keystroke I created custom on my mac, start Teams, or if
// running, bring it to the foreground. Note that some apps "eat" this keystroke and it does not
// make it to Automator to process, so therefore it is ignored. Most apps will pass it along and
// therefore it will work from most apps. This can be changed in automator app.
// Send Shift CMD A
DigiKeyboard.sendKeyStroke(KEY_A, MOD_SHIFT_LEFT | MOD_GUI_LEFT);
DigiKeyboard.delay(500);
// Assuming we are in Teams app, send keystroke to toggle Mute.
// Send CMD Shift M
DigiKeyboard.sendKeyStroke(KEY_M, MOD_GUI_LEFT | MOD_SHIFT_LEFT);
DigiKeyboard.delay(100);

} // click1


////////////////////////////
// TOGGLE VIDEO
////////////////////////////
void click2() {
// this is generally not necessary but with some older systems it seems to
// prevent missing the first character after a delay:
DigiKeyboard.sendKeyStroke(0);

// Using Automator app, using global keystroke I created custom on my mac, start Teams, or if
// running, bring it to the foreground. Note that some apps "eat" this keystroke and it does not
// make it to Automator to process, so therefore it is ignored. Most apps will pass it along and
// therefore it will work from most apps. This can be changed in automator app.
// Send Shift CMD A
DigiKeyboard.sendKeyStroke(KEY_A, MOD_SHIFT_LEFT | MOD_GUI_LEFT);
DigiKeyboard.delay(500);
// Assuming we are in Teams app, send keystroke to toggle Video.
// Send CMD Shift O
DigiKeyboard.sendKeyStroke(KEY_O, MOD_GUI_LEFT | MOD_SHIFT_LEFT);
DigiKeyboard.delay(100);

} // click2
hi thank you fore your work, BTW this one is work with MAC?
thank you in advance.
THX for sharing the hint using Automator!
Nice work. Just wanted to post for others that don't have the skills needed to make (or in my case, Code) this project but still have a need for a dedicated zoom controller I use a Wacom remote. It is expensive at $100 new, but works well and is also wireless.
https://www.amazon.com/Wacom-Express-Remote-Cintiq...
Thanks for all the info.
I want to add 2 push buttons and a volume control knob to a single Attiny85 Mini, Is that even possible?
This is awesome :) Had this same idea and then looked it up to find you've already made it, and in a really pretty case.
Hi
I'm a complete newbie and couldn't find a way to check if I succeed in uploading the code into the attiny85 microcontroller
I don't see any indication that the arduino IDE has identified it but also no error when I press "upload"
Am I missing anything? I'm on win 10
Is there a chance to "build" one with switches instead of
buttons? So there would be an I/O switch for my cam. How do I have to code
that? Cause I can't code that well. Thanks for your answers!
I find that the Zoom keyboard shortcuts provoke a Windows "ding", which the equivalent graphical functions don't. This is a problem for us as we're holding multi-mode services at church with a split congregation between church and Zoom. The church sound system (microphones and speakers) are effectively the Zoom mic and speaker, so that church is just another Zoom participant, and remote participants can interact and take part on an equal basis to those in church.

These Windows dings, then, come across loud and clear across the church, often just as the pianist has started to play, as I press Alt-S to share the hymn words which I've just displayed on the screen. Very annoying.

Has anyone else had this problem, or found a work-around?
Honestly just turn off all the bleeps and dings in windows. If you go thru the list, you can find which one is what zoom triggers and only turn that one off if you want.
Yeah, but in other locations and other contexts they may serve a useful purpose. I don't see why Alt-S needs to produce a ding when the equivalent GUI operation doesn't.
Understandable, but I've never found them to be useful in the context of a computer connected to any kind of PA system or where many people will hear what it is playing. Generally you want only the audio from your program or music and nothing else ever.
It's only connected to a PA system for an hour on a Sunday. Your experience is not ours.
I was having that issue too. But not just when you use the digispark buttons, but if you do the key combination on your regular keyboard. The problem seems to be that Windows reserves the Alt key combinations for system functions. But Zoom decided to use Alt+key combos for its shortcuts by default. The easiest way to remedy this is by checking the "global shortcut" checkbox next to the shortcuts in Zoom Settings > Keyboard Shortcuts. You could also disable the Windows sound completely, as already suggested. Or you can change the keyboard shortcut in Zoom to something else. For example, I built some of these buttons with an Arduino Pro Micro clone and I gave my buttons the values "F13", "F14", and "F15". Since those aren't often used keys (have to hit Shift+F# key to get it), I just assigned those as the Zoom shortcuts I wanted. No ding, no other issues. (Keyboard.h and DigiKeyboard.h are different and I haven't gotten the higher function button working for Digispark yet.)
Hello and THX for sharing!

With the current Zoom version on Windows, ALT & Q does not work to end the meeting (don't know if it was different).

After ALT & Q a pop-up appears with the choice "Leave meeting" or "End meeting", but none of the variants has the focus.

Therefore, another TAB is necessary before the ENTER.

This requires a modification in the "DigiKeyboard.h" - as TAB is not included.
In the line under
#define KEY_ENTER 40
add:
#define KEY_TAB 43

And then in the ZoomButton.ino
use this block:

DigiKeyboard.sendKeyStroke(0, MOD_SHIFT_LEFT | MOD_CONTROL_LEFT | MOD_ALT_LEFT);
DigiKeyboard.delay(50);
DigiKeyboard.sendKeyStroke(KEY_Q, MOD_ALT_LEFT);
DigiKeyboard.delay(50);
DigiKeyboard.sendKeyStroke(KEY_TAB);
DigiKeyboard.delay(50);
DigiKeyboard.sendKeyStroke(KEY_ENTER);

BTW: under MAC the focus is correct, so everything works there as it should.

Cheers
WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOW SOOOO COOL LOVE IT
Could you please show pictures of how to correctly wire up a second button?
More Comments