Vu meter from mono to stereo

Hi. I'm working on a stereo neopixel VU-meter based on the 24x led neopixel ring.

I found a blogpost about this, but it is only mono. I have tried to understand the code, and added the second ring (or strip as the blogger used) and allso found where it reads from the analaoge-0 input, but I cant seem to figure out how to map that specific input to the left channel (led-ring representing the left channel) or to add the code for the right channel. I asume it is only to copy/paste the code and choose analogRead(1) instead of (0).

But the big issue is mapping analogRead (0) to #define LEFT 6 and analogRead (1) to #define RIGHT 7

Here is the link to the original code from Walltech.cc http://www.walltech.cc/wp-content/uploads/2014/03/VUMETER.txt

I changed the #define LED 6 to #define LEFT 6 and added #define RIGHT 7 I changed the Adafruit_NeoPixel strip = Adafruit_NeoPixel(99, PIN, NEO_GRB + NEO_KHZ800); to Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, LEFT, NEO_GRB + NEO_KHZ800); and added Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, RIGHT, NEO_GRB + NEO_KHZ800);

I hope anyone can help me out here.

Here is the link to the original code from Walltech.cc

You are having trouble with the code you modified, so you want us to look at the original. I don’t see how that will help.

But, if you make that a link, instead of expecting me to copy and paste it, I’ll look.

I’m having trouble with unerstanding the original code so that I can modify it to work for stereo in stead of mono.

Tarjei85: I'm having trouble with unerstanding the original code so that I can modify it to work for stereo in stead of mono.

I'm not going looking for it, and apparently others aren't either. You can post your code here, or struggle. Your choice.

Well thanks a lot. I was hoping for some help here, and asumed this was a serius foum with helping members. Not easy getting to know this shit when you get slapped in the face on your first time ever coding an arduino...

looking for a more welcoming forum to re post my issue

Why didn’t you just post your code? You listed several changes you made to the original, and expected us to go to the linked site, grab the code, and manually copy in your changes.

Whereas if you posted your modified code in the </>code block, I might of taken a look.

My problem is finding the place in the code where i define the animation to read the analog input from pin 0 or in my case pin 0 and 1. I'm currently on the road, and wont be back in a couple of days, but I will post my code once I'm back home.

Hi again.
Finally back home.

After some thinking while on the road I figured out the stereo part of the VU-meter, but when I fixed that a new problem showed up.

This vu-meter has a peak led that drops from peak to current reading, but the peak led is identical on both channels.
When i play audio on only the right channel the peak shows on the left one as well.
Because of this I have just commented out the peak part, until I figure it out.

After setting this up and testing the code I figured I want to reverse the direction on the right channel VU to go counterclockwise instead of clockwise.
Ihave been playing around to figure this out with no luck.

I allso added a potentiometer to adjust the sensitivity of the vu-meter.

#include <Adafruit_NeoPixel.h>

#define n 24
#define LEFT_OUT 6
#define RIGHT_OUT 5
#define BRIGHTNESS 50
#define COLOR_START 90
#define COLOR_FROM 60
#define COLOR_TO 255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(n, LEFT_OUT, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(n, RIGHT_OUT, NEO_GRB + NEO_KHZ800);

const int sampleWindow = 30; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
int potPin = 2;
int val = 0;
int peak;
int dotCount;
#define PEAK_FALL 3  // Rate of peak falling dot

void setup() 
{
  strip1.begin();
  strip1.setBrightness(BRIGHTNESS);
  strip1.show(); // Initialize all pixels to 'off'
  strip2.begin();
  strip2.setBrightness(BRIGHTNESS);
  strip2.show(); // Initialize all pixels to 'off'

}

void loop() 
{
  val = (analogRead(potPin) / 2);
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 100;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude

   int led = map(peakToPeak, 0, val, 0, strip1.numPixels()) -1;
   
   for(int i; i <= led; i++)
   {
     int color = map(i, COLOR_START, strip1.numPixels(), COLOR_FROM, COLOR_TO);
     strip1.setPixelColor(i, Wheel(color)); 
     
   }
   
   for(int i = strip1.numPixels() ; i > led; i--)
   {
     strip1.setPixelColor(i, 0); 
     
   }
  strip1.show();
  
//  if(led > peak)  peak = led; // Keep 'peak' dot at top
   
//   if(peak > 1 && peak <= strip1.numPixels()-1) strip1.setPixelColor(peak,Wheel(map(peak,0,strip1.numPixels()-1,0,255)));

//   strip1.show();
   
// Every few frames, make the peak pixel drop by 1:

//    if(++dotCount >= PEAK_FALL) { //fall rate 
      
//      if(peak > 0) peak--;
//      dotCount = 0;
//    }
    
{
   unsigned long startMillis1= millis();  // Start of sample window
   unsigned int peakToPeak1 = 0;   // peak-to-peak level

   unsigned int signalMax1 = 0;
   unsigned int signalMin1 = 100;

   // collect data for 50 mS
   while (millis() - startMillis1 < sampleWindow)
   {
      sample = analogRead(1);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax1)
         {
            signalMax1 = sample;  // save just the max levels
         }
         else if (sample < signalMin1)
         {
            signalMin1 = sample;  // save just the min levels
         }
      }
   }
   peakToPeak1 = signalMax1 - signalMin1;  // max - min = peak-peak amplitude
   
   int led = map(peakToPeak1, 0, val, 0, strip2.numPixels()) -1;
   
   for(int i; i <= led; i++)
   {
     int color = map(i, COLOR_START, strip2.numPixels(), COLOR_FROM, COLOR_TO);
     strip2.setPixelColor(i, Wheel(color)); 
   }
   
   for(int i = strip2.numPixels() ; i > led; i--)
   {
     strip2.setPixelColor(i, 0); 
     
   }
  strip2.show();
  
 // if(led > peak)  peak = led; // Keep 'peak' dot at top
   
 //  if(peak > 1 && peak <= strip2.numPixels()-1) strip2.setPixelColor(peak,Wheel(map(peak,0,strip2.numPixels()-1,60,255)));

//   strip2.show();
   
// Every few frames, make the peak pixel drop by 1:

//    if(++dotCount >= PEAK_FALL) { //fall rate 
      
//      if(peak > 0) peak--;
//      dotCount = 0;
//    }
    
}



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

void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip1.numPixels(); i++)
  for(uint16_t i=0; i<strip2.numPixels(); i++) {
    strip1.setPixelColor(i, c);
    strip2.setPixelColor(i, c);
    strip1.show();
    strip2.show();
    delay(wait);
  }
}

Does anyone have any idea of how to fix the direction of the right channel and allso how to fix the peak problem?

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(n, LEFT_OUT, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(n, RIGHT_OUT, NEO_GRB + NEO_KHZ800);

Instead of stripLeft and stripRight? Why?

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)

How can that comment be correct, when sampleWindow is 30?

      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings

There’s not a snowball’s chance in hell that analogRead() will return a value that is not less than 1024.

   int led = map(peakToPeak, 0, val, 0, strip1.numPixels()) -1;

What will happen if peakToPeak is NOT between 0 and val?

{
   unsigned long startMillis1= millis();  // Start of sample window

Why is that curly brace there?

startMillis1, signalMax1, signalMax1, peakToPeak1, and strip2 just don’t seem to go together.

   for(int i; i <= led; i++)
   {
     int color = map(i, COLOR_START, strip2.numPixels(), COLOR_FROM, COLOR_TO);
     strip2.setPixelColor(i, Wheel(color)); 
   }

i represents the pixel number to set. To index from the opposite end, use strip2.numPixels() - i.

For the sample window i changed the value but forgot to change the comment. The other bits of code youre refering to I can not answer for since it is just simple clone of a code i found on the web.

The reverse direction you gave me will be checked out once i get home from work.

Thank you very much :)

I finally made it home from work.

Been testing out the

strip2.numPixels() - i

But with no luck. Only change I get is some shift in colors. But the leds still light up clockwise.

It is most likely me thats the problem, not the code.

Could you post your version of the code so that I could study it and maby ynderstand this a bit better? I have tried the strip2.numPixels () - i in all the places I could think of, but still nothing.

Could you post your version of the code

I don't have a version. Post yous. There is only ONE place where you should be using strip2.numPixels () - i in place of i:

     strip2.setPixelColor(strip2.numPixels () - i, Wheel(color));

Sorry my bad. I thouht i could just place in the -i and not the whole string. got the reverse animation to work. But yet again a new problem surfaced. Now the peak-led is acting weird. (Or not so weird actually, but it is not reversed, so it follows the output but it goes clockwise instead of counter clockwise.

Any ideas on this issues?

After testing out the VU-meter for an hour or two. And tweaking the code a bit I have come to terms that it looks great and I wont miss the peak function. That part of the code will be removed completely tomorrow, and the next step of my project will start. Making a casing for this thing.

I shot some photos and video of the vu meter as it is right now. You can take a look at the links below.

Video Photo1 Photo2 Photo3

Once again I would like to thank you all for great help and for being so patient with me since I'm a noob.

Thank you all :)

Update:

I have finished the casing for the VU-meter and is kinda happy with the end result.

Here is a video of the finished product

Tarjei85: Update:

I have finished the casing for the VU-meter and is kinda happy with the end result.

Here is a video of the finished product

Cool project. Glad you got it working.

I couldnt have done it wkthout all your help. once again thank you for makkng this project possible.

Hey Tarjei85,

Would you be so kind and publish the code because I intend the same.

greetings Thomas

evercity: Hey Tarjei85,

Would you be so kind and publish the code because I intend the same.

greetings Thomas

You see thats the problem with some people! Others help them and when they finaly do it right, they forgot about the forum and dont care to help the others! Now you and I can struggle to make the code for stereo VU meter insted of getting it from here.

I always help others on forum as good as I can, others help me alot, all from audio, mechanics to arduino programing and when I get it right I always leave schematic, code, results, etc... here for others that will need the same thing in the future.

https://drive.google.com/file/d/14N5Jh3GNWgOPeYzV7NqIIKi-Ow9CU91G/view?usp=sharing

Here you go if you need it, I made it from mono version and share it I`m not selfish feel free to use and modify it ;)