Feedback!

Sound Sensing Heart

Views: 5838 Difficulty: 3 Status: Development
Hm_sound_back

Combine an electret microphone, Arduino and a heart matrix for a sound-sensitive wearable device.

Here we show how to make the LucidTronix heart matrix sound-sensitive using an electret condenser microphone and some Arduino code. (Need to learn more about sensing sound on the Arduino? See our electret microphone breakout board tutorial.) The sound-sensitive Heart Matrix is great for concerts or monitoring your noisy neighbors. We turn the heart matrix into a volume (not frequency) equalizer. If you want the normal frequency display of audio equalizers you will need to perform the famous Fourier Transform, there is even an Arduino library for it!

Sound and Back

Hm_sound_back
Heart Matrix showing an audio waveform and its 3D printed case.

Video of The Heart Matrix Sensing Sound

Yell at the electronics and the electronics hear you!

Heart Matrix in 6 Seconds

Heart Matrix in 6 seconds!

Arduino Code for Sensing Sound and Displaying Audio Waveforms on the Heart Matrix

This code displays sound on our Heart Matrix display. This program uses two arrays, one to keep track of the raw input from the electret microphone and the second to keep track of the state of the LED display. The arrays are both global and declared at the top of the program:
  const int buffer_size = 15;
  int noises[buffer_size];
  const int num_cols = 10;
  int volumes[num_cols];
The audio waveform is detected by keeping a buffer of sound values from the electret microphone. Every delay_speed we shift the buffer down and record a new sound. The volume or amplitude is detected by finding how much the noise buffer varies. We use the individual pixel access which our Heart Matrix library allows to display the waveform like a bar graph. The minimum and maximum variances are kept track of in the lines:
     max_var = max(var, max_var);
     min_var = min(var, min_var);
We map the sound level value to lie between 0 and 8 so that it will correspond to a row index in the LED Matrix.
     var = map(var, min_var, max_var, 0, 9);
Then we iterate over the buffer of volumes and light up the LEDs according to the sound value in the buffer. We go from left to right across the Heart Matrix so that the newest sounds are shown on the right and the oldest ones on the left. (The same direction you read in English). This is the code:
  for (int i = 0 ; i < num_cols; i++){
     for (int j = 0 ; j < volumes[i]; j++){
       hm.set_pixel(i, j, true);  
     }
     for (int j = volumes[i] ; j < 8; j++){
       hm.set_pixel(i, j, false);  
     }
   } 
As in our electret microphone breakout board tutorial, we calculate the noise at any given moment in time by finding the variance of the sound buffer. Importantly, we use unsigned long integers for the variance because this number can get very big and overflow the size of a regular int data type.
/* LucidTronix Heart Matrix.
 * A volume visualizwer using the Heart Matrix's
 * on board LM386 amplifier chip and the electret microphone
 * See the tutorial at: 
 * http://lucidtronix.com/tutorials/35 */
 
#include <MsTimer2.h>
#include <HeartMatrix.h>

// dataPin is on 5, Latch is on 6, and clock is on 7
HeartMatrix hm = HeartMatrix(5,6,7); 

// sound global variables
const int buffer_size = 15;
int noises[buffer_size];
const int num_cols = 10;
int volumes[num_cols];

int cur_index = 0;
unsigned long last_shift = 0;
int mic_pin = 1;
int delay_speed = 40;
unsigned long max_var = 0;
unsigned long min_var = 99999999;

void setup() {
   Serial.begin(9600);
   MsTimer2::set(1,displayer2);
   MsTimer2::start();
   for (int i = 0 ; i < num_cols; i++) volumes[i] = 8;
   for (int i = 0 ; i < buffer_size; i++) noises[i] = 512;
   hm.animate();
}

void loop() {
  hm.on();
  sound_display();
}

void displayer2(){  
  hm.displayer();
}

void sound_display(){
   // Get a value from the electret microphone   
   noises[cur_index] = analogRead(mic_pin) ;
   cur_index++;
   if(cur_index == buffer_size) cur_index = 0;
   // Control the scroll speed with a potentiometer on analog pin 0
   delay_speed = max(10, (analogRead(0)/4));
   
   // Shift the waveform over one column
   if (millis() - last_shift > delay_speed){
     last_shift = millis();
     unsigned int avg = average(noises, buffer_size);
     unsigned long var = variance(noises, buffer_size);
     max_var = max(var, max_var);
     min_var = min(var, min_var);
     var = map(var,min_var , max_var, 0, 9);
     for (int i = 1 ; i < num_cols; i++){
      volumes[i-1] = volumes[i];
     }
     volumes[num_cols-1] = var;
   }
   
   // Write the wave form to LED display
   for (int i = 0 ; i < num_cols; i++){
     for (int j = 0 ; j < volumes[i]; j++){
       hm.set_pixel(i, j, true);  
     }
     for (int j = volumes[i] ; j < 8; j++){
       hm.set_pixel(i, j, false);  
     }
   }
}

int average(int* array, int length){
  int sum = 0;
  int i;
  for(i = 0; i < length ; i++){
    sum += array[i];
  }
  int avg = sum / length ;
  return avg;
}

unsigned long variance(int* array, int length){
  long sum = 0;
  long avg = average(array, length);
  for(int i = 0; i < length ; i++){
    sum += (array[i] - avg)*(array[i] - avg);
  }
  unsigned long var = sum / length;
  return var;	
}

Heart Matrix Arduino Library

MS Timer2 Library

Get the MS TImer2 Library here. Unzip and place it in your Arduino libraries folder.
Click Here to Download: MS Timer2 Library

Parts

Title Description # Cost Link Picture
Heart Matrix Kit The heart matrix kit. Shift register based wearable heart-shaped LED display. 1 $17.95 Link Heart_matrix_baggy
Electret Ear PCB Ear shaped electret condenser mic breakout board. 1 $4.0 Link Screen_shot_2013-02-15_at_6.34.37_pm
Electret Condenser Microphone MIC COND ANALOG OMNI -44DB Value: -44dB ±2dB 20Hz ~ 20kHz 1 $0.96 Link Screen_shot_2012-12-28_at_7.35.36_pm
LM386 IC AMP AUDIO PWR .325W MONO 8DIP Value: 4 V ~ 12 V 1 $0.93 Link 8-dip
Capacitor CAP CER 10UF 10V Y5V 0805. Ceramic Capacitor. Value: 10µF 10 $0.16 Link 0805(12_5mm_thickness)
Permalink: http://lucidtronix.com/tutorials/35
Connecting the MCP79410 real-time clock chip and our Heart Matrix you can show the time with love....
The heartduino is a heart-shaped arduino clone complete with onboard sensors and a 70 pixel LED matri...
Control the Heart Matrix LED display wirelessly, using XBEE radio modules....
Standalone programmable Heart-Shaped LED display....
Two LED matrices give 70 LEDs to light up a necklace with messages....
Wearable digital compass displays the direction in green LEDs....
RGB Flashlight, wearable sound art, rainbow lamp....
The Wearable Wayfinder is a totally programmable, beautiful little computer for your wrist packed wit...