Go Down

Topic: Spectrum Analyzer using Adafruit NeoPixel Strips & Arduino Mega (Read 6168 times) previous topic - next topic

Grumpy_Mike

Quote
are you talking about the Resistor that's in parallel with the 33pF capacitor?
No. I am talking about the resistor in series with the 33pF capacitor.

Quote
I have to see that in the output of my code,
Well that is what the LED strip does for you. You set your frequency generator to one of the the peaks of the none tuneable filter. Then move it half way to the next peak, and adjust the other EQU chip so the same output peaks.


Edcastillo09

No. I am talking about the resistor in series with the 33pF capacitor.
Well that is what the LED strip does for you. You set your frequency generator to one of the the peaks of the none tuneable filter. Then move it half way to the next peak, and adjust the other EQU chip so the same output peaks.


Gotcha. Thanks Mike. You've been extremely helpful.

HajoPiltz

Another project that may be interesting for you to look into is Lumazoid.

They use software FFT AND drive up to 180 Neopixel on a UNO-comparable custom board and have open-sourced the code (link at the very end of the page).

Check out the video: They also have the nicest "pulse" effect I have seen in any project, open source or closed. Looks very fast to me.

A lot of cues about band binning, assigning weights etc. in there.
I plan to do something similar some day but with microphone input. We'll see...

Good luck with your project.

Edcastillo09

Just an updated:

Circuit & Code are working correctly. Now it's time to constructing the housing for these LEDs. I recently bought a good size picture frame where I can tape down the LEDs strips into 14 bands using foam double side tape, run all the wiring in the back and then have the arduino board close by.

Had a question if anyone wants to put their two cents in:

These LEDs strips come with weatherproofing on them. Is it better to remove this or leave it on there when I start constructing my layout? I'm trying to decide what's best. Thoughts?

FYI:
If someone is interested in creating something similar, please direct message me. I can provide steps on what I did :)

Grumpy_Mike

Well I would have got the type without the waterproofing as they are cheaper.

But if you are using them in a picture frame indoors, then I would take them out to get better cooling of the LEDs.

Edcastillo09

Well I would have got the type without the waterproofing as they are cheaper.

But if you are using them in a picture frame indoors, then I would take them out to get better cooling of the LEDs.
I was looking at Adafruit's website and they don't sell it without the weatherproofing. I'll see how difficult it is to take them out. If its too much hassle, I'll probably leave the weatherproofing on. The frame I have is not super enclosed so i'm not supper worried about cooling.

Thanks Mike!

Edcastillo09

Welp...was doing some testing of my code tonight and noticed that the first LED wasn't lighting up on my strip. Ran into my first problem (bittersweet). Seems like I may have burned the first LED but I have a 1000 uF cap in  parallel with the power rails on my 5VDC 10amp pwr supply and put a 470 ohm resistor in series on my data-in wire between the arduino and LED strip.

I have to look at the strip again to make sure I'm not seeing things but what could have cause my first LED to burn out? I followed the instruction from adafruit so I'm confused. I did do a continuity check between 5VAC and ground and of course I hear a small quick beep due to the caps charging but not an actual short. 

Any ideas anyone?

Grumpy_Mike

The first LED is mainly working, because if it were not then none of the other LEDs would light up. This is because the LEDs regenerate the data signal and if the first one were not working then the signal would never reach the others.

That said the first led is vulnerable to the signal you put into it. That is part of the reasons you put a seriese resistor in the signal line. If the Arduino is powered and feeding into a strip that is not powered then that input looks like a diode connected to ground. Without a resistor that can cause the Arduino's output to burn it out. Even with a resistor it could damage it. What value did you use? Always power up the LED strip first.

INTP

Make sure you are addressing the first LED as 0 instead of 1.

Edcastillo09

The first LED is mainly working, because if it were not then none of the other LEDs would light up. This is because the LEDs regenerate the data signal and if the first one were not working then the signal would never reach the others.

That said the first led is vulnerable to the signal you put into it. That is part of the reasons you put a seriese resistor in the signal line. If the Arduino is powered and feeding into a strip that is not powered then that input looks like a diode connected to ground. Without a resistor that can cause the Arduino's output to burn it out. Even with a resistor it could damage it. What value did you use? Always power up the LED strip first.
The morning after I posted my latest post, it came into mind that the LED wasn't dead since the others worked. So your response is dead on.

I used a 470ohm resistor for the data_in signal. I need to check my code (haven't got the chance). Glad I didn't burn it out. Learning as I go here. This is turning out into a great project :)

Edcastillo09

I haven't tested this yet, since I'm still waiting for my 100 LEDs to come in, but is one data-in signal for 280 LEDs fine? 140 LEDs are for the Left Channel 7 band while the other 140 LEDs are for the right channel. Can one data line control all of these or do I need another digital output? I was trying to find the specs online, but no luck.

Grumpy_Mike

Quote
is one data-in signal for 280 LEDs fine?
Yes it is fine.

Edcastillo09

Mike/or anyone else,


Do anyone know how to test to see if your Digital Input is flowing through all the LEDs? I cut up my LEDs strips by 20 LEDs and bought these jumpers to tie them together. Every other LED strip (Starting with the 2nd one) is flipped in order for the LEDs strips to reach. Before I cut them up, I ran my code and most of my LEDs were lighting up but for some reason this is not happening anymore. Only the first strip is working and I'm not sure how to test out the other lights. Ideas?

