Adafruit Neopixel Library [PORTED]

No need, it works. The led walk is all fine. But whenever I try to combine it with a spark exposed function the spark is halted. In the last example I tried to change the brightness with a function… It stopped the loop and spark needed a reset.

It’s too strange…

Hi, @hansamann the new library works fine for me, I just tested it with the 8x8 matrix from Adafruit. Works well on Spark :spark: and I also ran tests on Arduino Uno and Due. Keep looking, must be something basic you are confronted with.

Well if you still want help, post your code and we’ll take a look! :smile:

Hi @rudyvan, @BDub, the Spark_NeoPixel lib alone, e.g. with a led walk example works fine. I got the latest code up and running :slight_smile: It really just stops working for me once I combine it with some sort of spark-exposed function. What's really strange is that it works for @Bdub now.

So the full code is below. I included the latest Spark_NeoPixel lib from Github, yesterday evening. Here are the "symptoms":

  • Once I flashed the firmware, I can verify that it works. E.g. the LED is flashing and I can check that the spark core exposes the function "lights". I took out the Serial wait function - but that's pretty much the only change.

  • I'll then call the lights function, e..g with 3 - it will turn on the 4 LEDs that should be turned on. But once the function returns, correctly with a 200 response code in this case, the LED triggered in the loop function to signal if spark is fine stops flashing. Spark has halted after the first call.

  • the only way to make it work again is to hit reset. Every function call over the REST API will now yield a "Timed out."

  • also funny: I am pretty sure it worked for a single RGB led - e.g. if I am not trying to toggle 4 at once. The problem is that I later want to toggle NeoPixel Rings with 12 RGB LEDS each - so I need to be able to control 16 Rings (16 is a number defined by my project, I want to toggle the lighting of 16 things...). NeoPixel Ring - 12 x 5050 RGB LED with Integrated Drivers : ID 1643 : $7.50 : Adafruit Industries, Unique & fun DIY electronics and kits

  • the RGB123 LED board I am using right now is this: http://rgb-123.com/product/88-8x8-rgb-led-matrix/ - I checked it twice, these are WS2812B chips. I have this connected to a 4A/5V power supply and I connected the GNDs of Spark and this power supply.

  • I read somewhere that calculating an input to to a function (base+1) is not a good idea. I cannot really understand why, but maybe this could be an issue. I could try at home tonight the next time. BTW I also remember that we once had delay(50) between each setPixelColor call.

I'll be posting a more general question to the forum about spark becoming unresponsive, too. It seems in this case somehow connected with the strip.setPixelColor calls, but I am wondering what the general issue here could be. thx for all your help :slight_smile: I've not given up.

 #include "Spark_NeoPixel.h"
int lights(String command);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(64, D2, WS2812B);
uint16_t channels = 0x0000; // All lights off
bool updateTime = false; // Time to update flag
bool s = false;
void setup() {
  pinMode(D7,OUTPUT);
  digitalWrite(D7,HIGH);
  strip.begin();
  strip.show();
  Serial.begin(9600);
  Spark.function("lights", lights);
  Serial.println("Ready.");
}
void loop() {
  s = !s;
  digitalWrite(D7,s);
  delay(100);
  if(updateTime) updateLights();
}
void updateLights() 
{
  updateTime = false;
  const uint32_t c_on = strip.Color(255, 255, 255);
  const uint32_t c_off = strip.Color(0, 0, 0);
  for (uint16_t i = 0; i < 16; i++)
  {
    uint16_t val = (channels & (1 << i)) ? 1 : 0; // is bit set or clear?
    Serial.print(i, DEC);
    Serial.print("->");
    Serial.print(val, DEC);
    Serial.print(" BASE: ");
    //strip.setPixelColor(i, (val == 1) ? c_on : c_off);
    uint16_t base = i * 4;
    Serial.println(base, DEC);
    delay(50);
    strip.setPixelColor(base, (val == 1) ? c_on : c_off);
    strip.setPixelColor(base+1, (val == 1) ? c_on : c_off);
    strip.setPixelColor(base+2, (val == 1) ? c_on : c_off);
    strip.setPixelColor(base+3, (val == 1) ? c_on : c_off);      
  }
  strip.show();
}
int lights(String command) 
{
  Serial.println("lights called with command " + command);
  delay(100);
  if(command.length() == 0)
    return -1;
  uint16_t number = command.toInt();
  if(number > 15)
    return -2;
  channels ^= (1 << number); // toggle the bit (0 - 15)
  updateTime = true;
  return 200;
}

Trying to play with the Library.
I have a 2811 strip, 100 Leds.

When using the default sample, only changing which pin to use, I get the raindbow(20) to work.
I can change the numbers of leds and it still work.
Changing to 2811 (instead of default ws2812B) It only leds my numbers of leds in white and only first led will use rainbow.
Switching back to 2812B setting it “works” with rainbow on the leds active works.

Now in 2812B mode I try to use the setpixel function.
Using this gives med 3 leds lit with 3 different colors.

Any suggestions how to solve this?

@mippen if you have a WS2811 strip, I think you should just set it to WS2811 and forget it :slight_smile: It was working that way right? There is basically two sets of timing in the library WS2812/WS2812B or WS2811.

Where did you buy your strip?

base+1 should be fine passing as reference to your function. It can get to be tricky in macros when you don't write your macros well.

I added the delay(50) just to make sure the Serial buffer was emptying before looping through the for() loop again and pushing more data out at the serial buffer. It's probably overkill, and you don't need a delay between each setPixelColor call.

The setPixelColor calls are super fast... they just set 3 bytes in RAM to your pixel color and return. The strip.show() is the one that has the __diable_irq() calls and should take only several milliseconds to complete for your 64 pixels.

@BDub I have better functions using ws2812 setting than ws2811.
Was a while ago I bought the strip… either via ebay or dx.

Is the “pre-split” version available on github?
I am sure that I managed to use set-pixel function on that version.

Ahh, it’s possible then that ebay advertised it as WS2811, WS2812 or WS2812B all in the same auction, but in reality it’s something completely different like a TM1803 or TM1804… I’ve seen it before! See above posts. Maybe also try this library: https://gist.github.com/technobly/8469105

If you can dig up the auction you bought it on, see what library they reference using… that might give you a better idea of what LED it is.

Here is the state of the library just before I split the files up:

It was bought on ebay but the auction details is not longer available.
“1M 60LEDs/M WS2811 Led Digital strip light Dream RGB Indi… (111121302056)”

Seems that I have the same problem with the old state of the library as well.

Ok, looks like they say WS2811, but the pictures show what looks like the 6-pin WS2812.

http://www.ebay.com/itm/1M-60LEDs-M-WS2811-Led-Digital-strip-light-Dream-RGB-Individually-Addressable-5V-/121136482420

The old library timing was set perfectly for WS2812's spec. Now it's somewhere in between 12 and 12B for maximum compatibility.

So rainbow(20); works with the library set to WS2812 with 100 pixels, but you just can't control the led's with setPixelColor()? Let's see your code. Paste it in here like this:

Three pixels is visible… but also a stray led is lit…

Wrapping code??

/*-------------------------------------------------------------------------
  Spark Core library to control WS2811/WS2812 based RGB
  LED devices such as Adafruit NeoPixel strips.
  Currently handles 800 KHz and 400kHz bitstream on Spark Core, 
  WS2812, WS2812B and WS2811.

  Written by Phil Burgess / Paint Your Dragon for Adafruit Industries.
  Modified to work with Spark Core by Technobly.
  Contributions by PJRC and other members of the open source community.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!
  --------------------------------------------------------------------*/

/* ======================= Includes ================================= */

#include <application.h>

#include "Spark_NeoPixel.h"

/* ======================= Prototype Defs =========================== */

void colorAll(uint32_t c, uint8_t wait);
void colorWipe(uint32_t c, uint8_t wait);
void rainbow(uint8_t wait);
void rainbowCycle(uint8_t wait);
uint32_t Wheel(byte WheelPos);

/* ======================= Spark_StrandTest.cpp ===================== */

