Add bounce effect to LED code; Add random repeat

Wow thank you so much for your suggestions!

I really had no idea where to start, but now I know where to focus my attention. I'm following your suggestions, and am also going through the Arduino tutorial to start building my Arduino coding vocabulary. It seems knowing about functions is key for my task. Thank you, now I have a fighting chance to achieve this by the 31st =D

Welcome

It will be hard to achieve what you want with the actual code, as everything is done with strange loops and delays

Here is an example on wokwi : meteor.ino - Wokwi Arduino Simulator

It looks more complex, but it's not using delays and in my opinion it's easier to understand and modify. You could even make it run multiple meteors at the same time.

2 Likes

OMG this is so amazing! The kids are going to absolutely flip when they see this LED effect emerging from the ground! Thank you so much!

I'm definitely studying this code. I think some of it is already making sense. Particularly the InvertDirection part and the "if" "else" parts. I'm going to continue studying both sketches (both seem to have their own advantages and disadvantages) and use this as an opportunity to really start absorbing how Arduino code works. This is gunna be so great, eeee!

Also, funnily, I was just looking for an Arduino simulator. How perfect that you pointed me to one. Yay!

Just thought I'd give an update for future readers: (If some of my numbers are off, please let me know!)

The Digispark ATTINY85 boards arrived. I tried the new Meteor Rain code, and nothing happened. The boards definitely work, because the "Start" example code successfully blinked an LED. After doing some sleuthing, I discovered that the Digispark boards are limited by only 512 bytes of SRAM, meaning it can only reliably handle about 85 RGB addressable LEDs (even worse for WRGB addressable LEDs, I assume). Each addressable LED consumes 3 bytes of SRAM, so 144 LEDs would need 432 bytes of SRAM, leaving not nearly enough for the programming to run, which caused the Digispark to just sit there and do nothing. So my LED strip of 144 LEDs is too much for the Digispark to handle. I was so worried that the code had to be specially tailored for the stripped down nature of the Digispark, but thankfully not.

Ultimately, because I'd like to use all 144 LEDs on each strip, I've purchased some Arduino Nanos. The 2k of SRAM should be enough, I hope. So far so good, more or less.

The two sources that lead me to my conclusion:

Okay so, another issue cropped up (hopefully the last one). The LED animation slows way down if I use the full length (144 LEDs) of the LED strip, even with my MEGA 2560 supplied with 9 volts. The animation only speeds up to what I need when I reduce the LEDs to around 55 LEDs, even after configuring the existing code to animate the LEDs at maximum speed. From what I've read, the two main causes are:

  1. The 800 KHz Kbs data speed limitation, and method of communication of the addressable LEDs cause the animation to slow directly proportionally to the number of LEDs in play

  2. Efficiencies of the code

The best explanation I found for the code efficiency impacting animation speed is way over my head, but maybe someone can help

// Thank you guix!

#include "FastLED.h"
#define NUM_LEDS 144 
CRGB leds[NUM_LEDS];
#define PIN 6

void setup()
{
  FastLED.addLeds<WS2813, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  Serial.begin(115200);
}

void loop()
{
  meteorRain( CRGB(255, 255, 255), 5, 50, 5 );
}

void meteorRain( CRGB color, uint8_t size, uint8_t decayAmount, uint8_t speed )  
{
  uint32_t now = millis();
  static uint32_t past = now;

  if ( now - past >= speed )
  {
    past = now;

    static int16_t pos = 0;
    static bool invertDirection = false;

    if ( invertDirection == false )
    {
      if ( pos >= size )
      {
        for ( int16_t i = 0; i <= pos - size; i++ )
        {
          decay( i, decayAmount );
        }
      }

      if ( pos < NUM_LEDS + size - 1 )
      {
        if ( pos < NUM_LEDS )
        {
          leds[pos] = color;

          for ( int16_t i = pos + 1; i < NUM_LEDS; i++ )
          {
            decay( i, decayAmount );
          }
        }
        pos++;
      }
      else
      {
        pos = NUM_LEDS - 1;
        invertDirection = true;
      }
    }

    else
    {
      if ( pos < NUM_LEDS - size )
      {
        for ( int16_t i = pos + size; i < NUM_LEDS; i++ )
        {
          decay( i, decayAmount );
        }
      }

      if ( pos > -size )
      {
        if ( pos >= 0 )
        {
          leds[pos] = color;

          for ( int16_t i = 0; i < pos; i++ )
          {
            decay( i, decayAmount );
          }
        }
        pos--;
      }
      else
      {
        static uint32_t past = 0;
        static uint32_t restart = 0;

        if ( past == 0 )
        {
          past = now;
          restart = random( 2000, 15000 );
          Serial.print( "Restarting in ");
          Serial.print( restart );
          Serial.println( " ms" );
        }

        if ( now - past >= restart )
        {
          past = 0;
          pos = 0;
          invertDirection = false;
        }
      }
    }

    FastLED.show();
  }
}

