Build an Audio Detector - LEKULE

Breaking

19 Aug 2015

Build an Audio Detector

Requirements

  • CC3200 Demo board
    • Updated to latest firmware for Energia support, directions here.
  • Energia - Arduino IDE Clone from TI
    • Use in article: v. 0101E00016
  • Electret Microphone
    • Used in article: BOB-09964
      • *This board requires modification to work with CC3200
  • Jumper wires
  • Device capable of running Python with a UDP server
    • Used in this article: Windows 8 PC with Python 2.7

Hardware Setup

Modifying the microphone

Unfortunately the CC3200 can only read voltages up to 1.45V on the ADC pins. Since we'll be powering the microphone from 3.3V, we need to modify the circuit to output a voltage of 1.45/2 = 0.725V when no sound is present. Resistors R2 and R3 in the schematic for a voltage divider that sets the bias point. To change it to 0.725V, we can calculate a new resistor based on the common voltage divider equation. This works out to changing the resistor R3 to 2.82k. The closest 1% value is 2.8k, and the closest 5% value is 3k. I would recommend using a 2.8k resistor if you can find one. The value isn't extremely critical if you don't have many resistors lying around, you just may introduce distortion in the signal if the bias is too far low or high in voltage.

Connecting the wires

CC3200 pinout here.
 CC3200  BOB-09964
 Pin 1 -- 3v3 Power  VCC
 Pin 22 -- GND  GND
 Pin 23 -- ADC_CH0  AVD

Testing the connection

The code below implements sampling the input from the microphone. It calculates a moving average of the RMS value from the microphone. It then prints a bar graph to the serial terminal indicating how much audio energy there is.
  1. Download the following zip file and unpack to a directory.
  2. Open the sketch in Energia.
    1. File>Open>audio_RMS_print.ino
    2. Make sure to select the correct board in Tools>Board>Launchpad w/ CC3200 80MHz.
  3. Program the board.
    1. File>Upload or the arrow button
  4. You should see the bar graph in a terminal move depending on the audio. *Note: The built-in terminal doesn't handle the '/r' to display the graph. I recommend Tera Term instead.

 

Transmitting over WiFi

The following code adds WiFi capability to the audio detector.
  1. Download the following zip file and unpack to a directory.
  2. Open the sketch in Energia.
    1. File>Open>audio_RMS_print.ino
    2. Make sure to select the correct board in Tools>Board>Launchpad w/ CC3200 80MHz.
  3. Modify the network constants below 
  4. Program the board.
  5. File>Upload or the arrow button.
  6. The CC3200 will now transmit over UDP every time a new average is measured.

                    /*network settings*/
char ssid[] = "yourSSID";                     //SSID of network
char password[] = "yourpassword";             //password for wireless network
char UDP_server_IP[] = "yourserverpassword";  //IP address of UDP server to send data to
int UDP_server_port = 9999;
                  

 

Setting up a Python UDP Server

The following code starts a UDP server at the specified IP address and port. It expects two bytes sent with every UDP packet. It converts the two bytes to an int16 number and converts it to a bar graph displayed on the console. Executing this script while the CC3200 is running the code above will display a bar graph when audio is playing near the microphone.


                    import SocketServer
import struct
import sys

class MyUDPHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data = self.request[0].strip()
        socket = self.request[1]
        try:
            moving_average = struct.unpack('h',data)[0]
            bar_chart = moving_average
            print "\r                         \r",
            while bar_chart > 0:
                sys.stdout.write('#')
                bar_chart = bar_chart - 200
        except:
            pass

if __name__ == "__main__":
    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
    server.serve_forever()
                  

 

Adding email notifications

  1. Make sure you have a Gmail account that allows "Less secure apps" to communicate.
  2. Adjust the "EMAIL_THRESHOLD" to the audio energy you want to send an email at.
  3. Add your username and password to the variables at the top of the file.
  4. Execute the script. You should see the following when the threshold is reached. If you want to keep sending emails forever, remove the variable "already_sent_once".
  5. Email in the inbox:

                    import SocketServer
import struct
import sys
import smtplib
from email.mime.text import MIMEText

HOST, PORT = "yourip", 9999
EMAIL_THRESHOLD = 600
email_address = "youremail" 
password = "yourpass"
already_sent_once = 0
moving_average = 0
class MyUDPHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        global already_sent_once,moving_average
        data = self.request[0].strip()
        socket = self.request[1]
        try:
            moving_average = struct.unpack('h',data)[0]
            bar_chart = moving_average
            print "\r                         \r",
            while bar_chart > 0:
                sys.stdout.write('#')
                bar_chart = bar_chart - 200
        except:
            pass
        if moving_average > EMAIL_THRESHOLD and already_sent_once == 0:
            already_sent_once = 1
            print "Sending email, audio above threshold: " + str(moving_average)
            msg = MIMEText("Audio is at level: " + str(moving_average))
            msg['Subject'] = 'Audio above threshold'
            msg['From'] = email_address
            msg['To'] = email_address
            s = smtplib.SMTP('smtp.gmail.com:587')
            s.ehlo()
            s.starttls()
            s.login(email_address,password)
            s.sendmail(email_address, email_address, msg.as_string())
            s.quit()

if __name__ == "__main__":
    server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
    server.serve_forever()

VIDEO

                  

No comments: