SOS (hard fault) with tweaks to NeoPixel example

Let’s start with the code. Pretty simple stuff: https://gist.github.com/pennig/003a0c7d46ae88d54b35

I’ve got a strip of NeoPixels, and I don’t want to have to refer to the global variable when calling out to it, as I’m intending to add 3 separate strips to my project, and need to refer to them individually.

I took the basic rainbow example code, and plumbed parameters through the functions, and I’m now getting a hard fault (SOS with 1 flash). Sometimes the first LED will light up just before the fault occurs.

How would I go about debugging this further? So far as I can tell, there’s nothing wrong with my code, but I admit I am not well versed on the intricacies of C++, so it could be something silly I’m missing.

I could be mistaken, but shouldn’t this work?

Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(11, D2, PIXEL_TYPE);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(11, D3, PIXEL_TYPE);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(11, D4, PIXEL_TYPE);

In a separate test, that seemed to work fine. But my issue isn’t in creating multiple strip objects, it’s (ostensibly) in creating generalized functions that can make changes to any strip. Is it possible to learn exactly what is causing the hard fault? I’m totally in the dark otherwise.

The very basic debugging steps would be to scatter some Serial.print() statements all over your code to pin down the offending instruction and possibly also some parameters.
Once you found the instruction you can have a look out for buffer, stack, heap violations (most common cause for SOS +1).

BTW: I’d suggest to use this way to instantiate an object

Adafruit_NeoPixel strip(11, D2, PIXEL_TYPE);

The use of the assignment operator causes two objects to be instantiated (first strip() with the default constructor and second the actually desired object which will subsequently replace the default object).

1 Like

@pennig, after having said the above and finally having a look at your code, I now see your “mistake”.

You can’t just pass around objects by value (similar reason as above), which you’d do with your two functions.
But if you use references instead, the code should work

void rainbow(Adafruit_NeoPixel&, uint8_t);
uint32_t Wheel(Adafruit_NeoPixel&, byte);

Alternatively you could always pass the object pointer (which especially C puritsts prefer :wink: )

Thank you very much, @ScruffR! This is purely my ignorance of C++ at work then. Since strip wasn’t instantiated as a Adafruit_NeoPixel *, I figured it was implicitly treated like a pointer, and not passed around as a value.

If you want to instantiate an object and assign it to an “object pointer”, you’d do it this way

Adafruit_NeoPixel *strip = new Adafruit_NeoPixel(11, D2, PIXEL_TYPE);