#define PIN A6

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
//               note: if not specified, D2 is selected for you.
// Parameter 3 = pixel type [ WS2812, WS2812B, WS2811 ]
//               note: if not specified, WS2812B is selected for you.
//               note: RGB order is automatically applied to WS2811,
//                     WS2812/WS2812B is GRB order.
//
// 800 KHz bitstream 800 KHz bitstream (most NeoPixel products ...
//                         ... WS2812 (6-pin part)/WS2812B (4-pin part) )
//
// 400 KHz bitstream (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(100, PIN, WS2812B);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  // Do not run more than one of these at a time, or the b/g tasks 
  // will be blocked.
  //--------------------------------------------------------------
  strip.setPixelColor(6, strip.Color(255, 0, 255));
  strip.setPixelColor(7, strip.Color(255, 0, 255));
  strip.setPixelColor(8, strip.Color(255, 0, 255));
  
  strip.show();
  
  //colorWipe(strip.Color(255, 0, 0), 50); // Red
  
  //colorWipe(strip.Color(0, 255, 0), 50); // Green
  
  //colorWipe(strip.Color(0, 0, 255), 50); // Blue
  
  //rainbow(20);
  
  //rainbowCycle(20);
  
  //colorAll(strip.Color(0, 255, 255), 50); // Magenta
}

// Set all pixels in the strip to a solid color, then wait (ms)
void colorAll(uint32_t c, uint8_t wait) {
  uint16_t i;
  
  for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
  }
  strip.show();
  delay(wait);
}

// Fill the dots one after the other with a color, wait (ms) after each one
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 rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout, then wait (ms)
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) { // 1 cycle of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

So pixel index 6, 7, and 8 (actually the 7th, 8th, and 9th pixels) are lit up Magenta?

Which stray pixel is lit, what color is it?

Is it always the same one or does it move around?

Does the rainbow(20); flicker at all on any pixels or is it smooth?

Have you added a large 1000uF cap across the input power supply pins of the strip?

I have a 60 pixel strip at home that I can hook up that are WS2812B’s… let me see tonight if your code does the same thing on my strip.

seems to be pixel #36 that remains lit.
Have tested both with #6 #7 #8, #56 #57 #58 and #0 #1 #2
Have not added any CAP on power line

@mippen I’m seeing the same issue with my strip, except my pixel is #20 and it’s green. It appears memory is not being cleared with memset() like it should. If you clear that pixel does it return at all? In my testing I’ve found that once cleared it stays off. I’ll update again when I have more info on a fix.

EDIT: All fixed up now, I was only allocating and clearing the first 1/3 of memory needed for the pixels. This might fix other problems as well such as the one @hansamann was having :smile: Please let me know if it does!

1 Like

@BDub Great work! The change works!

1 Like

@BDub my code works now :slight_smile: this is crazy. thx a lot. I will now make changes so I can toggle all 16 channels at once. But I just made multiple calls and it still runs fine, that never worked before. Very cool.

By now I have sketched a crazy other setup: arduino running firmata talking to raspberry pi, pi connected via pub/sub zeroMQ to cloud endpoints,etc. crazy setup compared to the easy one I can have with Spark Core. Now the only thing that needs improvement is the reliability in chatty environments, but that’s CC3000/TI’s issue.

thx!!!

2 Likes

YES. Really super happy. :slight_smile:

1 Like

Hey @bdub(or anyone),

I’m having an issue getting my Neopixel Strip up and running. I’m using this: http://www.adafruit.com/products/1376 but only have 17 LEDs on my strand. After reading through this thread, I’m guessing my issue is the data pin. Could you give a little bit more info on the level switching?

So running the strip and the core off of 5v, then the Din through D0 + 300Ohm resistor(as suggested by adafruit), I need to add in this level switcher? Is there no way around it or am I just missing something?

I’ve had this running a while back, but I’m starting to think I did it before through my Uno instead of the Spark core.

Thanks for any tips!

Try removing the 300 ohm resistor. When controlling with a 3.3V output, the resistor seems to add too much of a drop and the strip starts to flake out at Vdd above 4V. If you are just controlling 17 LEDs, you can also try adding a diode 1N4001 in series with the Vdd input to the strip. So VIN on the Spark Core ---- |>|----- Vdd of the NeoPixel Strip As long as you don’t leave it set to all white, all the time… you’ll be ok. If you do though, you should power it from a separate power supply.

1 Like