Hey Folks,
I am new to the Arduino and coding, so please don't kill me if this is an everyday question.
I wanted to build a VU meter with a strip of neopixels, so I googled and found this.
It IS working like a charm, but I thought it would be looking much better if it were two strips, each for one channel of a stereo audio signal.
The code I am using is this:
#include <Adafruit_NeoPixel.h>
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(99, PIN, NEO_GRB + NEO_KHZ800);
const int sampleWindow = 10;
unsigned int sample;
int maximum = 110;
int peak;
int dotCount;
#define PEAK_FALL 4
void setup()
{
strip.begin();
strip.show();
}
void loop()
{
unsigned long startMillis= millis();
unsigned int peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 100;
// collect data for 50 mS
while (millis() - startMillis < sampleWindow)
{
sample = analogRead(0);
if (sample < 1024)
{
if (sample > signalMax)
{
signalMax = sample;
}
else if (sample < signalMin)
{
signalMin = sample;
}
}
}
peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude
int led = map(peakToPeak, 0, maximum, 0, strip.numPixels()) -1;
for(int i; i <= led; i++)
{
int color = map(i, 0, strip.numPixels(), 0, 255);
strip.setPixelColor(i, Wheel(color));
}
for(int i = strip.numPixels() ; i > led; i--)
{
strip.setPixelColor(i, 0);
}
strip.show();
if(led > peak) peak = led;
if(peak > 0 && peak <= strip.numPixels()-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,0,255)));
strip.show();
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
}
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);
}
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
I tried to just double each paragraph and change the variables to other ones for the second strip, so it would not interfere, but all I got was some pretty weird things.
This is the code I tried:
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define PIN2 5
const int sampleWindow = 25;
const int sampleWindow2 = 25;
unsigned int sample;
unsigned int sample2;
int maximum = 40;
int maximum2 = 40;
int peak;
int peak2;
int dotCount;
int dotCount2;
#define PEAK_FALL 4
#define PEAK_FALL2 4
void setup()
{
strip.begin();
strip.show();
strip2.begin();
strip2.show();
}
void loop()
{
unsigned long startMillis= millis();
unsigned int peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 100;
unsigned long startMillis2= millis();
unsigned int peakToPeak2 = 0;
unsigned int signalMax2 = 0;
unsigned int signalMin2 = 100;
while (millis() - startMillis < sampleWindow)
{
sample = analogRead(0);
if (sample < 1024)
{
if (sample > signalMax)
{
signalMax = sample;
}
else if (sample < signalMin)
{
signalMin = sample;
}
}
}
while (millis() - startMillis2 < sampleWindow2)
{
sample2 = analogRead(1);
if (sample2 < 1024)
{
if (sample2 > signalMax2)
{
signalMax2 = sample2;
}
else if (sample2 < signalMin2)
{
signalMin2 = sample2;
}
}
}
peakToPeak = signalMax - signalMin;
peakToPeak2 = signalMax2 - signalMin2;
int led = map(peakToPeak, 0, maximum, 0, strip.numPixels()) -1;
int led2 = map(peakToPeak2, 0, maximum2, 0, strip2.numPixels()) -1;
for(int i; i <= led; i++)
{
int color = map(i, 0, strip.numPixels(), 0, 255);
strip.setPixelColor(i, Wheel(color));
}
for(int j; j <= led; j++)
{
int color2 = map(j, 0, strip2.numPixels(), 0, 255);
strip2.setPixelColor(j, Wheel2(color2));
}
for(int i = strip.numPixels() ; i > led; i--)
{
strip.setPixelColor(i, 0);
}
for(int j = strip2.numPixels() ; j > led; j--)
{
strip2.setPixelColor(j, 0);
}
strip.show();
if(led > peak) peak = led; // Keep 'peak' dot at top
if(peak > 0 && peak <= strip.numPixels()-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,0,255)));
strip.show();
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
strip2.show();
if(led2 > peak2) peak2 = led2; // Keep 'peak' dot at top
if(peak2 > 0 && peak2 <= strip2.numPixels()-1) strip2.setPixelColor(peak2,Wheel2(map(peak2,0,strip2.numPixels()-1,0,255)));
strip2.show();
if(++dotCount2 >= PEAK_FALL2) { //fall rate
if(peak2 > 0) peak2--;
dotCount2 = 0;
}
}
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);
}
}
uint32_t Wheel2(byte WheelPos2) {
WheelPos2 = 255 - WheelPos2;
if(WheelPos2 < 85) {
return strip2.Color(255 - WheelPos2 * 3, 0, WheelPos2 * 3);
} else if(WheelPos2 < 170) {
WheelPos2 -= 85;
return strip2.Color(0, WheelPos2 * 3, 255 - WheelPos2 * 3);
} else {
WheelPos2 -= 170;
return strip2.Color(WheelPos2 * 3, 255 - WheelPos2 * 3, 0);
}
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void colorWipe2(uint32_t d, uint8_t wait2) {
for(uint16_t j=0; j<strip2.numPixels(); j++) {
strip2.setPixelColor(j, d);
strip2.show();
delay(wait2);
}
}
If anyone could tell me what I can do to get my Arduino to just double the whole analysing of the analogue pin and driving the neopixel strip, that would be really great.
My solution for the moment is that I am running just two ATMegas side by side, but of course this is not the best solution...
Thanks in advance guys!