Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am new to C++ I come from a C# background. I am creating an Arduino project using c++ using vs code thanks to
https://docs.platformio.org/
.
The following code works and turns on my led strip:
main.cpp
#include <Arduino.h>
#include <LedStrip.h>
// pin where led strip is connected
#define LED_STIP_PIN 4
// number of leds in the strip
#define LED_STRIP_COUNT 7
// My wrapper class
LedStrip myLedStripWrapper;
void setup() {
// empty
void loop() {
myLedStripWrapper.setup(LED_STRIP_COUNT, LED_STIP_PIN);
// myLedStripWrapper.foo1(); // <<<HERE-1>>>
// wait forever
while (true) {
delay(1);
LedStrip.h
#include <Adafruit_NeoPixel.h>
class LedStrip
public:
Adafruit_NeoPixel strip;
void setup(uint16_t led_count, uint16_t pin)
// Declare our NeoPixel strip object:
Adafruit_NeoPixel a(led_count, pin, NEO_GRB + NEO_KHZ800);
strip = a;
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
foo1(); // <<<HERE-2>>> <------------------- calling foo1 from here turns on the led strip
// Color led strip blue
void foo1()
uint32_t color = strip.Color(0, 0, 100);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{ // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
// delay(100);
Note that in the code I have labels <<<HERE-1>>> and <<<HERE-2>>>. I want to call function foo1 from <<<HERE-1>>>. Why is it that if I uncomment <<<HERE-1>>> and comment <<<HERE-2>>> the code does not work and the LED strip does not turn on? In other words I do not want to call foo1 from within the class wrapper. I am just calling it form there because it only works if I call it form there.
–
–
–
–
The writers of that class made a grade-school C++ mistake and didn't correctly observe the Rule of Three. This means an Adafruit_NeoPixel object can be copied when it is not safe to do so.
void setup(uint16_t led_count, uint16_t pin)
// Declare our NeoPixel strip object:
Adafruit_NeoPixel a(led_count, pin, NEO_GRB + NEO_KHZ800);
strip = a; // copy here. Both a and strip point to a shared resource
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
} // a goes out of scope here and frees the shared resource in its
// destructor. Oops.
The easiest fix is to initialize strip in LedStrip's constructor where it doesn't need to be copied.
To ensure strip isn't copied, you're going to have to prevent LedStrip from being copied or implement special member functions that allow LedStrip to be copied without copying strip. In the example below I will simply prevent copying.
If copying is required consider replacing Adafruit_NeoPixel strip; with std::shared_ptr<Adafruit_NeoPixel> strip; so a pointer will be copied rather than an object that can turn into a bomb when copied.
class LedStrip
public:
Adafruit_NeoPixel strip; // you sure you want this public?
// adding constructor so we don't have to copy a Adafruit_NeoPixel object
LedStrip(uint16_t led_count, uint16_t pin):
strip(led_count, pin, NEO_GRB + NEO_KHZ800) // this is a member initializer list
// It allows us to construct strip
// without having to copy anything.
// more on that later
// INITIALIZE NeoPixel strip
strip.begin();
strip.show();
strip.setBrightness(15);
// preventing copying of LedStrip
LedStrip(const LedStrip& ) = delete;
LedStrip & operator=(const LedStrip& ) = delete;
// note if the compiler doesn't like the = delete, remove it, make
// the copy constructor and assignment operator private, and do not
// implement them
// Color led strip blue
void foo1()
uint32_t color = strip.Color(0, 0, 100);
for (uint16_t i = 0; i < strip.numPixels(); i++)
{ // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
// delay(100);
private:
/* only needed if the = delete trick above doesn't work.
LedStrip(const LedStrip& );
LedStrip & operator=(const LedStrip& );
LedStrip myLedStripWrapper;
becomes
LedStrip myLedStripWrapper(LED_STRIP_COUNT, LED_STIP_PIN);
myLedStripWrapper.setup(LED_STRIP_COUNT, LED_STIP_PIN);
vanishes from the world, never to be seen again.
Documentation on the Member Initializer List.
Documentation on std::shared_ptr
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.