Skip to content

Instantly share code, notes, and snippets.

@anroots
Created January 27, 2013 09:29
Show Gist options
  • Save anroots/4647548 to your computer and use it in GitHub Desktop.
Save anroots/4647548 to your computer and use it in GitHub Desktop.
Python script for Raspberry Pi, Adafruit 7-segment 4-digit LCD backpack and a LED. Uses an USB mic to measure and display sound level.
#!/usr/bin/python
# Sound level indicator on a 7-segment 4-digit LCD, for Raspberry Pi
# Uses a USB mic to measure sound level
#
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_LEDBackpack/Adafruit_7Segment.py
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_LEDBackpack/Adafruit_LEDBackpack.py
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_I2C/Adafruit_I2C.py
#
# Author Ando Roots <ando@sqroot.eu> 2013
# http://sqroot.eu
import alsaaudio, time, audioop, datetime
from Adafruit_7Segment import SevenSegment
import RPi.GPIO as GPIO
class SoundMonitor:
# Red LED address
RED_LED = 23
# Light red LED when measured sound value exceeds the preset limit
WARNING_THRESHOLD = 800
# Tolerance as a percentage (0.5 is 50%)
# LCD output is changed when the measured value exceeds this tolerance
TOLERANCE = 0.15
# Minimum time in seconds between each LCD value change
MAX_CHANGE_FREQ = 0.5
# 7-segment display (run i2cdetect -y 1 to get the addr)
segment = SevenSegment(address=0x70)
# Alsaaudio instance
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,alsaaudio.PCM_NORMAL, 'sysdefault:CARD=Set')
def __init__(self):
# LED
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.RED_LED, GPIO.OUT)
# Set attributes: Mono, 8000 Hz, 16 bit little endian samples
self.inp.setchannels(1)
self.inp.setrate(8000)
self.inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
self.inp.setperiodsize(160)
# Write a 4-digit number to the LCD
def write_number(self, value):
value = int(value)
if value > 9999:
print "Value %s is out of bounds, setting to 9999" % value
value = 9999
value = str(value).zfill(4)
self.segment.writeDigit(0, int(value[0]))
self.segment.writeDigit(1, int(value[1]))
self.segment.writeDigit(3, int(value[2]))
self.segment.writeDigit(4, int(value[3]))
return self
# Get the current sound level
def get_sound_level(self):
# Read data from device
l,data = self.inp.read()
if not l:
return 1
# Return the maximum of the absolute value of all samples in a fragment.
value = float(audioop.max(data, 2))
if value < 1:
value = 1.0
return value
# Main loop
def run(self):
print "Running the program - press Ctrl + C to exit."
time.sleep(2)
saved_value = 1
last_changed = time.time()
while True:
value = self.get_sound_level()
red_state = value > self.WARNING_THRESHOLD
print "Level: %s; Red: %s;" % (value, red_state)
if abs((saved_value - value) / value) > self.TOLERANCE:
if time.time() > last_changed + self.MAX_CHANGE_FREQ:
self.write_number(value) # Change LCD output
GPIO.output(self.RED_LED, red_state) # Light red LED?
saved_value = value
last_changed = time.time()
time.sleep(.001)
# Cleanup on exit
def __del__(self):
self.segment.disp.clear()
GPIO.cleanup()
# Run the program
monitor = SoundMonitor().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment