Digital Sandbox Arduino Companion

Pages
Contributors: jimblom
Favorited Favorite 3

13. Sound Detecting

\<Pitchman voice> Introducing the fabulously groundbreaking SOUND (Sandbox's Over/Under Nominal Decibels) System! Microphone check 1..2..1..2. With the SOUND you'll always have an adjustable sound level detector handy! \</Pitchman voice>

Background Information

In this experiment we'll use the Sandbox's on-board microphone to measure volume levels and display them on the LEDs. The microphone produces a sound wave, which is just another analog voltage that we can measure. The louder the sound, the higher the amplitude of the wave and the larger the voltage.

Without a lot of complicated math and filters, sound can be a difficult thing to measure and react to. Using the Sandbox for voice recognition isn't quite possible, but it can be programmed pick out high volumes as long as it can sample the microphone input fast enough. We can use the slide potentiometer to set the sensitivity of the display.

Active Parts

alt text

Code Components

You're probably getting used to this now: time for more variable types! This time it's not so much a new variable type as a common storage space for variables.

Arrays

Arrays are a group of variables all housed under a single variable name. Array syntax makes heavy use of the square brackets [ and ]. Here's an example of an array declaration:

language:c
int myArray[3]; // Create an array of 3 int's

You can also initialize your array, using curly brackets:

language:c
// Create and initialize an array containing 5 long variables
long myBigArray[5] = {0, 1000, -44321, 412355234, 42}; 

To reference a single variable in an array we use an index. Here's where the most confusing array-related thing comes into play: arrays are 0-indexed. That means, to access the first value in an array you put a 0 inside those square brackets. To access the last variable, you use an index of length_of_array - 1. For example:

language:c
int example_array[4] = {10, 20, 30, 40}; // Declare an array with four values
...
Serial.print(example_array[0]);  // Prints 10 (first value in array)
Serial.print(example_array[2]);  // Prints 30 (third value in array)
Serial.print(example_array[3]);  // Prints 40 (fourth value in array)
// Illegal: Serial.print(example_array[5]); // No good, there's no such thing.

You can create an array of two variables, or you can create an array of hundreds of variables. The size of the array is determined when you declare it. Your array can be of any type you wish.

for Loops

Time to introduce your first real loop: the for loop. for loops are used to repeat a block of code for a specified set of repetitions. Instead of looping indefinitely, like the loop() function, the for loop can be controlled to repeat once, twice, thrice, or thousands of times. It's up to you.

Here's the anatomy of a for loop:

language:c
for ( [variable declaration] ; [conditional]; [increment])
{
    // For loop statements
}

There are three important aspects to a for loop declaration:

  1. Variable declaration -- Each for loop allows you to declare and initialize a variable. That variable's scope is limited to the for loop and anything inside that loop.
  2. Conditional test -- This test determines when you break out of the for loop. As long as the result of the conditional is true, then the loop runs at least one more time. Once the result of the conditional test is false, we break out of the loop. This is kind of like an if statement inside the for loop. Traditionally you'll test the variable from the declaration section here.
  3. Variable increment -- The point of the for loop is to not loop indefinitely. Each time through, you want to get closer and closer to breaking that conditional statement. That's what the variable increment section is for. Traditionally, you'll increment the variable from the declaration section here.

Here's an example for loop that should run exactly five times:

language:c
for (int i=0; i<5; i = i + 1)
{
    // Loop through here 5 times.
    // i starts at 0
    // each time through i increases by 1
    // once i increases to 5, we break
    // out of this loop.
}

The order of operations of this loop looks a little something like this:

  1. Create a variable called i and set it to 0.
  2. Test i. If i < 5 we run through the for loop. If i >= 5 break out of the loop, we're done.
  3. After running through the loop, run the increment: add 1 to i.
  4. After the increment jump back up to step 2. And repeat until the condition becomes false (i >= 5).

In this case we'll exit the for loop after i increases to 5. We'll have run through it 5 times by then.

Arrays are the perfect partner for for loops. When you need to run through each variable in an array, you can place a variable in the index section, and for loop through each member of the array. We'll be doing just that in this experiment...

Sketch and Experiment

Here's the Sandbox_13_SoundDetecting.ino sketch. Read through the comments, they'll help re-inforce what you've just learned about array's and for loops.

language:c
    // Sandbox 13: Sound Detecting

/* Introducing the fabulously groundbreaking SOUND (Sandbox’s Over/Under Nominal 
   Decibels) System! Microphone check 1..2..1..2. With the SOUND you’ll always 
   have an adjustable sound level detector handy!

   In this experiment we’ll use the Sandbox’s on-board microphone to measure 
   volume levels and display them on the LEDs. The microphone produces a sound 
   wave, which is just another analog voltage that we can measure. The louder 
   the sound, the higher the amplitude of the wave and the larger the voltage.

   This sketch introduces the concept of arrays. Arrays are a collection of 
   variables, which can all be accessed and manipulated with a single variable
   name. To keep track of which variable within the array is being called, we
   use an index.

   We also use for loops for the first time in this experiment. For loops are a
   looping construct we use to run a block of code for a specified number of
   iterations. Instead of looping indefinitely, like we do with the loop()
   function, a for loop allows us to loop five, ten, twenty...however many times
   we need.
*/

const int slidePin = A3;    // A constant variable to store our slide pot pin
const int micPin = A2;      // A constant variable to store our microphone pin

// Now let's create an ARRAY of variables. An array is a collection of variables,
// all referenced with an array name and an INDEX. This is how we create an
// array containing 5 values:
const int ledPins[5] = {4, 5, 6, 7, 8};
// Our array is called "ledPins". Each value in the array can be referenced
// using a specific index, called within the square brackets directly following
// the array name. The index STARTS AT 0.
// For example, ledPins[0] is 4, ledPins[1] is 5, and ledPins[4] is 8 (the last
// value in the array).

void setup()
{
    // Set up our mic and slide pot pins as INPUTs
    pinMode(slidePin, INPUT);
    pinMode(micPin, INPUT);

    // Now let's use a for loop to set each ledPins as an input.
    // There are three parts to defining a for loop: (1) variable declaration,
    // (2) a test (like an if statment), (3) increment. As long as the test
    // returns true, we continuously run through the for loop. Each time through
    // the loop, the increment part happens. Eventually we want to exit the for
    // loop after everything we need to happen has happened.
    // In this example, we create a variable, i, and set it to 0. Each time 
    // through the loop we increase i by 1 (i++). At that point, if i is bigger
    // than 5, we exit the for loop.
    // We can also use the variable declared in the for loop. In this case we
    // use it to index the array. Arrays and for loops work hand-in-hand.
    for (int i=0; i<5; i++)
    {
        // First time through, set ledPins[0] (pin 4) to OUTPUT
        // 2nd time through, set ledPins[1] (pin 5) to OUTPUT
        // ...
        // 5th time through, set ledPins[4] (pin 8) to OUTPUT)
        // Then exit the for loop because i >= 5.
        pinMode(ledPins[i], OUTPUT);
    }
}

void loop()
{
    int maximum = analogRead(slidePin); // Read the slide pot sensor into a var
    int micReading = analogRead(micPin);    // Read the microphone value in

    // Again, we'll use a for loop to cycle through each LED in the ledPins
    // array.
    for (int i=0; i<5; i++)
    {
        if (micReading > ((maximum / 5) * (i+1)))
        {   // If the microphone reading is greater than a scaled value
            digitalWrite(ledPins[i], HIGH); // Turn on that LED
        }
        else
        {   // Otherwise, turn off that LED
            digitalWrite(ledPins[i], LOW);
        }
    }
}

Go ahead and upload the sketch, then make some noise at your Sandbox. Are the LEDs bouncing to your voice? If not, try tapping on the mic.

To adjust the sensitivity of the volume meter, move the slide pot up or down. With the slider set to the far right, it’ll take a really loud sound to make every LED turn on. But if you set the slider too low even the slightest noise will set the meter off.

Your Turn!

  • Can you rewrite the sketch to use the RGB LED instead of the white LEDs? Make it turn red when the volume is really loud, and blue and/or green otherwise. Bonus points for using analog outputs!