I've done a continuity check on the 5VDC and GND and they're good so this is why I'm saying it might be the digital input. I've also attached a picture for reference.

Edcastillo09

Ignore my comment avoid. With a little help from a friend, I have it work.

Have another question though. The following is my code just for the left handle channel which is lighting up 7 bands.

#include <MSGEQ7.h>

#include <Adafruit_NeoPixel.h>
//#define A0
//#define A1
#define pinReset 27
#define pinStrobe 26

#define LEDs 140 //total number of LEDs
#define PIN 22
#define OnColor 0x0000FF     // BLUE
#define OffColor 0x000000    // OFF
int SpectrumLeft[7];
int SpectrumRight[7];

int SpectrumGraphLeft[7][20];

Adafruit_NeoPixel Strip = Adafruit_NeoPixel(LEDs, PIN, NEO_GRB + NEO_KHZ800);

//#define MSGEQ7_INTERVAL ReadsPerSecond(50)
//#define MSGEQ7_SMOOTH 191 // Range: 0-255

//CMSGEQ7<MSGEQ7_SMOOTH, pinReset, pinStrobe, pinAnalogleft> MSGEQ7;

// Choose a PWM pin!
#define pinLed 22

void setup()
{

Serial.begin(9600);

//pinMode(pinAnalogleft, INPUT);
pinMode(pinStrobe, OUTPUT);
pinMode(pinReset, OUTPUT);
//analogReference(DEFAULT);

digitalWrite(pinStrobe,LOW);
digitalWrite(pinReset,HIGH);
digitalWrite(pinStrobe,HIGH);
digitalWrite(pinStrobe,LOW);  //Strobe pin on the shield (go to next Band)
digitalWrite(pinReset,LOW);

   // Assign pixels to graph array
  for (byte bar = 0 ; bar < 7 ; bar++)
  {
    for (byte pixel = 0 ; pixel < 20 ; pixel ++)
    {
      SpectrumGraphLeft[bar][pixel] = (bar * 20) + pixel;
    }    // end for
  } // end for

Strip.begin();
Strip.show(); // Initialize all pixels to 'off'

}

void loop()
{
 
  readSpectrum();      // Get values from spectrum shield
  mapSpectrum();      // Color pixels according to spectrum values     
  //delay(30);
}

void readSpectrum()
{
  // Band 0 = Lowest Frequencies.
  byte Band;
  for(Band=0;Band <7; Band++)
  {
    SpectrumLeft[Band] = analogRead(A0); //left
    //SpectrumRight[Band] = analogRead(1); //right
   
    digitalWrite(pinStrobe,HIGH);
    digitalWrite(pinStrobe,LOW);

      }
   
   
}

void mapSpectrum()    // map spectrum to pixel strips
{
  for(byte Band=0 ; Band <7 ; Band++)
  {      // remap the analogRead values to fit our 30-pixel segments/'bars'
    SpectrumLeft[Band] = map(SpectrumLeft[Band], 0, 1023, 0, 19);

    for (byte Pixel = 0 ; Pixel < SpectrumLeft[Band] ; Pixel++)
    {    // Turn appropriate pixels ON!
      Strip.setPixelColor(SpectrumGraphLeft[Band][Pixel], OnColor);
    }    // end for (Pixel
    for (byte Pixel = SpectrumLeft[Band] ; Pixel < 20 ; Pixel++)
    {      // Turn the rest OFF!
      Strip.setPixelColor(SpectrumGraphLeft[Band][Pixel], OffColor);
    }    // end for (Pixel

  }    // end for (Band
  Strip.show();
 
}    //  end mapSpectrum()
 


How do I code to have certain individual LEDs a certain colors? Lets say I want to make the first 5 LEDs on my first band a dark color and as I go up by 5, it turns into a more lighter and brighter color. Confused here.

Also, since I flipped every other strip, how do I "flip" my code so my LEDs are moving upwards in the same direction.

Thanks!
Eddie

Grumpy_Mike

Quote
since I flipped every other strip, how do I "flip" my code so my LEDs are moving upwards in the same direction.
This is called a serpentine raster the conversion from X - Y values to strip values are just a little more involved than the linear raster but that  what software is for. In the case of even numbered columns the conversion is simply the conversion from a linear laster, with:-
Code: [Select]
LED number = Y + (X * number of LEDs in a column)
However for odd numbered columns the conversion is :-
Code: [Select]
LED number = (X * number of LEDs in a column) + (number of LEDs in a column -1 -Y)
To determine if the X coordinate is odd or even, simply look at the least significant bit of the X value and if it is a zero then it is an even column or if it is a one it is an odd column. So all the software has to do is to examine the X - coordinate and decide what formula to use. It is simple enough to make a function that returns the LED number given the X & Y values.
Code: [Select]
int getLEDpos(int x, int y){ // for a serpentine raster
   int pos;
   if(x & 0x1) { // is X odd
      pos = x * yMax + (yMax -1 - y) ;
   } else { // x is even
      pos = x * yMax + y;
   }
   return pos;
}

Where yMax is the number of LEDs in a column.

Quote
How do I code to have certain individual LEDs a certain colors? Lets say I want to make the first 5 LEDs on my first band a dark color and as I go up by 5, it turns into a more lighter and brighter color.
You can use an array as a look up table to convert your LED number divided by 5 into the range of colours you want.
Arrays are covered here http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

Go Up