Introduction: Shattering Wine Glasses With Sound!

About: Mechatronics Engineer and tinkerer. Making Robots is my main hobby. Check out my website for more projects: https://tylergragg.com/projects/

Hello and welcome!

Here is a full demo of the project!

The speaker tops out at about a whopping 130 dB at the edge of its tube, so hearing protection is DEFINITELY REQUIRED!

The idea for this project is as follows:

I want to be able to record a resonant frequency of a wine glass using a small microphone. I then want to re-produce the same frequency at a much higher volume to cause the glass to break. I also want to be able to fine-tune the frequency in case the microphone was slightly off. And lastly, I want it all to be about the size of a large flashlight.

Button Control and Operation:

- The top left dial is a rotary encoder. It can spin infinitely and will pick up on which direction it is being turned. This allows the output frequency to be adjusted in either direction. The rotary encoder also has a push button inside allowing you to 'click' it in. I have this to reset the output frequency to whatever you originally 'captured' the frequency as. Basically it just takes off your tuning.

- The top right is an ON/OFF Switch. It turns power to the whole circuit on or off.

- The bottom left is the microphone capturing button. It alternates between recording frequencies to be ignored and recording frequencies to reproduce. This way you can remove the "Ambient frequencies" of the room you're in.

- The bottom right is the speaker output button. While pressed the speaker starts outputting the frequency it previously captured.

If you are interested in breaking glass also, follow this Instructable and maybe you'll learn something neat along the way. Just a heads-up, this project includes a lot of soldering and 3D printing, so it might be a bit difficult. At the same time, you're already pretty amazing at making things (You're on Instrucables, aren't you?).

So, prepare yourself and...

Let's Make Robots!

Step 1: Materials, Tools, and Equipment

Because this project does not need to be done exactly as I did it, I will include a 'required' list and an 'optional' list of materials, depending on how much you want to build! The optional part will include 3D printing a housing for the speaker and electronics.

REQUIRED:

Materials:

Tools / Equipment:

  • HEARING PROTECTION - Not kidding, this guy tops out at about 130 dB, which can cause instant damage
  • Soldering Iron
  • Solder
  • Wire Strippers
  • Sand Paper
  • Hot Glue Gun

NOT-REQUIRED:

The following is only required if you too want to make the full 3D printed housing for your project

Materials:

  • Lots of ABS Filament - I didn't measure how much I used, but there are two ~24hr prints and one ~8hr print
  • Assortment of M3 screws and bolts - Technically you can probably use any size if you want to drill the holes for it. But I made the design with M3 screws in mind.

Tools / Equipment:

  • 3D Printer - I used the Ultimaker 2
  • A Dremel is useful also if the printer leaves some residue on your part.

Step 2: Build Test Circuit

Next we're going to want to build the circuit using jumper wires and breadboard most likely!

Technically this step is not required if you want to go directly to soldering onto an Arduino Nano, but I would highly recommend that you do this anyways. It's a good way to test all your parts and make sure that you know where everything goes before you stuff it all into a small enclosed space.

In the first picture posted, I have not hooked up the amplifier board or the power switch, I just connected pins 9 and 10 to a mini test speaker I had, but I encourage you to put EVERYTHING together before moving on.

Onto the Circuit:

To power the arduino, plug it into your computer using the USB cable. If anything is not clear, I'm going to go into detail about each part individually below.

Let's start with the power supply:

The positive end of the battery goes into the switch. This allows us to turn on and off our circuit without having to fully unplug anything or do anything too crazy to restart the circuit if needed. The actual switch I used only had two terminals, and the switch either connected them or left them open.

The positive end then goes from the switch to the amplifier board.

The negative end of the battery does NOT need to go through the switch. It can go directly to the Power- end of the Amp.

Next, the Amplifier Board:

The amplifier board has four sets of pins, each set having two througholes. I'm not using the 'Mute' feature of this board, so feel free to not worry about that. I already described above that the Power + and Power - should be getting direct 22.2v from the battery. For the output, you should hook this directly up to the leads on the compression driver. It does not matter directly which lead goes to which pin, but sometimes switching them around gets you better sound quality. Lastly, the Input + and Input - go to pins 10 and 9 on the Arduino, again, the order does not necessarily matter.

Microphone:

The microphone is super simple. Vcc gets 5v from the arduino, GND goes to GND on Arduino, and OUT goes to the A0 pin on the Arduino.

Buttons:

If you've ever used buttons on an Arduino before, you may be slightly confused to see the buttons connected without a resistor. This is because I have them setup to use the internal pullup resistors that are inside the Arduino. This basically makes them always read as HIGH until you push the button, then they read as LOW. It just makes wiring simpler and easier. If you want more information, check out this instructable:

https://www.instructables.com/id/Arduino-Button-wi...

