10 LED's that are supposed to be red but aren't!

Hi all,

A little background first. This is my first attempt at using programming to interface with hardware, it is my first experience using a micro-controller and it is my first real exposure to a C++ type language. However, I've been using shell script for over a decade, have a passing familiarity with PERL and have been teaching myself VBA recently. In short, I'm not a complete noob, although right now, I'm feeling like one! :frowning:

So now onto the problem at hand!

Ultimate Goal: I'm attempting to creating some pulsing purple lights for a costume being displayed at the International Makeup Artists Trade show (IMATS) in May.

Hardware: To test the final look I'm aiming for I am currently using an Uno Rev3 (ATMEGA328 with 10 Adafruit NeoPixel LEDs cut from a strip. The LED's are connected to the Uno via the 5V and GND pins and data is provided via pin 6.

Current Goal: Rather than jump straight in at the deep end, I'm attempting to build the code from scratch so that I have a better understanding of exactly what is happening. As such, at the moment I am just attempting to turn all 10 LED's onto a single colour, red in this case. The code I am using for this is as follows:

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIX 10

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIX, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // put your setup code here, to run once:
  strip.begin();
  strip.show();

}

void loop() {
  // put your main code here, to run repeatedly:
  for(int i = 0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i,255,0,0);
    strip.setBrightness(10);  
    strip.show(); 
  }
   
}

Expected Output vs Reality: So, if I'm aiming for 10 red LED's from this code, I'm not even close!

LED's 1, 4 and 7 are red.
LED's 2, 5 and 8 are green. 2 and 5 also have their white side lit up.
LED's 3 and 6 are blue with white lit up.
LED's 9 and 10 are unlit.
Output can be seen here.

I should also add that I've tested the hardware configuration using the strandtest sketch that comes with the NeoPixel library. Output from that appears to be OK so I don't think I have a hardware issue.

So in short, what simple thing have I overlooked/gotten wrong in getting red LED's?

exitalterego:
So in short, what simple thing have I overlooked/gotten wrong in getting red LED's?

exactly how are you powering the LEDs?

The Uno is plugged into my laptop via USB, with the LED's then powered from the 5V pin.

The LED's are connected to the Uno via the 5V and GND pins

The 5V output on the Uno cannot provide much current and overloading it will cause the Arduino to malfunction.

Follow Adafruit's guide to powering them.

Move strip.show out of the for loop. So after all the colors are set.

Add delay(100);

after that.

Another note; You do not need to call "show()" and "setBrightness()" for each pixel you set, and if you do not need to change the colors of the LED's, you can put your loop() code inside setup() since you only have to set the colors once. After that, you can put the Arduino to stand-by / low power mode to save some battery.

OK, thanks for the help so far guys.

jremington:
The 5V output on the Uno cannot provide much current and overloading it will cause the Arduino to malfunction.

Follow Adafruit's guide to powering them.

Forgive the ignorance but if I'm reading that correctly, rather than powering the LED's through the Uno, I can simply power them separately (via battery), just using the Uno to drive the data pin?

alto777:
Move strip.show out of the for loop. So after all the colors are set.

Add delay(100);

after that.

Danois90:
Another note; You do not need to call "show()" and "setBrightness()" for each pixel you set, and if you do not need to change the colors of the LED's, you can put your loop() code inside setup() since you only have to set the colors once. After that, you can put the Arduino to stand-by / low power mode to save some battery.

I think I've followed the advice regarding moving things out the loop. I'd have probably gotten to that point myself eventually once I started looking at improving the code but it's nice to have someone else QC'ing my code :smiley:

However, I'm a little uncertain as to the purpose of the delay. What is it supposed to achieve?

With respect to the low power mode, that would likely be a good idea in this particular example, but as I'm going to ultimately be working with an animation effect, I imagine that the Uno would have to remain on for that to work? If so, I'm not going to worry about adding it to this particular sketch.

Here is the sketch with the adjustments:

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIX 10

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIX, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // put your setup code here, to run once:
  strip.begin();
  strip.show();

  for(int i = 0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i,255,0,0);
    delay(100);  
    }
  strip.setBrightness(5);
  strip.show(); 
}

void loop() {
  // put your main code here, to run repeatedly:

   
}

Forgive the ignorance but if I'm reading that correctly, rather than powering the LED's through the Uno, I can simply power them separately (via battery), just using the Uno to drive the data pin?

You also have to connect all the grounds.

Yes, you can power the strip from a different source and use the Arduino on the data pin only - but you must remember to use a common ground.

Please do not add delay where you did, it will not do anything else than slowing down you code for no avail.

If you need animation in the strip / colors, you need to make that animation. Moving the "set all red" out of the main loop may be contra-productive if it is part of an animation on the strip.

Low power mode is of course useless if you want to run an animation on the strip. My suggestion was aimed at the fact that you only wanted the strip to be red.

Thanks for the help guys and the patience! I'll sort the power issue and retest the code. Assuming I get the LED's to be one given color, I'll be able to move onto the animation side of things :slight_smile:

I've also literally just stumbled on this page which I'm guessing shows the correct way to wire things?

Danois90:
Please do not add delay where you did, it will not do anything else than slowing down you code for no avail.

I did wonder about this. I'm assuming alto777 meant for me to add it after the show() but I'm still not entirely sure what the purpose of this would be here.

Danois90:
If you need animation in the strip / colors, you need to make that animation. Moving the "set all red" out of the main loop may be contra-productive if it is part of an animation on the strip.

Low power mode is of course useless if you want to run an animation on the strip. My suggestion was aimed at the fact that you only wanted the strip to be red.

I'll move the code back into the loop once I've got a working set of lights :stuck_out_tongue:

The second illustration from the page you found is how to do it. They have used a 1000mF, I think that 1000nF would be enough and mF may be an error.

The delay was meant as a slow down of the update frequency for the LED's. This is how it should have been:

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIX 10

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIX, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // put your setup code here, to run once:

  strip.begin();
  strip.show();

}

void loop() {
  // put your main code here, to run repeatedly:

  for(int i = 0; i<strip.numPixels(); i++)
  {
    //Animate the strip here
    strip.setPixelColor(i,255,0,0);
  }

  //Only call this when brightness actually changes
  strip.setBrightness(5);

  //Only call this once per update / loop. It will send all changes
  //to the strip, thus updating all LED's
  strip.show();

  //Wait a bit before next update of the strip. You should avoid the
  //usage of delay if possible. Use timing with millis() instead.
  delay(100);

}

setBrightness() was intended to be called once, in setup(), to limit the current/brightness of the LEDs throughout the life of the sketch. It is not intended as an animation effect itself! The operation of this function is “lossy” — it modifies the current pixel data in RAM, not in the show() call — in order to meet NeoPixels’ strict timing requirements. Certain animation effects are better served by leaving the brightness setting alone, modulating pixel brightness in your own sketch logic and redrawing the full strip with setPixel().

Directly from the docs...