WS2812 VU meter

I was looking for a nice VU meter using the WS2812 LED Strip and found a link which I cannot remember to accredit but the code was limited to 50 LEDs so I have a play around and not it was address the limits of the Adafruit_NeoPixel.h library.

Enjoy.

Youtube link

Just connect the audio source to GND and analoge pin A1 and then the LED to power and D2

Enjoy

#include <Adafruit_NeoPixel.h>

#define PIN 2
#define lightCount 144

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_HZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(lightCount, PIN, NEO_GRB + NEO_KHZ800);



//fadeThickness = 0;  // CHANGE THICKNESS (0-10)

int vol = 0;
float total = 0;
int fadeCol = 0;
int val[25];
int volLast = 0;
int fadeAmt = 0;
int counter = 0;




void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
// Serial.begin(9600); 
}

void loop() {
  fadeCol = 0;
total = 0;

  for (int i = 0; i < lightCount; i++){
      counter = 0;
       do{
      vol = analogRead(A1);
 
      counter = counter + 1;
      if (counter > 500){
         rainbowCycle(10);
        
      }
    }while (vol == 0);
    
    total = total + vol;
 
  }
  
  vol = total / 80;
// Serial.println(vol);
  
  vol = map(vol,20,255,0,20);
  
  
  if (volLast > vol) {
    vol = volLast - 4;
  }
  
  volLast = vol;
  fadeAmt = 0;
   
// Serial.print(vol);
  for (int i = 0; i<strip.numPixels()/2;i++){
    
   
 
    if (i < vol){ 
    
          
         
         strip.setPixelColor((i+strip.numPixels()/2), strip.Color(0,255,vol));
         strip.setPixelColor((strip.numPixels()/2-i), strip.Color(0,255,vol));
    }
    else if (i < (vol + 8)) {
      
         strip.setPixelColor((i+strip.numPixels()/2), strip.Color(255,vol,vol));
         strip.setPixelColor((strip.numPixels()/2-i), strip.Color(255,vol,vol));
      
    }
    else
    {
       
      
         strip.setPixelColor((i+strip.numPixels()/2), strip.Color(0,0,255));
         strip.setPixelColor((strip.numPixels()/2-i), strip.Color(0,0,255));

      
    }
  }
    
 
    
  
  
  
  strip.show();
  
}

void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
     vol = analogRead(A0);
     if (vol> 10) {
       
      return;
       
     }
    
    
  }
}

uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

Excellent many thanks, I tried it and it worked, very simple code. I would like to know which is the line that defines the audio input, I want to implement it in another code that I got and change that part since the other code I have uses a microphone and I want to connect it directly with this one, from now on, thank you very much, I hope you can help, greetings!

I am totally new in Arduino, just playing with some LEDS and building some projects I found in YouTube.

I took a 'Sound Sensor Module KY-038' and tried to connect it with a RGB 5V LED strip with 12 leds through an Arduino Uno. I tried several codes found on the Internet but nothing seems to work.

I connect the strip input and mic input to D6 on Uno. I connect the AO of the mic to A0 on Uno.
The mic also has a DO but I don't use it.

The project I am on is like this:

The code is so long that I had to write the link to it:

When I run the code the led strip lights all blue and only the last LED seems to flash in blueish formats only when sound change. I did changed the code to set the number of leds i am using from 150 to 12.

Any help? I really need it!

Wat kind of mic do you use? Some are comming with a dc-offset.

#define micPin  1 //Your mic pin


void setup() {

Serial.begin(9600);
}

void loop() {
Serial.println(analogRead(micPin));
}

Open serial plotter and look wat is your avarage signal (at silence).

@ the sound_reactiive.ino, change this part with your readings.

//Confirmed microphone low value, and max value
#define MIC_LOW 0.0
#define MIC_HIGH 737.0

Here is some code I have using the DFRobot Sound Analyzer as an input source to generae LED lighting:

