Skip to main content

Arduino Based Audio Spectrum Analyzer Project

This Video will illustrate you how to visualize audio left and right signals in bar-graph in 16X2 LCD Display using Arduino.

Components Required:

1. Arduino UNO

2. 16X2 LCD Display

3. 3.5mm Audio Jack

4. Jumper Wires

 

Connection Diagram:

Arduino Code

#include <LiquidCrystal.h>
#include <fix_fft.h>

#define DEBUG 0
#define L_IN 1 // Audio input A0 Arduino
#define R_IN 0 // Audio input A1 Arduino

const int Yres = 8;
const int gain = 3;
float peaks[64];
char im[64], data[64];
char Rim[64], Rdata[64];
char data_avgs[64];
int debugLoop;
int i;
int load;

LiquidCrystal lcd(11, 10, 7, 6, 5, 4); // pins to LCD

// Custom CHARACTERS
byte v1[8] = {
  B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111
};
byte v2[8] = {
  B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111
};
byte v3[8] = {
  B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111
};
byte v4[8] = {
  B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111
};
byte v5[8] = {
  B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111
};
byte v6[8] = {
  B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111
};
byte v7[8] = {
  B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111
};
byte v8[8] = {
  B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111
};

void setup() {

  if (DEBUG) {
    Serial.begin(9600); // hardware serial
    Serial.print("Debug ON");
    Serial.println("");
  }

  lcd.begin(16, 2);
  lcd.clear();
  lcd.createChar(1, v1);
  lcd.createChar(2, v2);
  lcd.createChar(3, v3);
  lcd.createChar(4, v4);
  lcd.createChar(5, v5);
  lcd.createChar(6, v6);
  lcd.createChar(7, v7);
  lcd.createChar(8, v8);

  for (i=0;i<80;i++)
  {
    for (load = 0; load < i / 5; load++)
    {
      lcd.setCursor(load, 1);
      lcd.write(5);
    }
    if (load < 1)
    {
      lcd.setCursor(0, 1);
      lcd.write(5);
    }

    lcd.setCursor(load + 1, 1);
    lcd.write((i - i / 5 * 5) + 1);
    for (load = load + 2; load < 16; load++)
    {
      lcd.setCursor(load, 1);
      lcd.write(9);
    }
    lcd.setCursor(0, 0);
    lcd.print("LOADING.........");
    delay(50);
  }
  lcd.clear();
  delay(500);
}

void loop() {

  for (int i = 0; i < 64; i++) {    // 64 bins = 32 bins of usable spectrum data
    data[i]  = ((analogRead(L_IN) / 4 ) - 128);  // chose how to interpret the data from analog in
    im[i]  = 0;   // imaginary component
    Rdata[i] = ((analogRead(R_IN) / 4 ) - 128);  // chose how to interpret the data from analog in
    Rim[i] = 0;   // imaginary component
  }

  fix_fft(data, im, 6, 0);   // Send Left channel normalized analog values through fft
  fix_fft(Rdata, Rim, 6, 0); // Send Right channel normalized analog values through fft

  // At this stage, we have two arrays of [0-31] frequency bins deep [32-63] duplicate

  // calculate the absolute values of bins in the array - only want positive values
  for (int i = 0; i < 32; i++) {
    data[i] = sqrt(data[i]  *  data[i] +  im[i] *  im[i]);
    Rdata[i] = sqrt(Rdata[i] * Rdata[i] + Rim[i] * Rim[i]);

    // COPY the Right low-band (0-15) into the Left high-band (16-31) for display ease
    if (i < 16) {
      data_avgs[i] = data[i];
    }
    else {
      data_avgs[i] = Rdata[i - 16];
    }

    // Remap values to physical display constraints... that is, 8 display custom character indexes + "_"
    data_avgs[i] = constrain(data_avgs[i], 0, 9 - gain);     //data samples * range (0-9) = 9
    data_avgs[i] = map(data_avgs[i], 0, 9 - gain, 0, Yres);  // remap averaged values
  }

  Two16_LCD();
  decay(1);
}

