Author Topic: Neopixel Issues  (Read 16151 times)

crambo

  • Jr. Member
  • **
  • Posts: 52
Neopixel Issues
« on: November 20, 2016, 08:24:40 pm »
At the behest of a fellow...thread has been moved...

Here is a sample that attempts to do a rather simple animation to a single neopixel connected to PIN1. I am confused regarding the difference of how the pinout maps to GPIO versus Arduino mapping.., but never the less, the issue seems to revolve around the timing of the data stream being sent out pin1.

The led will light up, but it is TOTALLY arbitrary and has no bearing on what the program actually states:


#include <Adafruit_NeoPixel.h>

// Which pin on the Digispark is connected to the DigiLED?
//#define PIN            4 //equiv to pin 5 on Oak - see detail above
#define PIN            5 //equiv to pin 1 on Oak - default setup for DigiLED shield - see detail above

// How many DigiLEDs are attached to the Digispark? (This is on the Oak...does this make a difference?)
#define NUMPIXELS      1

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);

int delayval = 500; // delay for half a second
int testValue = 0;
void setup()
{
  Particle.variable("testValue", testValue);
  // For Use of Oak pin 1, GPIO pin 5
  pinMode ( 1, OUTPUT ); //Apparently GPIO pin 5 needs to be stated as the CONSTANT?
  digitalWrite ( 1, 0 ); // See detail above


  pixels.begin(); // This initializes the NeoPixel library.

  pinMode ( 4, INPUT ); //the constructor and begin will set this up as an output, change it back to an input if desired

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

void loop()
{
  // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
  // in Red,Green,Blue order

  pixels.setPixelColor(3, pixels.Color(255, 255, 255)); //white
  pixels.show(); // This sends the updated pixel color to the hardware.
  delay(delayval); // Delay for a period of time (in milliseconds).

  pixels.setPixelColor(3, pixels.Color(0, 255, 255)); //cyan
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(3, pixels.Color(255, 0, 255)); //violet
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(3, pixels.Color(255, 255, 0)); //yellow
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(3, pixels.Color(255, 0, 0)); //red
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(3, pixels.Color(0, 255, 0)); //green
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(3, pixels.Color(0, 0, 255)); //blue
  pixels.show();
  delay(delayval);
  testValue = testValue + 1;
}

crambo

  • Jr. Member
  • **
  • Posts: 52
Re: Neopixel Issues
« Reply #1 on: November 20, 2016, 08:27:51 pm »
Ok, so plot thickens...

If I set the delayval to something low like 10, it appears that void loop is getting hung up. There are brief moments of quick animation interspersed by long lags. So, something is hanging up void loop?

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #2 on: November 20, 2016, 08:52:06 pm »
I'm in the process of breadboarding this. I've used Neopixels quite a bit on other platforms and I think on the Oak.

What is your pixel? A raw WS2812B? You realize that these are 5V devices and need a 104 cap bewteen power and ground, unless you have one that includes this.

Give my a few minutes or more and I'll run your code on and Oak with a single neopixel.

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #3 on: November 20, 2016, 09:07:21 pm »
OK, Haven't tried it yet but looking at the code I think the issue is with your pin definitions.

For the Oak most use pin 5 which is gpio 4. The Neopixel constructor takes the gpio 4 as the pin number which is mapped to pin 5. I know, its confusing. Try that and I will do the same here.

crambo

  • Jr. Member
  • **
  • Posts: 52
Re: Neopixel Issues
« Reply #4 on: November 20, 2016, 09:50:28 pm »
Hi EngEx,

Yes. I am supplying WS2812B via a separate 5v power supply with a 680 microfarad cap. Again, the issue is not that it doesn't work, it doesn't work well. There are odd pauses in void loop, made MUCH more noticable when delay is dropped to sub 100ms.

Let me know what you find out! Glad to have you prototype this out as well!

-Cam

crambo

  • Jr. Member
  • **
  • Posts: 52
Re: Neopixel Issues
« Reply #5 on: November 20, 2016, 09:57:39 pm »
ExEng,

I can verify that using the other pin combo yields same results. Odd pauses on void loop. No discernible pattern.

I verified that neopixel is not bad by testing same on arduino uno with same exact code minus the GPIO pin mapping differences, which I still don't quite get...

crambo

  • Jr. Member
  • **
  • Posts: 52
Re: Neopixel Issues
« Reply #6 on: November 20, 2016, 10:02:59 pm »
And, just for giggles, I loaded it on to another Oak I have and get same results. Hopefully ruling out hardware issues.

 :D

PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Neopixel Issues
« Reply #7 on: November 20, 2016, 10:33:11 pm »
I'm fed up with study for a while, so for giggles I dug out a 24 neopixel I had knocking around, and threw the strandtest code on it. Worked like a charm out of the box. The GPIO pin remapping stuff must have been fixed at some time - you don't need to work out the ESP8266 -> Oak mapping - pin 1 is pin 1.

I think there were a couple things wrong with the code, some were code related, and one is do with the Oak architecture itself.

Below is the slighly modified version of your orginal code. I changed the pin to 1 simply as that is also the one I had used in other neopixel test code I'd used before. You need to set the NUMPIXELS define to the number of pixels you have connected. If you have 1, then you set one. I used a ring with but only wanted to control the first pixel, so I left it at 1. The pinout and digitalwrite stuff in setup() is not necessary - the library does all of that itself. I added a publish message so that I can see a message on OakTerm / Particle console logs indicating the Oak is indeed running the sketch. I also added a second one at the top of the loop so a message is printed every time the loop runs through... but I only did this because there was enough of a delay between runs of the loop - I wouldn't normally do this.

Next, I change the pixel being addressed - with a one pixel strand, 3 isn't really valid - as that is the 4th pixel down ;) The count starts from 0, so 0 is the first pixel. Compiled and ran this, and with the input of the pixel connected to P1 of the Oak, it colour changed as expected.

Now, the catch22 - there is the delay between it displaying blue and white - which is the last colour in the loop, and the first colour. (if these aren't the two colours your Oak is displaying, then the NEO_RGB bit up the top is wrong - it should be NEO_GRB - meaning your pixels get their colour sequence in a different order).

This is happening as you are incrementing the testValue, and so the Oak has to take a moment to check if that variable is being monitored in the cloud, and if so, send the new data. If you comment that line out, the pause will go away ;)

So the trick will be in allowing the delay, but not making it constant (as delay does), as you want to incorporate the time needed to allow for the particle update into the delay.

This may not be the most elegant or well written way to do it, but the substituted pause appears to work... have a look at the code comments and it should be pretty self-explanatory - it basically actively waits for the delay time rather than the normal 'dumb' delay. There may still be the occasional pause between the last line of the loop and the first line or when a delay() is called, which is again related to the wifi/particle stuff. The only way to get rid of that is to shut down the particle connection completely when you need time-sensitive code to run.

I will be interested to know if the Particle.variable works for you... using it that way almost never works for me... if it doesn't let me know, and I'll give you another version of this with the changes.

Code: [Select]
#include <Adafruit_NeoPixel.h>

// Which pin on the Oak is the NeoPixel (or string of) connected to
#define PIN            1

// How many NeoPixels are attached to the Oak -
#define NUMPIXELS      1

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);