#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include <Adafruit_NeoPixel.h>
#include "AudioAnalyzer.h"
////
/* define event group and event bits */
EventGroupHandle_t eg;
#define evtDo_AudioReadFreq       ( 1 << 0 ) // 1
////
TickType_t xTicksToWait0 = 0;
////
QueueHandle_t xQ_LED_Info;
////
const int NeoPixelPin = 26;
const int LED_COUNT = 24; //total number of leds in the strip
const int NOISE = 150; // noise that you want to chop off
const int SEG = 6; // how many parts you want to separate the led strip into
const int SerialDataBits = 115200;
const int Priority4 = 4;
const int TaskStack40K = 40000;
const int TaskCore1  = 1;
const int TaskCore0 = 0;
const int AudioSampleSize = 6;
const int Brightness = 180;
const int A_D_ConversionBits = 4096; // arduino use 1024, ESP32 use 4096
////
Analyzer Audio = Analyzer( 5, 15, 36 );//Strobe pin ->15  RST pin ->2 Analog Pin ->36
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
Adafruit_NeoPixel leds = Adafruit_NeoPixel( LED_COUNT, NeoPixelPin, NEO_GRB + NEO_KHZ800 );
////
int FreqVal[7];//create an array to store the value of different freq
////
void setup()
{
  eg = xEventGroupCreate();
  Serial.begin( SerialDataBits );
  Audio.Init(); // start the audio analyzer
  leds.begin(); // Call this to start up the LED strip.
  clearLEDs();  // This function, defined below, de-energizes all LEDs...
  leds.show();  // ...but the LEDs don't actually update until you call this.
  ////
  xQ_LED_Info = xQueueCreate ( 1, sizeof(FreqVal) );
  //////////////////////////////////////////////////////////////////////////////////////////////
  xTaskCreatePinnedToCore( fDo_AudioReadFreq, "fDo_ AudioReadFreq", TaskStack40K, NULL, Priority4, NULL, TaskCore1 ); //assigned to core
  xTaskCreatePinnedToCore( fDo_LEDs, "fDo_ LEDs", TaskStack40K, NULL, Priority4, NULL, TaskCore0 ); //assigned to core
  xEventGroupSetBits( eg, evtDo_AudioReadFreq );
} // setup()
////
void loop() {} // void loop
////
void fDo_LEDs( void *pvParameters )
{
  int iFreqVal[7];
  int j;
  leds.setBrightness( Brightness ); //  1 = min brightness (off), 255 = max brightness.
  for (;;)
  {
    if (xQueueReceive( xQ_LED_Info, &iFreqVal,  portMAX_DELAY) == pdTRUE)
    {
      j = 0;
      //assign different values for different parts of the led strip
      for (j = 0; j < LED_COUNT; j++)
      {
        if ( (0 <= j) && (j < (LED_COUNT / SEG)) )
        {
          set(j, iFreqVal[0]); // set the color of led
        }
        else if ( ((LED_COUNT / SEG) <= j) && (j < (LED_COUNT / SEG * 2)) )
        {
          set(j, iFreqVal[1]); //orginal code
        }
        else if ( ((LED_COUNT / SEG * 2) <= j) && (j < (LED_COUNT / SEG * 3)) )
        {
          set(j, iFreqVal[2]);
        }
        else if ( ((LED_COUNT / SEG * 3) <= j) && (j < (LED_COUNT / SEG * 4)) )
        {
          set(j, iFreqVal[3]);
        }
        else if ( ((LED_COUNT / SEG * 4) <= j) && (j < (LED_COUNT / SEG * 5)) )
        {
          set(j, iFreqVal[4]);
        }
        else
        {
          set(j, iFreqVal[5]);
        }
      }
      leds.show();
    }
    xEventGroupSetBits( eg, evtDo_AudioReadFreq );
  }
  vTaskDelete( NULL );
} // void fDo_ LEDs( void *pvParameters )
////
void fDo_AudioReadFreq( void *pvParameters )
{
   // int64_t EndTime = esp_timer_get_time();
   // int64_t StartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros
  for (;;)
  {
      xEventGroupWaitBits (eg, evtDo_AudioReadFreq, pdTRUE, pdTRUE, portMAX_DELAY);
      Audio.ReadFreq(FreqVal);
      for (int i = 0; i < 7; i++)
      {
        FreqVal[i] = constrain( FreqVal[i], NOISE, A_D_ConversionBits );
        FreqVal[i] = map( FreqVal[i], NOISE, A_D_ConversionBits, 0, 255 );
      }
      xQueueSend( xQ_LED_Info, ( void * ) &FreqVal, xTicksToWait0 );
    // }
  }
  vTaskDelete( NULL );
} // fDo_ AudioReadFreq( void *pvParameters )
////
//the following function set the led color based on its position and freq value
void set(byte position, int value)
{
  // segment 0, red
  if ( (0 <= position) && (position < LED_COUNT / SEG) ) // segment 0 (bottom to top), red
  {
    if ( value == 0 )
    {
      leds.setPixelColor( position, 0, 0, 0 );
    }
    else
    {
      leds.setPixelColor( position, leds.Color( value , 0, 0) );
    }
  }
  else if ( (LED_COUNT / SEG <= position) && (position < LED_COUNT / SEG * 2) ) // segment 1 yellow
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color(0, 0, 0));
    }
    else
    {
      leds.setPixelColor(position, leds.Color( value, value, 0)); // works better to make yellow
    }
  }
  else if ( (LED_COUNT / SEG * 2 <= position) && (position < LED_COUNT / SEG * 3) ) // segment 2 pink
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color(0, 0, 0));
    }
    else
    {
      leds.setPixelColor(position, leds.Color( value, 0, value * .91) ); // pink
    }
  }
  else if ( (LED_COUNT / SEG * 3 <= position) && (position < LED_COUNT / SEG * 4) ) // seg 3, green
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0));
    }
    else //
    {
      leds.setPixelColor( position, leds.Color( 0, value, 0) ); //
    }
  }
  else if ( (LED_COUNT / SEG * 4 <= position) && (position < LED_COUNT / SEG * 5) ) // segment 4, leds.color( R, G, B ), blue
  {
    // Serial.println( position );
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0));
    }
    else //
    {
      leds.setPixelColor(position, leds.Color( 0, 0, value) ); // blue
    }
  }
  else // segment 5
  {
    if ( value == 0 )
    {
      leds.setPixelColor(position, leds.Color( 0, 0, 0)); // only helps a little bit in turning the leds off
    }
    else
    {
      leds.setPixelColor( position, leds.Color( value, value * .3, 0) ); // orange
    }
  }
} // void set(byte position, int value)
////
void clearLEDs()
{
  for (int i = 0; i < LED_COUNT; i++)
  {
    leds.setPixelColor(i, 0);
  }
} // void clearLEDs()

You can just ignore the ESP32 OS code.

Just connect the audio source to GND and analoge pin A1

This will damage the Arduino. Audio signals are AC and the negative parts of signal will damage the analog pin.

I changed the MIC_LOW and MIC_HIGH to 530 and 630 respectively.
The 10 first leds are always on. The others are following the volume nicely. But they are all blue.

I testet it and end up with blue led´s only.

There is a for loop who makes all the changes, but i dont figure out wat is wrong.

I testet this one:

This one is working for me.

Things you have to change:

#define DC_OFFSET  -260  // DC offset in mic signal - if unusure, leave 0

For you its possible -510

#define N_PIXELS  144  // Number of pixels in strand

For you should be 12.

#define MIC_PIN   A0  // Microphone is attached to this analog pin
#define LED_PIN    6  // NeoPixel LED strand is connected to this pin

You should understand it by yourself :slight_smile: .

const int buttonPin = A2;     // the number of the pushbutton pin

There are multible VU-Meter you can switch with a button to GRD.