Ye gods I detest* C++ syntax.
I’m trying a simple “frame first” approach (see Google Workspace Updates: New community features for Google Chat and an update on Currents); I want to do it all in the Arduino IDE because nothing else seems to be able to upload to the DFRobot Beetle I’m running it on.
Can anybody help me with the Magic Syntax to make this work. Here’s what I’ve got:
#include <FastLED.h>
#include “FrameEffect.cpp”
#include “RainbowFrameEffect.cpp”
const uint16_t NUM_LEDS = 180;
const uint8_t DATA_PIN = 9;
CRGB leds[NUM_LEDS];
uint8_t frameNumber = 0;
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
RainbowFrameEffect rainbow(leds, NUM_LEDS);
FrameEffect *effects = {
&rainbow,
NULL
};
}
void loop() {
int effectIndex = 0;
while (effects[effectIndex] != NULL) {
effects[effectIndex++]->draw(frameNumber++);
}
}
This gives me “effects was not declared in this scope”. Fair, it goes out of scope at the end of setup(). How do I declare it outside of setup() without having to also explicitly declare the number of items in the array?
(* Where “detest” == don’t understand.)
I’m a noob so I apologize in advance if I give you wrong advice. Thought you were to #include only .h files; not .cpp. Yes, I hate learning C++ myself.
Move the declaration of effects[] outside of the setup function; make it it’s own top-level thing and that turns it into a global, available from inside every function.
For more examples try googling “declare a global array in C”-- much has been written on the subject.
You’ll have to move the declaration of rainbow, too, so it’s also “visible” to the I initialization of effects[].
And yeah… There may later be complicating issues around including the cpp. But really, #include is the simplest to understand of all this: it literally just inserts the contents of the named file at that point in your code.
Brilliant, thanks +Mark. I was thrown by Daniel’s original example new-ing the effect classes, the Arduino environment doesn’t let you have new—and what is “global” (and what that means) is confused by whatever Arduino does with its makefile. Working now:
#include <FastLED.h>
#include “FrameEffect.cpp”
#include “RainbowFrameEffect.cpp”
const uint16_t NUM_LEDS = 180;
const uint8_t DATA_PIN = 9;
CRGB leds[NUM_LEDS];
uint8_t frameNumber = 0;
RainbowFrameEffect rainbow(leds, NUM_LEDS);
FrameEffect *effects = {
&rainbow,
NULL
};
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
}
void loop() {
int effectIndex = 0;
while (effects[effectIndex] != NULL) {
effects[effectIndex++]->draw(frameNumber++);
}
LEDS.show();
}
I have a question: wouldn’t it be better to change const uint8_t DATA_PIN = 9; to (#define DATA_PIN = 9;) ?
Are there advantages to one over the other? I have always used the (#define) to declare my LED pins.
It’s either/or in this context.
#define tells the C/C++ preprocessor to make a textual substitution for the defined value, before the code is compiled. Kind of like search-and-replace. Declaring a const tells the compiler “here’s a variable, it’s of this particular type, and its value is this, which will never change.”
In the small amount of code typical of a FastLED sketch, there’s not much to choose between them. With a larger codebase being worked on by many people, you can make a case to prefer the const as it might prevent mistakes where you try and plug (say) a float into a function parameter that’s meant to take an int. This is hard(er) for the compiler to catch if you use #define. And it can get more complex than that.