int delayval = 500; // delay for half a second
int testValue = 0;

void setup()
{
  Particle.variable("testValue", testValue);
  Particle.publish("oak/userrom/msg","neopixel_test is running",PRIVATE);

  pixels.begin(); // This initializes the NeoPixel library.
  pixels.show(); // Initialize all pixels to 'off'
 
//  pinMode ( 4, INPUT ); //the constructor and begin will set this up as an output, change it back to an input if desired
}

void loop()
{
  // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
  // in Red,Green,Blue order

  pixels.setPixelColor(0, pixels.Color(255, 255, 255)); //white
  pixels.show(); // This sends the updated pixel color to the hardware.
  delay(delayval); // Delay for a period of time (in milliseconds).

  pixels.setPixelColor(0, pixels.Color(0, 255, 255)); //cyan
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(255, 0, 255)); //violet
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(255, 255, 0)); //yellow
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(255, 0, 0)); //red
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(0, 255, 0)); //green
  pixels.show();
  delay(delayval);

  pixels.setPixelColor(0, pixels.Color(0, 0, 255)); //blue
  pixels.show();
 
  testValue = testValue + 1; 

  bool timeNotUp = true;
  unsigned long runtime = millis();

  while (timeNotUp)
  {
   //if the millis counter minus the start time is greater than the delay...
    if (millis() - runtime > delayval)
    {
     //... wait time has elapsed, get out of this busy/idle loop
      timeNotUp = false;
    }
   else
   {
    //still waiting, let the particle cloud stuff do its thing
    Particle.process();
   }
  }
}
« Last Edit: November 20, 2016, 10:35:31 pm by PeterF »

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #8 on: November 20, 2016, 11:45:30 pm »
Pete,

