Neo Pixel: Logical fault in my firmware? [Solved]

Does anyone have any idea what I might be doing wrong here? Am I missing some basic understanding of how the neopixels work? Thanks in advance.

Could you explain what your problem actally is?
This way it would be easier to know what we are looking for :wink:

One thing that looks odd is the frequent use of &pink in this part

  Spark.variable("pink", &pink, INT);
  Spark.variable("grey", &pink, INT);
  Spark.variable("orange", &pink, INT);
  Spark.variable("yellow", &pink, INT);
  Spark.variable("cream", &pink, INT);
  Spark.variable("violet", &pink, INT);

Instead of doing this

 //ultimately I'll have an exposed function for each color to change the active color. right now only this one is stubbed in.

I would suggest to have one function and only pass in the color as parameter.

And instead of having multiple “color flags” (state switches) I’d only go for one current_color variable which you set in your Spark.function() and request via a Spark.variable. Additionally you could use the return value of the Spark.function() to report back what the previous color was.

2 Likes

@phoenixperry, it seems @ScruffR never rests! :stuck_out_tongue_winking_eye: Knowing the exact problems would be very helpful :smile:

3 Likes

Thanks everyone! I’m not using those references yet. They are placeholder for now. Ultimately, I’ll call a series of functions like set_light_blue() from open frameworks but for now it’s just stubbed out so I can test the fade actually works between the two colors. Could not having it in be causing chaos? I’ll add it just for the heck of it.

The problem is that function triggerFade() does not do what I want, which is trigger the neopixel to fade colors.

If I set change=1; it runs the else part of that master if statement just fine and it also seems to call the triggerFade() function with no worries. I just don’t get the color fade. If I flip change=0; I get nada!
:frowning:

I would love to do just that! Is there a way to send a function a parameter in the http request? I feel like I’m coding in chains not being able to do that! Either that or can I set a variable with a post request? The documentation only has post for functions and get for variables.

Am I missing something in the cloud documentation? http://docs.spark.io/api/

Any Spark.function() expects a String parameter which you can send via your POST request and use inside the function.

As for you fading problem you seem to do the fading for each pixel too quickly.

1 Like

I noticed that but I didn’t see an example of how to pass it in the documentation. I’m new to http stuff and would love a sample curl request if you have one or just a sample http url. (I normally make games.)

But I don’t understand. Both for loops run and that should change the current color to the new color. Shouldn’t I filp my change off once it’s changed colors?

In the docs
http://docs.spark.io/firmware/#spark-function

You can find this example, where “brew” is the function to call and “coffee” is the string parameter to be passed to it.

# EXAMPLE REQUEST
curl https://api.spark.io/v1/devices/0123456789abcdef/brew -d access_token=123412341234 -d "args=coffee"

Sorry for that. I have edited my post while you were answering :blush:

Try to flip the two loops around (pixel loop inside fade loop).
At the moment your strip should "pan" the color from one end to the other while the transitions (fade) for each single pixel are faster than your eye could possibly see.

Ack - slowing it down did not work. :frowning:
I wonder why… well I just refractored the bugger. I’ll try calling it this way b/c it’s so much cleaner. Thanks for the curl example! https://gist.github.com/phoenixperry/055fbbe723b6e29d640d

It snapped colors really quickly vs fading but the little pixel did change colors. Part sucesss! Woo hoo.

tried this and it just timed out and gave up the ghost on me. I’m going to refer back to the sample code and try and work out why the fade isn’t working.

Two things.

First, it's best to keep the Spark.functions() as light weight as possible, so I'd stick with your first approach to only set the new target color and the fade flag and do the rest in a designated function which is called from loop()

Second, you have to ensure that the firmware allows to do the cloud house keeping at least every 10 sec (better more often). While delay() should allow for this implicitly, last time I looked it only did this if the delay parameter is greater than 1000 (10 calls of delay(1000) will still stall the cloud connection).

As a suggestion remodel your fade function to only do one color step per iteration for all pixels and keep calling this function from within loop() till you got your target color

For example like this

int fadeCount = -1;

const unsigned long softDelay = 100;
unsigned long softDelayCount;

int set_color(String command)
{
  ...
  target = command.toInt();
  fadeCount = 255;
}

void doFading()
{
  // do your magic
  ...
}

void setup()
{
  ...
  softDelayCount = millis();
}

...

void loop()
{
  // this way we spend max time doing some cloud keeping
  if (millis() - softDelayCount < softDelay)
    return;
  else
    softDelayCount = millis();

  if (fadeCount >= 0)
  {
    // do one fading step
    doFading();
    --fadeCount;
  }
  else  
  {
    // stick to this color
    ...
  }
}

If you want to give your own version another shot try what I suggested before


BTW: This is a useful way to store RGB colors. It allows to access the color components individually or have the full color as one integer

struct ARGB_COLOR {
	byte B;  // blue  channel
	byte G;  // green channel
	byte R;  // red   channel
	byte A;  // alpha channel (not used)
};

