Created
June 1, 2016 15:21
-
-
Save kasperkamperman/a947f12e4db48b4f52b6246aedf8a69c to your computer and use it in GitHub Desktop.
read a soundsensor and calibrate the volume.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* script to calibrate (sound level normalizing) a microphone (or other sensor). | |
| used with Sound Sensor v2.0 from flamingoeda.com / electronic bricks | |
| sampling based on Arduino Cookbook recipe "detecting sound" chapter 6.7 | |
| dim_curve idea by Jims <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1174674545> | |
| created 7 september 2011 Kasper Kamperman | |
| http://www.kasperkamperman.com | |
| This example code is in the public domain. | |
| */ | |
| const int ledPin = 10; | |
| const int micPin = 0; | |
| const byte dim_curve[] = { | |
| 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, | |
| 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, | |
| 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, | |
| 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, | |
| 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, | |
| 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, | |
| 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, | |
| 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, | |
| 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, | |
| 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, | |
| 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, | |
| 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, | |
| 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, | |
| 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, | |
| 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, | |
| 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255, | |
| }; | |
| // global variables readSoundLevel | |
| long minimumLevelAverage = 10; | |
| long maximumLevelAverage = 500; | |
| long soundLevel = 0; | |
| void setup() { | |
| Serial.begin(57600); | |
| pinMode(ledPin, OUTPUT); | |
| pinMode(13, OUTPUT); | |
| } | |
| void loop() { | |
| int level = readSoundLevel(0,255, true); // stored in mappedValue | |
| if(level>220) digitalWrite(13, HIGH); | |
| else digitalWrite(13, LOW); | |
| //strange bug with PWM. Causes noise on analogInput ???? | |
| analogWrite(ledPin, dim_curve[level]); | |
| } | |
| int readSoundLevel(int outMin, int outMax, boolean debug) { | |
| // initialisation of variables and constants | |
| const int numberOfSamples = 64; // how many samples will be read each time | |
| const int averagedOver = 4; // how quickly new values affect running average | |
| const int bottomMaximumLevel = 30; // let maximumLevelAverage don't go below this level | |
| const int topMinimumLevel = 10; // let minimumLevelAverage don't go below this level | |
| int sample; // sample the analog input | |
| long sumOfSamples = 0; | |
| // calculate average | |
| for (int i=0; i<numberOfSamples; i++) { | |
| sample = analogRead(micPin); | |
| sumOfSamples += sample; | |
| } | |
| long averageReading = sumOfSamples/numberOfSamples; | |
| // smooth the soundlevel | |
| soundLevel= (( (averagedOver-1) * soundLevel) + averageReading )/averagedOver; | |
| // === calibration of minimum and maximum levels ==== | |
| // kind of sound level normalizing | |
| if(soundLevel>minimumLevelAverage) | |
| { // slowly minimum up when there are high sound levels | |
| //minimumLevelAverage = (soundLevel * 0.005) + (minimumLevelAverage * 0.995); // global var | |
| minimumLevelAverage = ((soundLevel * 1) + (minimumLevelAverage * 511)) / 512; // global var | |
| } | |
| else | |
| { // move minimum fast down when there sound levels are lower | |
| //minimumLevelAverage = (soundLevel * 0.1) + (minimumLevelAverage * 0.9); | |
| minimumLevelAverage = ((soundLevel * 26) + (minimumLevelAverage * 230)) / 256; | |
| } | |
| if(soundLevel>maximumLevelAverage) | |
| { // move maximum up fast when there are high sound levels | |
| //maximumLevelAverage = (soundLevel * 0.2) + (maximumLevelAverage * 0.8); // global var | |
| maximumLevelAverage = ((soundLevel * 26) + (maximumLevelAverage * 230)) / 256; // global var | |
| } | |
| else | |
| { // move maximum down slowly if sound levels are lower | |
| //maximumLevelAverage = (soundLevel * 0.005) + (maximumLevelAverage * 0.995); | |
| maximumLevelAverage = ((soundLevel * 1) + (maximumLevelAverage * 511)) / 512; | |
| } | |
| // ignore noise | |
| //if(soundLevel<(minimumLevelAverage+20)) | |
| //{ soundLevel = 0; | |
| // } | |
| // limit the maximum and minimumAverage | |
| if(maximumLevelAverage<bottomMaximumLevel) maximumLevelAverage = bottomMaximumLevel; | |
| if(minimumLevelAverage<topMinimumLevel) minimumLevelAverage = topMinimumLevel; | |
| // limit the soundLevel between max, min to prevent values outside the outMin/outMax range | |
| soundLevel = constrain(soundLevel, minimumLevelAverage, maximumLevelAverage); | |
| // map the soundValue to the defined range | |
| int mappedValue = map(soundLevel, minimumLevelAverage, maximumLevelAverage, outMin, outMax); | |
| if(debug) | |
| { // Serial Graphing Sketch by Tom Igoe | |
| // http://processing.org/exhibition/features/igoe/ | |
| Serial.print(averageReading, DEC); | |
| Serial.print(","); | |
| Serial.print(soundLevel, DEC); | |
| Serial.print(","); | |
| Serial.print(int(minimumLevelAverage), DEC); | |
| Serial.print(","); | |
| Serial.print(int(maximumLevelAverage), DEC); | |
| Serial.print(","); | |
| Serial.print(map(mappedValue, outMin, outMax, 0, 1023), DEC); | |
| Serial.print(","); | |
| Serial.print(analogRead(micPin), DEC); | |
| Serial.println(); | |
| } | |
| return mappedValue; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment