ws2812b and msgeq7 spectrum sheild

I know this topic has been done to death but i haven’t been able to find what I need. Im very new to arduino and am making a spectrum rgb spectrum visualizer I found on reddit. I want to modify the sketch to separate at least 5 of the 7 available bands from the msgeq7 chip and have different ws2812b strips react. I like how the lighting effects works on this example and want to keep that effect.

I feel like the answer has to be staring me in the face… the original sketch i found from reddit allows you to select a frequency and display it on a single strip…so i know its possible to select a single frequency to be displayed.

so far all I have managed to learn is how to do is add more strips to the board and make them work.
I have found plenty of examples using a matrix but not sure how to apply that to individual strips of 20 leds.
I also dont quite understand how the frequencies are separated in those examples. I want to use individual strips instead of a matrix so i can arrange them physically anywhere.

for this project im using:
UNO R3
sparkfun spectrum sheild
ws2812b led strips

This is the code I have so far. it works just not how i want it to. all strips will display the same animation.
Any help is greatly appreciated, a nudge in the right direction is all I need.

#include <FastLED.h>
#include <Wire.h>
#include <Arduino.h>


#define STRIP2                13
#define STRIP                 12
#define NUM_LEDS_PER_STRIP  20
#define LED_TYPE              WS2812B
#define BRIGHTNESS            64
#define COLOR_ORDER           GRB
CRGB leds[NUM_LEDS_PER_STRIP];


// Audio input setup
int strobe = 4;
int reset = 5;
int audio1 = A0;
int audio2 = A1;
int left[7];
int right[7];
int band;
int audio_input = 0;
int freq = 0;

//int STRIP = (12,13);

// Standart Visualizer Variables
int midway = NUM_LEDS_PER_STRIP / 2; // Centre mark from double level visualizer
int loop_max = 2;
int k = 255; // Color wheel position
int decay = 0; // How may ms befor decay
int decay_check = 0;
long pre_react = 0; // New spike conversion
long react = 0; // Numbre of leds beeing lit
long post_react = 0; // Old spike conversion
// Rainbow wave setting
int wheel_speed = 2;

#define UPDATES_PER_SECOND 100


void setup() {
  // Spectrum setup
  pinMode(audio1, INPUT);
  pinMode(audio2, INPUT);
  pinMode(strobe, OUTPUT);
  pinMode(reset, OUTPUT);
  digitalWrite(reset, LOW);
  digitalWrite(strobe, HIGH);
  
  // Led lightning setup
  
  delay( 3000 ); // power-up safety delay
//  FastLED.addLeds<LED_TYPE, STRIP2, COLOR_ORDER>(leds, NUM_LEDS_PER_STRIP).setCorrection( TypicalLEDStrip );
  FastLED.addLeds<LED_TYPE, STRIP, COLOR_ORDER>(leds , NUM_LEDS_PER_STRIP).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );

// Clear leds
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++)
    leds[i] = CRGB(0, 0, 0);
  FastLED.show();
}

// Function to generate color based on virtual wheel
CRGB Scroll(int pos) {
  CRGB color (0,0,0);
  if(pos < 85) {
    color.g = 0;
    color.r = ((float)pos / 85.0f) * 255.0f;
    color.b = 255 - color.r;
  } else if(pos < 170) {
    color.g = ((float)(pos - 85) / 85.0f) * 255.0f;
    color.r = 255 - color.g;
    color.b = 0;
  } else if(pos < 256) {
    color.b = ((float)(pos - 170) / 85.0f) * 255.0f;
    color.g = 255 - color.b;
    color.r = 1;
  }
  return color;
}









// Function to get and set color
void singleRainbow()
{
  for(int i = NUM_LEDS_PER_STRIP - 1; i >= 0; i--) {
    if (i < react)
      leds[i] = Scroll((i * 256 / 50 + k) % 256);
    else
      leds[i] = CRGB(0, 0, 0);      
  }
  FastLED.show(); 
}