void Two16_LCD() {
  lcd.setCursor(0, 0);
  lcd.print("L"); // Channel ID replaces bin #0 due to hum & noise
  lcd.setCursor(0, 1);
  lcd.print("R"); // ditto

  for (int x = 1; x < 16; x++) {  // init 0 to show lowest band overloaded with hum
    int y = x + 16; // second display line
    if (data_avgs[x] > peaks[x]) peaks[x] = data_avgs[x];
    if (data_avgs[y] > peaks[y]) peaks[y] = data_avgs[y];

    lcd.setCursor(x, 0); // draw first (top) row Left
    if (peaks[x] == 0) {
      lcd.print("_");  // less LCD artifacts than " "
    }
    else {
      lcd.write(peaks[x]);
    }

    lcd.setCursor(x, 1); // draw second (bottom) row Right
    if (peaks[y] == 0) {
      lcd.print("_");
    }
    else {
      lcd.write(peaks[y]);
    }
  }

  debugLoop++;
  if (DEBUG && (debugLoop > 99)) {
    Serial.print( "Free RAM = " );
    Serial.println( freeRam(), DEC);
    Serial.println( millis(), DEC);
    debugLoop = 0;
  }
}


int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}


void decay(int decayrate) {
  int DecayTest = 1;
  // reduce the values of the last peaks by 1
  if (DecayTest == decayrate) {
    for (int x = 0; x < 32; x++) {
      peaks[x] = peaks[x] - 1;  // subtract 1 from each column peaks
      DecayTest = 0;
    }
  }

  DecayTest++;
}

Comments

Popular posts from this blog

LED Brightness Control using Touch Sensor and ARM

Hey Folks, In this tutorial, we will learn, how to change  the intensity of light using touch sensor the ARM (FRDM-KL25Z). INTRODUCTION The FRDM-KL25Z is an ultra-low-cost development platform for Kinetis L Series KL1x (KL14/15) and KL2x (KL24/25) MCUs built on ARM® Cortex™-M0+ processor.  The FRDM-KL25Z has been designed by NXP in collaboration with mbed for prototyping all sorts of devices, especially those requiring the size and price point offered by Cortex-M0+ and the power of USB Host and Device. The FRDM-KL25Z is supported by a range of NXP and third-party development software. It is packaged as a development board with connectors to break out to stripboard and breadboard and includes a built-in USB FLASH programmer.               FEATURES NXP KL25Z Kinetis KL2x MCU (MKL25Z128VLK4) High-performance ARM® Cortex™-M0+ Core 48MHz, 16KB RAM, 128KB FLASH USB (Host/Device) SPI (2) I2C (2) UART (3) PWM (TPM) ADC (16 bit) DAC (1x 12bit) Touch Sensor

Arduino Based Piano Project

This video will illustrate to you how to make a simple piano by using IR Modules. Based on the frequency of sa, re, ga, ma, pa, dha, ni and sa the tone of the buzzer will change. Video Link Components Required: 1> I.R. Modules 2> Arduino Uno 3> Jumper Wires 4>Small Breadboard Circuit Diagram Arduino Code: int button_C = 2; int button_D = 3; int button_E = 4; int button_F = 5; int button_G = 6; int button_A = 7; int button_B = 8; int button_Cup = 9; int speaker = 10; int buttonstate_C = 0; int buttonstate_D = 0; int buttonstate_E = 0; int buttonstate_F = 0; int buttonstate_G = 0; int buttonstate_A = 0; int buttonstate_B = 0; int buttonstate_Cup = 0; //NOTES         'c'  , 'd',  'e',  'f',  'g', 'a',  'b',  'C' int tones[] = { 240, 254, 285, 320, 359, 280, 427, 956 }; //freq int Cur_tone = 0; void setup() {   pinMode(button_C, OUTPUT);   pinMode(button_D, INPUT);   pinMode(button_E, INP

Arduino Based Dancing Robo

Hello Makers This Blog is about making a generic dancing bot which will move his hand entertainingly responsive to interruptions. Video Link Components you need: Arduino UNO  ( Click here to Buy Arduino UNO ) I.R. Module ( Click here to buy IR Module ) Servo-2 ( Click here to buy servos ) Jumper Wire ( Click here to buy jumper wire ) Cardboard ( Click here to buy cardboard ) Follow the steps and do the connections As given in Video Arduino Code : Servo myServo0;     //Object Name of your first Servo Servo myServo1;     //Object Name of your Second Servo int a;              //Variable to Store Value of IR int count = 0;      //A Counter Variable void setup() {   // put your setup code here, to run once:   myServo.attach(3);   //Attaching pin No. of first Servo will be 3   myServo1.attach(4);  //Attaching pin No. of first Servo will be 4   pinMode(5, INPUT);   //Attaching pin No. of IR   Serial.begin(9600);  //To Start your Serial Monitor } void loop() {   // put