Skip to main content

Modified Microphone

I've owned a Blue Yeti microphone for a little over five years, now. It's a pretty decent microphone for video calls, and I really like that it has its own audio interface for (pass-through) earphones, and a dedicated hardware mute feature. I've used it on probably 1500 calls, with only one complaint: the mute button makes noise.

For most of that five years, my colleagues could usually tell when I wanted into the conversation because the mute button has a satisfying ka-chunk tactile feedback that—unfortunately—transfers vibration into the thing to which it is attached, and that thing is a highly-sensitive vibration transducing machine… a microphone!

The ka-chunk noise has bothered me for years. Not so much for the signifier that I'm about to speak, but that I couldn't unmute myself without people expecting me to speak. Plus, it's kind of fundamentally annoying to me that a microphone has a button that makes noise.

So, I set out to fix this. I've been playing with these ESP32 microcontrollers from Espressif. These inexpensive chips (and development boards) are full of features and are way overpowered compared to the first-generation Arduinos I was playing with 15 years ago. They have WiFi and Bluetooth built in, come with enough RAM to do some basic stuff (and off-chip serial-bus-accessible RAM for more intensive work), and are easy to program (both from a software and hardware standpoint).

One of the cool built-in features of the ESP32 is a capacitive touch sensor. There are actually several of these sensors on board, and they're often used to sense touch for emulating buttons… silent buttons. You can see where I'm going with this.

I laid out a test circuit on a breadboard, and wrote a little bit of firmware (including some rudimentary debouncing) using the Arduino framework, then tested:

(This is on a ESP32 WROOM development board that's not ideal for some of my other projects, where I prefer the WROVER for the extra RAM, but is ideal—if not serious overkill—for this project.)

Not bad. But now I had to do the hard part: figure out how the microphone handles that button press. I looked around the Internet a little for someone who'd already done something similar, and I found some teardown videos, but couldn't track down a schematic.

I took the microphone apart, dug into the Yeti's board, and found the button. It was a bit more complicated than I'd imagined, mostly because the button is both illuminated (the built-in and light-piped LED will flash when muted, and will be lit solidly when unmuted), and mode-less (it's a momentary button). With some creative probing with a volt-meter and some less-than-ideal hotwiring of the +5V/GND provided by the USB interface, I tracked the button press down to a single pin on the switch, which was sunk low when the button is pressed. I soldered on a wire to use with my project:

I also soldered on a way-too-big barrel connector to tap into the USB interface's +5V and Ground lines. (Use what you have on-hand, right? Try not to get the connector genders backwards like I did… and also maybe solder better than me.)

My code would need to be modified to simulate this button "press". In addition to the debouncing, I'd have to pretend to press and release the button, and also instead of providing +5 volts to an output pin (the normal way to signal something like this), I'd actually have to sink the 5V to ground. Here's the (Arduino framework) code I ended up with (including some Serial debuggery):

#include <Arduino.h>

#define TOUCH_PIN 4
#define LED_PIN 2
#define EXT_LED_PIN 15

#define PULSE_DELAY 500

unsigned int threshold = 20;

// the last time the output pin was toggled:
unsigned long lastDebounceTime = 0;
// the debounce time
unsigned long debounceDelay = 500;

unsigned long pulseStartTime = 0;
bool toggledLow = false;

void gotTouch() {
  if (millis() < (lastDebounceTime + debounceDelay)) {
    return;
  }
  lastDebounceTime = millis();
  Serial.println("Touched.");

  // pulse the button
  digitalWrite(LED_PIN, LOW);
  digitalWrite(EXT_LED_PIN, LOW);
  Serial.println("(low)");
  pulseStartTime = millis();
  toggledLow = true;

}

void setup() {
  Serial.begin(9600);
  delay(100);
  Serial.println("Started.");
  pinMode(LED_PIN, OUTPUT);
  pinMode(EXT_LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  digitalWrite(EXT_LED_PIN, HIGH);
  touchAttachInterrupt(T0, gotTouch, threshold);
}

void loop() {
  // Touch0, T0, is on GPIO4
  Serial.println(touchRead(T0));  // get value using T0
  Serial.println("");
  delay(100);
  if (toggledLow && (millis() > (pulseStartTime + PULSE_DELAY))) {
    digitalWrite(LED_PIN, HIGH);
    digitalWrite(EXT_LED_PIN, HIGH);
    toggledLow = false;
    Serial.println("(high)");
  }
}

Please at least attempt to refrain from making fun of my weak C++ skills… but this seems to be surprisingly stable code in practice.

Now, I'd need to attach the ESP32 dev board, and reassemble the microphone part-way. The case of the Yeti is cast aluminum (or another softish metal, but I assume aluminum). This means that I could maybe—hopefully—use the case of the the Yeti itself as the touch sensor. I rigged up a sensor wire to loosely connect to the mounting hole (which gets a thumb-screwed bolt, and will, by force, make a good connection to the case), since it's a huge pain (at best) to solder to aluminum:

Then, some bench testing before really putting it back together: it works! (You can see the blinking light in the middle of the Yeti's board go solid and back to blinking when I touch the unassembled-but-connected case.)

Great! Success! I managed to do that mostly in a single evening! I put the microphone back together, including putting the case-mounting bolts back in and… suddenly it no longer worked. I disassembled, hooked up the serial monitor via USB, and… well… it works! Maybe I just pinched a connection or shorted a pin or something. More Kapton tape! Reassembled, and… failed again. So I ran a cable through the volume knob hole and reassembled, and tested it in-situ. Weird. The capacitance numbers are all very low. In fact, the might be always just (very near) 0 plus some occasional noise. What?

After a day or two of head-scratching, and then some measuring to confirm the hypothesis, I realized that when the bolts go into the case, the case gets connected to the chassis, and the chassis is grounded to the board, then through to the USB ground. So the case itself gets grounded. And that's bad for a floating capacitance sensor. Turns out it didn't work after all.

This led to experimentation with some insulating enamel paint for transformers, and me certainly burning through a few too many brain cells with the fumes from said paint. I gave up on isolating the case from ground (which is probably good, anyway, all things considered), and made a little touch pad out of some aluminum ducting tape, some solderable copper tape, and a chunk of cardboard, that I happened to have on hand (back to using what you have here).

Actual successful hack.

As you can see in the video, I also added a little toggle switch to the back of the microphone that could allow me to completely detach the switching line from the microphone, just in case my hack started to fail, and I was on an important call—the stock mute button still works, of course. But, I'm happy to report that it's been nothing but stable for the past few weeks—it didn't even overflow the millis() checks, somehow, which still surprises me—and I use the new ka-chunk-free touch-to-mute-unmute feature of my microphone every day.