union COLOR {
	ARGB_COLOR argb;
	unsigned int value;
} color;

   // usage
   color.argb.R = 100;
   color.argb.G =50;
   color.argb.B = 0;

   Serial.println(color.value, HEX);
1 Like

Thanks man! Just googled union type in c and that’s awesome! I’ll take a look at it. This is actually a port of something I did in Java and there I used an enum for the colors for a really similar reason. I have only ever used c++, java, python and c# so I’m new to C and spark. Thanks for the feedback. A better question is can I do enums.? I’ll google it.
This is my java code for the same functionality:

public enum Colors{
	GREEN (94,191,140), 
	YELLOW(252,167,40), 
	BLUE (63,79,233), 
	PINK(239,156,162), 
	RED(224,60,27), 
	BLACK(0,8,21),
	GREY(96,133,147);
	public int r,g,b; 
	private Colors(int r, int g, int b)
	{
		this.r = r; 
		this.g = g; 
		this.b = b; 
	}
}

The delay of 10 seconds is from code from adafruit’s site where they set their fade time to 10ms and spark neopixel sample code is the structure I took for the loop. The sample I am working off is here: https://github.com/technobly/SparkCore-NeoPixel/blob/master/firmware/examples/a-rainbow.cpp

His delay of 20ms works flawlessly. One whole second makes the colors fade too slow I think. You’ll note my loops are in the same order as his, which peform a color fade. I’m going to drink more coffee and wake up a bit more then try it again with a longer delay and some of your suggestions.

Actually no, you didn't and they aren't :wink:

The sample does the color fading in the outside loop and the pixel panning in the inside, you do it the other way round

void rainbow(uint8_t wait) {
  uint16_t i, j;

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

vs.

       for(int16_t i=0; i<strip.numPixels(); i++)  // pixel pan 
       {
          for(int16_t i=0; i< 256; i++)  // color fade
          {
            ...
          }
          strip.show();
        }

One other thing you'd need to change is that you use i for both loops - I wonder why you didn't get an error there.

When you say you know C++, you'll like to hear that you do program the Core with C++ anyhow.
And yes, you can use enums for your colors.
To set your colors, I'd suggest you try HEX notation (e.g 0xFF112233 .. 0xAARRGGBB - alpha is irrelevant, so you could use 00 just as well, but FF stands for 100% opacity), which is practical since each color component is represented by two HEX digits. This way you can easily put your colors in a standard uint enum and guess the color quite easily by just looking at such a number.

omg. Really? How did I not realize that? I just assumed it was arduino C. Exhales. I think it was the i problem. I now feel like a total moron. I switched the loops btw and it did nothing. :frowning: NOW I KNOW WHY. Man, how did that not throw an error? Frankly, programming sans serial sucks - If I could of easily printed my numbers out, it would of been obvious. Do you also find their serial communication lacking to say the least? I’ve got cool term running and there are issues with it and the core. It constantly seems to be able to find my serial port for some reason after I flash my core, which leads to a total restart. It works kinda… not really. (And I really should post a new gist - I did flip them to match that code last night when debugging.)

Here’s my code. It switches verse fading still https://gist.github.com/phoenixperry/045f0b471fa749331e05

PS. Can’t see the added value in making an enum really. It’s such a low amount of code to set a color I don’t think I’ll bother.

I can Serial.print - it’s not lacking for me, you’ve just commented it out in your (previous) code :wink:

If you can’t get CoolTerm to work, have you tried the serial monitor in Spark Dev?
Or have you seen these threads (here and here)?

About the enum - it’s always good to employ good coding practice, even in the smallest of projects :wink:


What behaviour does your current code show?
Could you change your Spark.function to return the color code your fn actually does set and check this value against your expectations?

One possible reason for your lack of fading experience might be this line

  pct = i/255;

Since both parameters of your calculation are integer values, your result will be integer (0 or 1) too - even if the lvalue is a float.
If you change this to

  pct = i / 255.0;
  // or even
  pct = (float)i / 255.0F;  // to be overly cautious 

you might have more luck.

OMG I could cry. How did I not see that? That was it. THANK YOU. Facepalm. That was it. Man.

For anyone who wants a working sample fade of the neopixel code here you go: https://gist.github.com/phoenixperry/7c50b9b6244b60d029fd

The reason my serial is commented off is b/c it is not stable for me. I can sometimes get cool term or the sparkIDE to see my USB port but not always. Usually, I have to unplug all my hardware & restart. I have friends who have this issue too who are on the new macbook pro (asked around - might be a mac vs spark thing). I mean if…if I can get it up the link is not stable. It will drop again.I have no idea why. Also, it truncates the messages. If I get it up again just for legacy I’ll make a little screen cap for the forums. I don’t think it’s the software b/c it does it in both the spark IDE and cool term.

1 Like

HI @phoenixperry

USB 3.0 ports have been problematic for the core for some people. If you can use a USB 2.0 hub between the core and your MBP, you will likely get better results.

2 Likes