void decay( uint16_t id, uint8_t value )
{
  if ( 0 )
  {
    leds[id] = CRGB::Black;
  }
  else if ( random( 2 ) )
  {
    leds[id].fadeToBlackBy( value );
  }
}

Maybe you can cut the 144 LEDs strip into 2, 3 or 4 strips, each strip having their own data pin FastLED/MultipleStripsInOneArray.ino at master · FastLED/FastLED · GitHub

There are other, much faster (and more expensive) adressable LEDs like APA102, HD107..

1 Like

Wow you were right! That works! Dividing the data signal among multiple strips speeds the animation way up! Perfect! OMG this is so great. There's a lot of soldering in my future...

I was wondering if something like that was possible, but I just don't yet have the vocabulary to properly search for that. I wouldn't have thought of including "Array" in my search. You saved the day, again!

After removing the void loop () in the multiple strips code, the sketch functions perfectly!

Also, holy cats! You weren't kidding about the faster LEDs being more expensive. Double the cost, at least. But I'll keep those faster LEDs in mind for my future purchases.

Thank you so much! I'm going to post pics later so you can see what you helped bring to life.

1 Like

I wasn't sure, and my calculation was probably wrong... Glad that it helped :slight_smile:

if RAM becomes a problem again
maybe the Seeeduino XIAO 48 Mhz, 32bit, 256KB Flash,32KB SRAM

is a solution

You can use them just like any arduino. I would recommend to attach a reset-button. Sometimes while uploading I experienced the XIAO to hang not responding.
And then a reset will make him respond again.

best regards Stefan

Holy moly that’s a powerful little board! Okay I’ll keep that in mind, thank you!

The main problem with the seeeduino thing is…

All the I/O pins are 3.3V, please do not input more than 3.3V, otherwise, the CPU may be damaged.

so for your smart pixels, you’d need to do a level translation on the logic line that drives them.

It is a darling and powerful little board. Impossibly inexpensive as well.

a7

Finally a use for my level shifters! :grinning_face_with_smiling_eyes:

1 Like

Well, looks like I'll be trying out a M0 board like the Seeeduino XIAO, after all.

When I further tested the signal splitting code configured for three LED strips, and 48 LEDs each LED strip, the animation slowed down to the same speed as if I were sending the signal to just one LED strip of 144 LEDs. So it seems the speed bottle neck for my animation isn't the LED data speed, but the ATMEGA 2560 data speed. Beans.

Sending 4 sets of 36 LEDs sequentially is no faster than sending 144 LEDs. If you look at the docs for the multiple strips example, they talk about it.

Performance - (NOT YET, but coming) - if you could write out 8 strips in parallel, about...

Ah okay, so dividing up the data signal yields zero improvement in speed (when the LED data speed isn't maxed out?). Sorry, but what docs? I don't see any performance discussions.

I remembered I have a (possibly damaged) spare Feather M4 Express board in storage, so I got that out and tried the code. Sure enough, the M4 board animates the LEDs fast enough (just barely), and at the same speed regardless of if I send the data to one 144 LED strip, or three 48 LED strips. I guess the LED data rate isn't an issue in this case.

I'm not sure which attribute of the M4 board is allowing my animation to run at high speed, which confounds my decision on getting an M0 board or an M4 board. But I have a feeling that if the animation is running just fast enough, the M4 is the bare minimum for this animation on this many LEDs. Ugh :weary: I'll have to save up to get enough of those boards, and just use the slower boards this year.

If a higher price is OK you could use a Teensy 4.0
Teensy 4.0 ARM Cortex-M7 at 600 MHz

not much bigger than a XIAO but much more RAM and more calculation-speed
https://www.pjrc.com/store/teensy40_pins.html
The teensy is really fast I guess the maximum bitbanging speed of the teensy is higher than the maximum busspeed of the LEDs. This means dividing the 144 LEDs in 3 or 4 parallel parts that get served on different IO-pins should make it faster.

The concept of using multiple IO-pins will speed up with any microcontroller.
But I don't know if there is a variant of fastled that can do this.

And there is some overhead for manageing how to move the "switched-on"-LEDs through a shared pattern-buffer

best regards Stefan

As previously mentioned, you can use a SPI-based LED Strip such as APA012 (aka Adafruit DotStar). I've clocked those at 20MHz.

Okay that Teensy 4.0 M7 is so powerful! I love it!

For now, I went with a bunch of ItsyBitsy M4 Express boards to get the job done well enough this time around. I might even try overclocking them a little. But LED strips are only going to get more dense in the future, so I'll have to start investing in M7 boards like the Teensy 4.0 M7 you suggested

Those DotStar LEDs look amazing. I can't wait to try those, eventually, but I've got to make due with the ones I already purchased, for now.

OMG the final product worked so well! It looks just as amazing as I imagined. I'm so happy!!! I'm actually hesitant to take it down post Halloween, lol. Thank you everyone so much!

Everyone thought the spooky ghost sprites were so cool! Trick-or-treaters and parents alike were commenting on them all night. Several even asked where I bought them!

Thank you everyone for helping to make Halloween extra special for the kids, this year!

As promised, here is some video of the final product in action:

1 Like