Today brought to you by a rubber mallet swinging at my head … trying to convert all of my light patterns into classes so it’s easier managing multiple strings on the same AVR. Not having fun. It would make the hardware so much easier, but at the cost of losing my mind. Urgh.
I think the rubber mallet might have missed your head and hit mine. If anyone finds a missing mind, please send it home to me. 
Meh, I gave up for now … I actually have a headache. Decided to do some cleaning and reorganizing of all the electronics bits and what not that I have.
If you happen to find my mind hiding in your stuff, please send it home…
A noble, if quixotic, mission!
What basic interface are you using for each animation? I recently did a small bunch of animations that were all basically “loop lite”: they drew one frame into a specified pixel buffer and returned. The outer control code dealt with calling show(), delay() if needed, etc:
void anim42( CRGB* pixels, int numPix);
Note: not a proper class, just a global function 
The two other things that I added to the argument list were a “seconds until you’re done” countdown, so the animation could ‘finish’ if it wanted, and an alpha blending parameter.
void anim42( CRGB* pixels, int numPix, int secsLeft, fract8 alpha);
So without getting into the pros (many!) and cons (few!) of using a proper class, what parameters are you passing in to your animation functions? And is “the loop” inside them our outside them? Just curious what other people are up to.
This is going to be long. Consider that I know not how to write classes (or proper C and family for that matter), I ended up stopping after a few hours to clean my office instead. I started getting a headache from all the reading I was doing and trying out different things with my existing code. So in the end, the ‘basic interface’ became the ‘failure method’ … Today’s another day, but now I have an office in complete disarray and it desperately needs to be cleaned up before I can do anything useful or functional in it … or before my daughter gets home tomorrow and lynches me.
However, having said that, the existing code runs something like this:
All the animations are declared as functions. All of the related variables for those animations are declared at the top of the main program (this, I understand, won’t work for classes.) The main loop() does two things:
- listen for I2C data (which is a number)
- pass that number down to a secondary function
The secondary function, callAnimation(), is a switch function that takes that number passed to it and calls the appropriate animation. For example:
case 0: snowFlake(); break;
case 1: candyCane(); break;
etc., etc.
Each animation function is responsible for its own ‘pause’ in the sense that, while the loop() (and callPattern()) are constantly called (at 16MHz), the actual animation itself has a test in place to determine whether it’s time to update the string or not. Standard millis() check:
if (millis() - lastRun > pause) { … }
That ‘pause’ is set by each animation when they are first called each time. Some set it to 50ms, others to 10ms, it just depends what the animation is doing.
Illustrated, you’re looking at:
#includ <FastSPI_LED.h>
#includ <Wire.h>
// variable definitions for each animation
void setup() {
// setup FastLED
// setup Wire
}
void loop() {
// check for Wire data
if (Wire data has changed) {
// this turns off the string in preparation
// for the next animation
resetString();
}
callAnimation(Wire data);
}
void callAnimation(ani) {
switch (ani) {
case 0: snowFlake(); break;
case 1: jumpUp(); break;
…
}
}
void snowFlake() {
if (millis() - lastRun > pause) {
// update the string, one step
lastRun = millis();
}
}
void jumpUp() {
if (millis() - lastRun > pause) {
// update the string, one step
lastRun = millis();
}
}
So each time the snowFlake() function gets called, it updates the string, one step at a time. So a pixel that travels from one end to the other on a 32 pixel string, will take 32 calls to snowFlake() to complete its travel (and likely several hundreds/thousands of call to callAnimation() to actually accomplish that once you factor in the ‘pause’ inside of snowFlake().
This works great for a single string. But for multiple strings on the same AVR … not so well. So that’s where I’m at. I want to be able to define more strings on an AVR (say leds1, leds2, ledsN) and have each one run independent from the other and display the same animation (with different values for its variables.) Taking the snowFlake() example, each falling flake changes in speed, brightness, and a random length pause between each flake. You can see all of animations in the clip I posted last year (go to the 2 minute mark to see the ‘snowFlake()’ effect, or the 3 minute mark for the ‘jumpUp()’ effect - they’re 30 seconds long):
Ten AVRs running a single string each … This year I want to, at the very least, double that string count, but not necessarily the AVR count. ![]()
Told you it was going to be long. ![]()
Thanks for sharing the video as well as the code ideas. @Peter_Chestna : you getting ideas?
Yep yep. Daniel sent me a modified piece of code for the snowFlake() portion some time ago but I’ve never been able to get it to work (complains about undeclared controllers) and I myself got busy after that and wasn’t able to do anything with it. Now I’m trying to update everything to use classes instead to make it easier to use multiple strings … Unsure if I’ll actually accomplish that. I have a parade coming up next weekend, concert a week after that, and by then the installation needs to be up. So yeah … Serious doubts.
@Mark_Kriegsman : For sure.