Quote
The GPIO pin remapping stuff must have been fixed at some time - you don't need to work out the ESP8266 -> Oak mapping - pin 1 is pin 1.

I must have an old library or something. I still have to do the remap to get it (your example) to work. That is, if using pin one 1 need to pass GPIO 5 to the constructor, and if pin 5, then GPIO 4.
With those changes for my environment I can confirm that you example works (1 pixel in my case) using both pins 1 and 5, with V supplied by the Oak VCC. Good to see that it works at 3V.

I saw the pixel set 3 in the call to setPixelColor (when only one was defined) and like a dummy I changed it to 1 not realizing it started at zero. I've used Neopixel on other platforms in the past and should have looked at examples for the call syntax.

Now to figure out why I still have to pass the GPIO to Adafruit_NeoPixel when you say it's not necessary.

emardee

  • Full Member
  • ***
  • Posts: 135
Re: Neopixel Issues
« Reply #9 on: November 21, 2016, 01:11:50 am »
I have an Oak operating 2x 5m strips of RGBW Neo pixels (300 pixels per 5m run).

I've interfaced the sketch to Blynk, so I can pick the subtle mood lighting colour using ZeRGBa or R, G, B, W sliders on my phone.

In a different sketch I was dabbling with animations that worked nicely, like fickering fire, or soothing water reflections, but these aren't in the live sketch I'm currently running yet.

I found dropping some yield () commands in helped a lot with that many pixels or it would cause issues.

Ideally I'd use a different library though (can't remember the other ones I looked at, but there were a few promising ones out there that were better set up for animations). Alos ideally I'd use a timer for triggering animations, rather than crude delays, as it allows the Oak to do its particle stuff in the gaps without telling the oak to do a foreground process of counting to 500 or whatever! (at least that is I understand the better way to do it... but don't fully understand, so need to read some more on timers!)

Very much a work in progress at this end... but it works enough for it to be running them as my main lounge lights for the house. Nowhere near the sketch code right now, so can't share them code I'm using right now.


PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Neopixel Issues
« Reply #10 on: November 21, 2016, 02:46:29 am »
lol... in the main, that is all a timer process does - it just checks against the system time, and then once the condition is met (or timer overflows), calls whatever function you configured.  I could have made that look prettier and used the elapsedMillis() library (or FlexiTimer2 but that is probably AVR specific), but didn't want to introduce too much at once ;)

But in the main, regular calls to yield() or Particle.process() and frequent non-blocking delays are the key to minimal flicker, unless you shut down the particle stuff down completely.

Flickering fire? Nice! I have to admit, I am partial to to the strandtest sketch that Adafruit did as the demo sketch for the neopixels... the colour wheel is particularly nice. Then again, I'm easily amused by colour fading leds ;)