// Function to mirrored visualizer
void doubleRainbow()
{
  for(int i = NUM_LEDS_PER_STRIP - 1; i >= midway; i--) {
    if (i < react + midway) {
      leds[i] = Scroll((i * 256 / 50 + k) % 256);
      leds[(midway - i) + midway] = Scroll((i * 256 / 50 + k) % 256);
    }
    else
      leds[i] = CRGB(0, 0, 0);
      leds[midway - react] = CRGB(0, 0, 0);
  }
  FastLED.show();
}

void readMSGEQ7()
// Function to read 7 band equalizers
{
  digitalWrite(reset, HIGH);
  digitalWrite(reset, LOW);
  for(band=0; band <7; band++)
  {
    digitalWrite(strobe, LOW); // strobe pin on the shield - kicks the IC up to the next band 
    delayMicroseconds(30); // 
    left[band] = analogRead(audio1); // store left band reading
    right[band] = analogRead(audio2); // ... and the right
    digitalWrite(strobe, HIGH); 
    delayMicroseconds(40);
  }
}

void convertSingle()
{
  if (left[freq] > right[freq])
    audio_input = left[freq];
  else
    audio_input = right[freq];

  if (audio_input > 80)
  {
    pre_react = ((long)NUM_LEDS_PER_STRIP * (long)audio_input) / 1023L; // Translate audio level to numbres of leds

    if (pre_react > react) // Only adjust levelof led if level is higher than current level
    react = pre_react;

    Serial.print(audio_input);
    Serial.print(" -> ");
    Serial.println(pre_react);
  }
}

void convertDouble()
{
  if (left[freq] > right[freq])
    audio_input = left[freq];
  else
    audio_input = right[freq];

  if (audio_input > 80)
  {
    pre_react = ((long)midway * (long)audio_input) / 1023L; // Translate audio level to numbre of leds

    if (pre_react > react) // Only adjust levelof led if level is higher than current level
      react = pre_react;

    Serial.print(audio_input);
    Serial.print(" -> ");
    Serial.println(pre_react);
  }
}

// Function to visualize with a single level
void singleLevel()
{
  readMSGEQ7();

  convertSingle();

  singleRainbow(); // Apply color

  k = k - wheel_speed; // Speed of the color
  if (k < 0) // Reset color wheel
    k = 255;

  // REMOVE LEDs
  decay_check++;
  if (decay_check > decay)
  {
    decay_check = 0;
    if (react > 0)
      react--;
  }
}

// Function to visualize with mirrored levels
void doubleLevel()
{
  readMSGEQ7();

  convertDouble();

  doubleRainbow();

  k = k - wheel_speed; // Speed of the color
  if (k < 0) // Reset color wheel
    k = 255;

  // Remove leds
  decay_check++;
  if (decay_check > decay)
  {
    decay_check = 0;
    if (react > 0)
      react--;
  }
}


void loop()
{  
  //singleLevel();      //Single level visualizer    -just commend one out and the other one in. You can only use one at a time!!!!! 
  doubleLevel();        //Mirrored visualizer        -just commend one out and the other one in. You can only use one at a time!!!!! 
  //delay(1);

}

You’re going to need a second array to hold the colours of the second strip:

CRGB leds2[NUM_LEDS_PER_STRIP];

Then you must tell FastLED that this array holds the colours for the second strip:

FastLED.addLeds<LED_TYPE, STRIP2, COLOR_ORDER>(leds2, NUM_LEDS_PER_STRIP).setCorrection( TypicalLEDStrip );

Then your code needs to set some colours in leds2. When FastLED.show() is called, both strips will be updated.

what if wanted all the strips to display the same colors but react differently to the different frequencies available from the spectrum sheild? do i still need to do that?

as the code is right now both strips update at the same time identically, what want is one strip to respond to the 63 hz freq, next one responds to the 160 hz, and so on. there are 7 frequencies available i just don't know how to assign a single freq to each strips data pin.

the lighting effect here is a rotating color wheel i want to keep that effect across all of them.

If you want the strips to be the same colours and react exactly the same as each other, you just need to connect them all to the same Arduino pin. I guess that's not what you want. If you want the strips to be different to each other, either in colour or how they react, then you need separate arrays for each strip.

PaulRB:
If you want the strips to be the same colours and react exactly the same as each other, you just need to connect them all to the same Arduino pin. I guess that’s not what you want. If you want the strips to be different to each other, either in colour or how they react, then you need separate arrays for each strip.

I want them to react differently but use the same rotating RGB pattern across the strips.

to simplify if i wanted them all lets say red, but want them to respond differently to the spectrum shield do they each need separate arrays still?

If so, I can do that but how do I tell each array to react to a separate frequency?

I want them to react differently but use the same rotating RGB pattern across the strips.

Can't make any sense of that.

to simplify if i wanted them all lets say red, but want them to respond differently to the spectrum shield

Again I cant reconcile all stay red yet react differently.

You can have one long string and, separate them into different sections with software, and then you will only need one data connection.

Or you can have separate strips each with its own data output and a separate array for each.

Grumpy_Mike: Can't make any sense of that. Again I cant reconcile all stay red yet react differently.

You can have one long string and, separate them into different sections with software, and then you will only need one data connection.

Or you can have separate strips each with its own data output and a separate array for each.

by react I dont mean the color. I want each strip to react to each frequency. the result being different numbers of leds light up on each strip depending on frequency input from music. I understand I need a separate array and data output, i dont know how to tell the data output to react to frequency.

I also found this post here. it seems they were trying to accomplish a similar task but having servos react to the frequencies.

Im attempting to adapt this to work... maybe?

I want each strip to react to each frequency. the result being different numbers of leds light up on each strip depending on frequency input from music.

You are not explaining this very well.

Do you actually mean that you want the number of LEDs that are on to be dependent on the amplitude of a specific frequency band?

If so you simply take the number that represents that band’s current amplitude , scale it to cover the number of LEDs you have and then turn on that number of LEDs.

So say you have 20 LEDs reserved for that frequency band, and you have a reading of 512 ( maximum 1023 ) then you have a 512 / 1023 = 1/2 or one half therefore you turn on 10 LEDs starting at the first one.

what i want to make is a spectrum visualizer basically.

i want each strip to react independently to a specific frequency 65hz, 120hz, and so on

so from what I can understand is I need to set all the strips up as separate arrays, easy enough

i cant figure out how to separate the frequencies into an array and apply them to the LED arrays.

please excuse me if I sound like I don't know what I'm talking about because I really dont.

I'm trying to use the MSGEQ7.h library but I think I am in over my head a bit. I've never coded anything myself and only have a very basic understanding. I have gotten other projects to work manipulating example codes but i cant find anything that is working.

Oh, I forgot. +1 Karma for using code tags in your first post.

Your code reads the sound levels in 7 bands and 2 channels and puts the results into two arrays:

int left[7];
int right[7];

But when the rest of the code reads these arrays, it accesses only one band's reading, because the variable:

int freq = 0;

which is set to zero and is never changed.

i want each strip to react independently to a specific frequency 65hz, 120hz, and so on so from what I can understand is I need to set all the strips up as separate arrays, easy enough

No, the simplest way of doing that is to have one long strip arranged as a zig zag matrix. That is starting at the lower left corner and have a column going up for the required number of LEDs, then coming down for the next column, and then up again. This is called a serpentine raster.

Your LEDs are all defined as one long array and you use software to split them.

I've never coded anything myself and only have a very basic understanding.

Sadly this is all too common with beginners. It is like saying you want to do dressage in the Olympics next week and asking what sort of an animal to use.

Don’t take my distress as defeat! I’ll figure it out eventually, it’s just going to take longer than anticipated. I knew it wouldn’t be easy. People spend their whole lives learning and perfecting this stuff.

I picked up an Arduino kit for a new hobby about a month ago. I have no expectations of picking this up easily, I expected a large learning curve Wich I’m happy to take on.

I mainly got into it to become better familiarized with circuits and micro controllers. I’m a master automotive technician by trade and thought Arduino could help me keep sharp when dealing with electrical problems and maybe even create a tool to help in my day to day work.

I diagnose fairly clomplex circuits regularly but understanding how some of them may be controlled by a computer or microcontroller could help me out a lot in my job.

I appreciate your help I’m sure I’ll bother this forum with more questions in the future.

Is there any reading material you might recommend for a newbie?

PaulRB: Oh, I forgot. +1 Karma for using code tags in your first post.

I did read all the "READ THIS BEFORE YOU POST!" shenanigans before wasting anyone's time. When asking strangers for help its best not to piss them off! ha.

Your code reads the sound levels in 7 bands and 2 channels and puts the results into two arrays:

int left[7];
int right[7];

But when the rest of the code reads these arrays, it accesses only one band's reading, because the variable:

int freq = 0;

which is set to zero and is never changed.

sorry I seemed to have missed your post here! so I was on the right track then. I Tried inserting "freq = 2" into the code for the strips....I know it was a long shot, but i feel proud that I deciphered that the freq value was what I needed...in a sense.

i noticed on the code that i am borrowing from they used a menu displayed on a lcd display. you can select different frequencies using this menu and 3 buttons(up, down, select)

this appears to be some of the code used to select a frequency. problem is i have no idea how to translate that into what i need.

void action4() {
   u8x8.clear();
   u8x8.drawString(0,0,"-Selected:");
   u8x8.drawString(0,1," 1 kHz");
    freq = 3;
  delay(1000);

theres some similar strings of code for the menu select, this seems to me to be the part of the code that actually tells the strip to react to the selected frequency

I picked up an Arduino kit for a new hobby about a month ago. I have no expectations of picking this up easily, I expected a large learning curve Wich I'm happy to take on.

So the first thing you must learn to do with a project is to break it down into manageable chunks, no one writes a large piece of code and expects it to work, you have to do a little, then test and then do some more. Finding code and trying to get it to run without understanding is sadly what a lot of people try to do these days and while it offers the potential of a quick fix, often this is illusory.

I did use two of these chips to male a spectrum display on a screen for another processor ( Raspberry Pi ), the video is here:- https://vimeo.com/manage/167914646/general

Then I used it to control animations https://vimeo.com/manage/184643867/general However the code was written in another language ( python ) that is not used with the Arduino IDE

For your project you need only one long strip. I would get that working first and then look at the example code you get with the driver libraries. The big two are fastLED and the Adafruit libiary, I find the latter easier to use. Look up the tutorials on that. https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-use

Learn how to split animations into separate sections of the strip by restricting the range of LED numbers you use. Change and modify the examples so that you know the effect of every step in the process of producing them.

Once you have that under your belt you can move onto reading the separate frequency bands and just printing them out on the serial monitor. At first just numbers, then as then number of "*" characters along the screen, each one representing an LED. It will look a bit of a mess but it will teach you to scale and map numbers from the shield.

Then you are ready to approach your goal and use these numbers in the LED animations. When all this is working then you can cut up your strip into a matrix and finish your project.

You are welcome to ask questions along the way, that is why we are here. What we don't do is write it for you or fix someone else's code for you. What we do like doing is teaching you how to do things, but do yourself a favor and take small bytes at a time.

Grumpy_Mike: You are welcome to ask questions along the way, that is why we are here. What we don't do is write it for you or fix someone else's code for you. What we do like doing is teaching you how to do things, but do yourself a favor and take small bytes at a time.

Thanks so much for the advice. As much as I want this to work I don't want anyone to write the code for me. The appeal of this whole thing is to learn a new skill that I can have fun with and make some actual useful things. Im not the smartest guy in the world but I have a ton of patience and I cant get this stupid idea out of my head until I finish it.

I have seen a lot of people suggest the adafruit library instead of the fastled. I may have to try it out. I may just try and get more familiar with fastLED though since i kind of have some experience with it. I will look into it either way.

I actually came across a post on this forum showing off that spectrum display you made. Very nice, the dancing skeletons were especially impressive.