/*
* Noise Announcer for Arduino
* Justin Streufert - monitron@gmail.com
* http://monitron.vox.com/
*
* Uses an amplified microphone to detect loud noises. Sets off a light and
* sound alarm, as well as sending a message over serial that can be used as
* a remote trigger.
* Goes into a "cool-down" state after an alarm sounds, so as to mitigate annoyance.
*
* TODO possible improvements:
* - Configurable remotely through XBee
* - Better noise discrimination?
* - Serial Heartbeat
*
* BOM:
* Radio Shack 273-059 Piezo Buzzer on pin 5
* Radio Shack 276-028 "Full Color" LED on pins 9, 10 & 11, connected to +5V through a resistor
* Radio Shack 270-092 Electret microphone on pin 2
* connected through a LM386 X200 amplifier circuit as seen here:
* http://www.josepino.com/circuits/?mini_amplifier_lm386.jpc
* Optional XBee and XBee Shield
*/
// Pins
const int micPin = 2; // Analog Input pin for amplified microphone signal
const int buzzerPin = 5; // Digital Output pin for piezo buzzer
const int redPin = 9; // Digital Output pin for red LED (sink; LOW = on)
const int greenPin = 10; // Digital Output pin for green LED (sink; LOW = on)
const int bluePin = 11; // Digital Output pin for blue LED (sink; LOW = on)
// Configuration Constants
const int micCenter = 490; // The bias of the LM386 amplifier. Approximate, empirically defined.
const int numToAverage = 300; // The number of samples to take before taking an average.
const int loudNoiseThreshold = 240; // How loud do things need to get before we complain?
const int buzzDuration = 6000; // The number of cycles of buzzing
const int buzzPeriod = 185; // Determines the frequency of the buzzing (us)
const int coolDuration = 60000; // Minimum time between alarms (ms)
// Working Variables
int numCollected = 0; // Number of samples collected so far
long sampleTotal = 0; // The total value of the samples collected so far
void setup() {
// Declare LED and buzzer pins as outputs
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
// Set initial state of LED (green)
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(redPin, HIGH);
// Start serial connection to XBee or PC
Serial.begin(9600);
}
void loop() {
int averaged;
int i;
int val;
numCollected++;
val = abs(analogRead(micPin) - micCenter); // read & normalize value from mic
sampleTotal += val;
if (numCollected == numToAverage) { // Ready to check for loudness?
averaged = sampleTotal / numToAverage;
// Enable for debugging:
// Serial.print("Avg: ");
// Serial.println(averaged);
if(averaged > loudNoiseThreshold) {
Serial.println("LOUD!!!"); // Tell the world :)
digitalWrite(greenPin, HIGH); // Switch to the red light
digitalWrite(redPin, LOW);
for(i=1;i!=buzzDuration;i++) { // Make a noise through the piezo buzzer by toggling it on and off
delayMicroseconds(buzzPeriod);
digitalWrite(buzzerPin, HIGH);
delayMicroseconds(buzzPeriod);
digitalWrite(buzzerPin, LOW);
}
digitalWrite(redPin, HIGH); // Go to blue
digitalWrite(bluePin, LOW);
delay(coolDuration);
digitalWrite(greenPin, LOW); // Back to green
digitalWrite(bluePin, HIGH);
}
numCollected = 0; // Reset to collect new samples
sampleTotal = 0;
}
}