The Button that is reading from the microphone will be connected to pin 6 and the button that actually tells the speaker to start producing sound is on pin 5. The other pins on both buttons are wired to GND.

Rotary Encoder:

The rotary encoder I used also included a button embedded inside of it. So, you can actually click in the dial, and it can be read as a button press.

The wiring for this goes as follows: GND to Arduino GND, + to Arduino +5v, SW to pin 4, DT to pin 3, CLK to pin 2

If you want more information on how rotary encoders work, check out this link:

https://howtomechatronics.com/tutorials/arduino/ro...

And that's it for the circuit!

Step 3: Test Code

Now it's time to upload some code to your Arduino!

You can download my repo on GitHub that has all the files you'll need: https://github.com/Tdoe4321/GlassGun

Or, I've uploaded just the GlassGun.ino file to the bottom of this step!

Now, let's talk a little bit about what all is going on.
Firstly, I am using a couple different Libraries in this project that you NEED TO DOWNLOAD. Libraries are a way to share modular code with someone, allowing them an easy way to integrate something into their project.

I am using all of these:

Each of them have instructions on how to install into your Arduino Directory. If you need more information on Arduino Libraries, check out this link:

https://www.arduino.cc/en/Guide/Libraries

This flag allows the user to easily turn off or on the screen printouts to the Serial line:

//Debug Flag 
boolean printDebug = true;

This initializes the variables that are used to capture the frequency and return the one that appeared the most:

//Frequency capture<br>LinkedList freqData;
LinkedList NOT_DATA;
int modeHold;
int modeCount = 1;
int modeSubCount = 1;
boolean gotData = false;
boolean badData = true;

This sets up the values for outputting the to the speaker. freqModifier is what we add or subtract to the output based on the rotary encoder tuning. modeValue is what holds the recording from the microphone. The final output is just modeValue + freqModifier.

//Frequency emitting
int freqModifier = 0;
int modeValue;

Sets up the Rotary Encoder using the library:

//Tuning by way of rotary encoder
int val;
#define encoderButtonPin 4
#define encoderPinA 2
#define encoderPinB 3
Rotary r = Rotary(encoderPinA,encoderPinB);

Defines the pins the buttons are attached to:

//Buttons to trigger microphone and speaker
#define speakerButton 5
#define microphoneButton 6

This value tells if the frequency recorded is exceptionally high or low:

//clipping indicator variables
boolean clipping = 0;

Used in the recording of the frequency:

//data storage variables
byte newData = 0;
byte prevData = 0;

Used in the actual calculating of the frequency number based on oscillations:

//freq variables
unsigned int timer = 0;//counts period of wave
unsigned int period;
int frequency;

Now, onto the actual body of the code:

Here, we setup the Microphone and Speaker buttons to not use a resistor when pressing the button as previously described in the Test Circuit step (More Info: https://www.instructables.com/id/Arduino-Button-wi... ) I also call the resetMicInterupt, which does some very low-level setting of pins to be listening to the A0 pin at very distinct time periods. I used this instructable to guide me through how to get frequency from these values:

https://www.instructables.com/id/Arduino-Frequency...

void setup(){<br>  pinMode(13,OUTPUT); //led indicator pin
  pinMode(microphoneButton, INPUT_PULLUP);  //Microphone Pin
  pinMode(speakerButton, INPUT_PULLUP);
  
  if(printDebug){
    Serial.begin(9600);
  }
  
  resetMicInterupt();
}

void resetMicInterupt(){
  cli();//diable interrupts
  
  //set up continuous sampling of analog pin 0
  
  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
  
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
  
  sei();//enable interrupts
}

ISR(ADC_vect) {//when new ADC value ready  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
    period = timer;//get period
    timer = 0;//reset timer
  }
  
  
  if (newData == 0 || newData == 1023){//if clipping
    PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
    clipping = 1;//currently clipping
  }
  
  timer++;//increment timer at rate of 38.5kHz
}

I think that most of the code here is simple enough, and should be pretty readable, but I'll highlight some of the more confusing areas:

This part comes mostly from the Rotary library. All that it's saying is that if you have moved clockwise, increment the freqModifer up by one, if you didn't go up, then you must have gone down, so take freqModifier down by one.

unsigned char result = r.process(); // See if the rotary encoder has moved
  if(result){
    firstHold = true;
    if(result == DIR_CW) freqModifier++; // If we moved clockwise, increase, otherwise, decrease
    else freqModifier--;
    
    if(freqModifier < -50) freqModifier = -50; // Clip the value from -50 to 50
    else if(freqModifier > 50) freqModifier = 50;
    if(printDebug){
      Serial.print("FreqMod: ");
      Serial.println(freqModifier);
    }
  }

This next section is where I run my algorithm on the captured frequency data to try and get the most consistant frequency reading from the wine glass. Firstly, I do a short press on the microphone button. This short button press captures "Bad Data" from the microphone. This equates to values that we want to ignore. We hold onto these, so that when we get "Good Data" we can loop through it and take out all the bad ones.

void getMode() {<br>  boolean doAdd = true

  // The first button press should be short to get "bad values" or values that we know are bad
  // This alternates between the recording of "bad data" and "good data"
  if (badData) { 
    if (printDebug) Serial.println("Bad Data: ");
    for (int j = 0; j < freqData.size(); j++) {
      for (int i = 0; i < NOT_DATA.size(); i++) {
        if (freqData.get(j) == NOT_DATA.get(i)) {
          doAdd = false;
          break;
        }
      }
      if (doAdd) {
        NOT_DATA.add(freqData.get(j));
      }
      doAdd = true;
    }

    if (printDebug) {
      Serial.println("-----");
      for (int i = 0; i < NOT_DATA.size(); i++) {
        Serial.println(NOT_DATA.get(i));
      }
      Serial.println("-------");
    }
  }

Here is us looping through the "Good Data" and taking out all the ones that match the "Bad Data from before"

Whenever we remove one element from the list, we have to go back a step in our outter loop (j--) because otherwise we will skip values.

  else {
    if (printDebug) Serial.println("Not Bad Data: ");
    for (int j = 0; j < freqData.size(); j++) {
      for (int i = 0; i < NOT_DATA.size(); i++) {
        if (freqData.get(j) == NOT_DATA.get(i)) {
          if (printDebug) {
            Serial.print("Removed: ");
            Serial.println(freqData.get(j));
          }
          freqData.remove(j);
          j--;
          break;
        }
      }
    }

  freqData.sort(minToMax);

  modeHold = freqData.get(0);
  modeValue = modeHold;

    for (int i = 0; i < freqData.size(); i++) {
      if (freqData.get(i) == modeHold) {
        ++modeCount;
      }
      else {
        if (modeCount > modeSubCount) {
          modeSubCount = modeCount;
          modeValue = modeHold;
        }
        modeCount = 1;
        modeHold = freqData.get(i);
      }
    } 


    modeCount = 1;
    modeSubCount = 1;

    if (printDebug) {
      Serial.println("--------");
      Serial.println(modeValue);
      Serial.println("---------");
    }
    NOT_DATA.clear();
  }
  if (badData) badData = false;
  else badData = true;
  freqData.clear();
}

Step 4: Tune Your Microphone

This was probably one of the hardest steps for me, because I was doing it in conjunction with editing the code to produce the correct output frequency.

Because the Arduino can't read negative voltages (like sound waves), the circuit built into the microphone converts everything to a positive voltage. Instead of a few millivolts positive and a few millivolts negative, the circuit tries to change that to a positive 5v and 0v. However, it can't really know how loud your source audio is. To fix this, they add a tiny potentiometer (screw) to the circuit.

This allows you to 'tune' your microphone to the audio level of wine glasses.

So, how do you actually achieve this?

Well, you can hook up your Arduino to your computer via the USB cable, the open up the serial monitor by clicking on the icon on the top right of the Arduino Editor.

Set the baud rate to 9600.

Then when you upload your code to the Arduino, you should see all the "printDebug" messages come up in that new window.

To actually get your microphone to be tuned correctly, I would recommend getting an app on your phone that reads in frequencies (Like this one) and actually find out what the correct frequency of your glass is. Ting the glass with the app open, find the correct frequency, then start to tune your microphone until you get fairly consistent results.

So, the process is:

  1. Ting the glass with the spectrometer app open and see what the true resonant frequency is
  2. Record the 'Bad Data' by pressing the wired up microphone button on your circuit quickly
  3. Hold the microphone button down on your circuit with the actual microphone close to the glass and ting the glass with a screwdriver or something
  4. Look at the output on the serial monitor and see if it is close to the true frequency value
  5. Adjust the potentiometer screw on the microphone slightly, and repeat

You can also just run the 'mic_test' script, which will constantly run the microphone, outputting it to the screen. If you do it this way, you will have to turn the screw potentiometer while the code is running to see where the best spot it for it.

Step 5: Break Some Glass!

It's time to break the old glass!

Firstly, MAKE SURE YOU ARE WEARING EAR PROTECTION!

There's an art to getting everything to fall into place right to get the glass to break.

  1. You need to sand the rim of the wine glass
  2. You need to get the frequency right
  3. You need to get the angle right
  4. you need to make sure your wine glass isn't losing precious vibrational energy into shaking

So, the best way I found to do this is:

Firstly, like I said, sand the rim of the wine glass. If you don't do this, the glass has no starting fracture point and will never be able to make a crack. A light sanding is all that's required, just enough for a few micro-abrasions.

Make sure that your frequency is right by putting something like a straw or zip tie into the glass after you have recorded the frequency. This allows you to see when the frequency causes the item to bounce and vibrate the most.

Secondly, try to point the speaker at the widest part of the glass right before the glass starts to bend back to the neck. This is where it tends to cause the straw or zip tie to bounce a lot, so you should be able to see what part works best.

Lastly, I taped my glass to the table. If the glass has the option to vibrate the whole glass and scoot across the table, it's losing vibration that would otherwise go into making the rim of the glass shake. So, my recommendation is to loosely tape the glass to the table with scotch tape. If you tape it too much, it won't be able to vibrate at all!

Spend some time playing with it to try and get the levels just right, and make sure you record it so you can show all your friends!

Step 6: (Optional) Solder

So, you've decided to make the whole thing have you? Well, good for you! I certainly enjoyed doing it!

Well, first things first. The circuit is basically the same, there are just some subtle differences.

  1. You will be soldering directly onto the leads of the speaker
  2. You will be adding the Bullet connectors to the speaker
  3. You will be adding the BEC to power the Arduino Nano

One quick note, you don't want to solder onto the main power switch until it's inside the case. This is because the switch needs to be fed in from the top, unlike the other parts which can be slotted in from the bottom. If you solder onto the switch before it's in the case, you won't be able to put it in.

The positive end of our battery first goes to the switch, the to the BEC. This steps our voltage down from 22.2v to 5v to provide power to the Arduino. The positive end of the battery also goes to the Power+ end of our Amplifier. This provides 22.2v directly to the Amp.

The BEC lower voltage end goes from + to the +5v on the Arduino, and - to GND on the Arduino.

It is highly recommended that you use some wire insulation on the bullet connectors, so that way they don't touch each other and short the circuit.

Also, you won't be soldering to anything in particular. You kind of just solder into the air, it's a technique that I call "Air Soldering" It's kind of hard to get the hang of in the beginning, but you get used to it after a while.

Once you're done soldering, it's a good idea to take some hot glue and cover any exposed wire or parts. Hot glue makes an excellent insulator that can be applied over most any electronics. It comes off with some effort, which makes it re-formable if you mess up. But definitely try to cover any button legs, pin headers, or other exposed parts, so that way nothing shorts out.

Step 7: (Optional) Print Housing

There are three files to print with this project:

  1. The front part that hold the speaker and microphone
  2. The middle bit that has all the electronics, buttons, and battery
  3. The battery cover

The parts all together are about a 48-hr print on Georgia Tech's Ultimaker 2's. Make sure you print with support, because there are some big overhangs on this print.

All the parts were designed to be a pretty tight fit, so they may require some sanding or a light dremel to get just right. I didn't have any issues on the machines I was using.

Step 8: (Optional) Paint - for Added Coolness

I thought it would be cool to add some paint to the print.

Fell free to do whatever you think looks cool with the colors you have. I had some acrylic paint on me, and that seemed to work well. The tape I used didn't seem to hold out the paint nearly as much as I hoped, so there's some bleed over, but I think it turned out alright.

Step 9: (Optional) Assemble

Now that all the parts are printed, the solder is solid, and the code is working, it's time to put it all together in one place.

I found it was easiest to put the Arduino sideways against the wall, then the amplifier board could sit flat on the bottom.

The push buttons were designed to be a compression fit. So, they should just be able to be forced up into their slots and stay there. However, if your printer doesn't have that kind of tolerance, feel free to get a piece of tape or some hot glue to affix them to their slots.

The rotary encoder has its own screw on it, so you can just tighten it from the top with the nut it provides.

The power switch needs to be slotted in from the top. It might take a bit of forcing to get it in, but it should fit nicely once it's in the slot.

Once those are in place, you should put the microphone in first, then the Speaker. I also found that the microphone didn't need to be screwed in, because the compression of the hole and the speaker being on top of it held it in nicely.

The battery should fit snugly in the back of the tray, but I didn't have any issue getting it to fit in there.

I also found that just putting an M3 screw on both sizes of the battery cover hole on the sides was enough to keep it in place without a nut at all. I was originally planning on getting one really long screw that went all the way through and out the other hole, but I didn't want to find one online, and the nut-less screw seemed to work fine.

Step 10: (Optional) Break Glass Again!

Fell free to bask in the glory of all the shattered glass around you in this moment. Take a breath, you made it. Smell the shards as they fly all around you.

You now have a fully working, hand-held, impeccably designed, glass shattering audio cannon. If someone comes at you with a wine glass, feel free to whip this bad boy out and just shatter that thing right in front of them. Well, truth be told, you'd probably break their ear drums before the glass would shatter, but no matter, either way they are incapacitated.

On a serious note though, thanks for taking the time to build my little project. If you have any feedback or improvements you want me to make, let me know! I'm more than down for listening!

And one last time...

Let's Make Robots!

Audio Contest 2018

Runner Up in the
Audio Contest 2018