@exeng : You updated your board package to 1.0.6 didn't you? Also check when you compile if it says multiple libraries were detected and which one it picked... you might have the 'normal' copy of the neopixel library installed as well and it's picking that? Other than that, I have no idea... I can simply say I compiled it on a linux box and I had a different sketchbook path set so it couldn't see any other of the ardunio libraires, just the oak ones, and using the strandtest sketch, the defined pin 1 was indeed P1 on the Oak...
« Last Edit: November 21, 2016, 02:57:16 am by PeterF »

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #11 on: November 21, 2016, 09:47:49 am »
Pete, I'm still at 1.0.5 and come to think about it I think at some time in the past (can't be sure) I updated from the net to an Adafruit Neopixel library that said it supported the ESP8266. I see that the Oak Core libraries were updated by Erik about 10 months ago. It has an Adafruit Neopixel Oak derivative that the readme says to install manually to replace the Adafruit version via renaming. I wonder if this is what I need? I'll update to 1.0.6 (stable right?).

EDIT UPDATE: Ah... now I see that I do have the Oak derivative Adafruit_Neopixel_Oak library (in 1.0.5) apparently not the one I'm currently using. Didn't know it was there.

ANOTHER EDIT: ??? Using 1.0.6 and the Oak Neopixel derivative "Adafruit_Neopixel_Oak lib renamed to "Adafruit_Neopixel" didn't eliminate the need to do the pin to gpio mapping in the constructor. Puzzled.

AND THE FINAL EDIT: It works. Just needed to do the rename of Adafruit_Neopixel_Oak lib to Adafruit_Neopixel in the 1.0.6 repo. Thought I did but apparently not.
« Last Edit: November 21, 2016, 12:24:06 pm by exeng »

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #12 on: November 21, 2016, 12:29:50 pm »
Here is my test program... It's a modified version of some other Neopixel colorWipe example. I call it BustedStrobe. You'll see why when you run it. As you can see pin 5 is used without having to pass the GPIO equivalent.

Code: [Select]
#include <Adafruit_NeoPixel.h>

#define PIN 5

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);

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

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255,0,0), 200);
  colorWipe(strip.Color(0,0,255), 200);
}

// Fill the dots one after the other with a color
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);
  }
}

PeterF

  • Hero Member
  • *****
  • Posts: 881
Re: Neopixel Issues
« Reply #13 on: November 21, 2016, 03:31:13 pm »
Ouch... I don't think I'll run that one... I can tell already why it's a busted strobe... it was bad enough with the 24 pixel circle going off in my face the other day... I don't need to make it really strobe-y ;)

Yes, 1.0.6 seems to be stable - I believe it was a minor packaging update to fix some issues re Particle Build docker image creation and to include some minor patches - haven't had any new problems arise from it yet. Interesting that you had to rename the folder - mine is still called Adafruit_NeoPixel_Oak (it's the header file that needs to be the correct name for it to be matched), but there is only one copy to be found - I don't have another copy installed in the sketchbook folder or anything, which could be what's happening with yours (hence why I was suggesting to check for a warning about multiple libraries when you compile). Have you ever used NeoPixels with other arduino devices? Meaning you actually have the genuine Adafruit_NeoPixel library installed, not an Oak mod?

It's because of this that I actually have a sketchbook for each major hardware type - Arduino, Digispark/Attiny, Oak/ESP8266, STM32, Teensy, etc... there ends up being hardware specific ports of libraries that much up on the other platform if mistakenly used there.

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Neopixel Issues
« Reply #14 on: November 21, 2016, 03:57:03 pm »
Pete,

Quote
Have you ever used NeoPixels with other arduino devices? Meaning you actually have the genuine Adafruit_NeoPixel library installed, not an Oak mod?

Yes, started running on Arduino UNO, then Digix, probably Digispark, now Oak and a couple of others most likely. Started playing with NeoPixels a few years ago when I acquired and 8x8 matrix and a few 1x8 strips and some raw WS2812B's. Used the official lib, then updated when the ESP8266 support was included and now using the Oak version. And yes, I think another there is an another instance of the NeoPixel lib lying around so who knows which it was using. OK now.