adafruit / Adafruit_CircuitPython_LED_Animation

CircuitPython helper library for LED colors and animations
MIT License
53 stars 43 forks source link

Adafruit sparkle animation broken on RP2040, but RainbowSparkle and SparklePulse work? #112

Open GithubUser99999999 opened 1 year ago

GithubUser99999999 commented 1 year ago

sparkle = Sparkle(pixels, speed=0.05, color=AMBER, num_sparkles=10)

This code should look like this (code and video taken from the adafruit guide):

https://user-images.githubusercontent.com/101017273/220235696-7bfdf958-84ca-4982-ad35-4bb50bd12839.mp4

But it does actually look like this:

https://user-images.githubusercontent.com/101017273/220235797-7f151fe9-4d0e-416b-8df5-ded4ece417f8.mp4

However, the rainbowsparkle.mpy animation does indeed work (with the same code):

https://user-images.githubusercontent.com/101017273/220235979-aa422634-d5fa-4db8-9359-5fd1cf343ed2.mp4

Tested with CircuitPython 8 on a PICO RP2040

Is this animation currently broken?

GithubUser99999999 commented 1 year ago

Tested on a Gemma M0 with the same result:

https://user-images.githubusercontent.com/101017273/222038523-bbecdf56-fb6a-456b-a51c-da63d532403c.mp4

It only has enough memory to run the standard Sparkle animation, but not SparklePulse or RainbowSparkle to show the difference.

(I tried an ItsyBitsy RP2040 too, same result and Sparkle doesn't work, but SparklePulse and RainbowSparkle do work.)

GithubUser99999999 commented 3 weeks ago

almost 1,5 years later with CircuitPython 9.1.1 and the latest libraries this bug is still not fixed

GithubUser99999999 commented 3 weeks ago

SparklePulse seems to just call Sparkle and Pulse and for some reason it works.

https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation/blob/main/adafruit_led_animation/animation/sparklepulse.py

If I could disable the pulsing, it would work.

https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation/blob/main/adafruit_led_animation/animation/sparkle.py

Or there is some bug I don't recognise in here.

dhalbert commented 3 weeks ago

@GithubUser99999999 Just checking, are you the same person as https://forums.adafruit.com/viewtopic.php?p=1025640#p1025640 ?

GithubUser99999999 commented 3 weeks ago

Hello Dan, yes I also linked the videos from here. I can also provide more if needed.

dhalbert commented 3 weeks ago

After testing Sparkle, Pulse, and SparklePulse, I think the problem here is that the videos in the guide on that page are mislabeled. The Sparkle effect at the very top of the page is what you should expect sparkle to look like: very quick random transitions. The animation labeled as Sparkle is really SparklePulse. And the animation labeled as SparklePulse is something else, maybe just an adjusted SparklePulse.

In other words, it's a bug in the Guide, not a code bug.

GithubUser99999999 commented 3 weeks ago

Aaaaaah okay. I never would've figured that out ^^ Thanks for that.

Do you perchance have an idea of how to use the RainbowSparkle library/code with just one single colour then?

The sparkling of SparklePulse and RainbowSparkle is perfect, but not that of Sparkle, that's just flickering.

I don't seem to be able to create any animation like the one in the gif from the guide at all. The guide gif also is simply not pulsing, it's just sparkling with one single colour.

dhalbert commented 3 weeks ago

I don't seem to be able to create any animation like the one in the gif from the guide at all. The guide gif also is simply not pulsing, it's just sparkling with one single colour.

Just to be clear, which one do you mean?

GithubUser99999999 commented 3 weeks ago

https://cdn-learn.adafruit.com/assets/assets/000/091/421/original/leds_LED_Anim_Sparkle.gif?1590196528

A non-pulsing single-colour sparkle animation like this. RainbowSparkle works fine, if only I knew how to change the code so that it outputs just one colour.

https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation/blob/main/adafruit_led_animation/animation/rainbowsparkle.py

dhalbert commented 3 weeks ago

I tried making a new video of the Sparkle effect and did not succeed in a faithful representation. I think the video in the guide may indeed be Sparkle, but because of video aliasing effects, it does not show up well and looks slower than in real life. The video at the top of that page is the best representation of Sparkle. I've added a warning to the guide about that video.

I also tried some simple modifications to the example code to force a monochromatic RainbowSparkle, but it wasn't possible because of the way the code is structured. The "rainbow" feature made it not possible to specify the individual color. If you change the initialization to

sparkle_pulse = SparklePulse(pixels, speed=0.05, period=3, color=JADE, step=256)

you will get a monochromatic red SparklePulse, but changing the initial color away from red requires modifications to both Rainbow and RainbowSparkle, or really, a thorough restructuring. I encourage you to study the current animation classes and experiment with modifying them.

GithubUser99999999 commented 3 weeks ago

I am using this as a sparkly replacement now even though it's not as random.

sparkle = Chase(pixel_spiral[0], speed=0.2, color=COLOUR, size=4, spacing=8)

https://github.com/user-attachments/assets/b4717919-a6d7-45c3-b8d0-c5c5ec1c3b31

I would need white for this for example with yellow PLA. Thanks for your help anyway!

Maybe I will be good enough to understand how the rainbowsparkle code actually works in-depth in order to be able to modify it for single colour use.

dhalbert commented 3 weeks ago

I am going to close this for now as it is not a bug in the library, but was more of a Learn Guide documentation problem. Feel free to continue posting.

DJDevon3 commented 3 weeks ago

Please take a look at my proposed fix. There does seem to be an issue with the way sparkle behaves by itself when not used with pulse.

Only file edited was adafruit_led_animation/animation/sparkle.py from this

# before
def _set_color(self, color):
        half_color = tuple(color[rgb] // 4 for rgb in range(len(color)))
        dim_color = tuple(color[rgb] // 10 for rgb in range(len(color)))

to this

# after
def _set_color(self, color):
        half_color = tuple(color[rgb] // 64 for rgb in range(len(color)))
        dim_color = tuple(color[rgb] // 16 for rgb in range(len(color)))

https://github.com/user-attachments/assets/a64a8c4d-5ec3-49a4-be76-6ccb5258ecb4

I don't know if changing the divisor values might have unintended consequences for other scripts using sparkle so please take my changes with a grain of salt. They might work well for this script but not be good for others.

I'd like to propose those divisor values become configurable. Some people might want the half color & dim color in their animation and others might want single color sparkle with no background color. Either that or a create a single_sparkle.py so it will have its own helper?

I hope this is what OP wanted and I haven't completely misunderstood the assignment?

GithubUser99999999 commented 3 weeks ago

It's going in the right direction but not quite. Here are some videos:

original Adafruit Sparkle animation (speed=0.05, color=WHITE, num_sparkles=1, brightness=1) https://github.com/user-attachments/assets/6ad0a996-ad5b-44b0-b896-eb8eba48bb39 -> doesn't sparkle at all, just flickering as if broken

your edited Sparkle animation (speed=0.05, color=WHITE, num_sparkles=1, brightness=1) https://github.com/user-attachments/assets/6fa3c5ab-4d5f-43aa-8a3c-e14357c9ba92 -> it does actually sparkle, but it's still very fast and also very dark

here as an example the Adafruit RainbowSparkle animation with Step=255 to show only RED (speed=0.05, num_sparkles=10, brightness=1) https://github.com/user-attachments/assets/ea0b7506-4f16-4149-84f7-b0891b021b89 -> very bright single colour sparkling

DJDevon3 commented 3 weeks ago

Seems like what you want isn't a single sparkle but sparkle pulse. remove the import for sparkle and remove it from the animation sequence. change the animation sequence to use sparkle pulse.

sparkle_pulse = SparklePulse(pixels, speed=0.08, period=1, color=RED)

animations = AnimationSequence(
    sparkle_pulse,
    auto_clear=True,
)

customize the speed (in seconds) where 0.05 is very fast and 1.0 is slow.

You can set the library back to the original library file where half_color is //4 and dim_color is //10.

When you add sparkle on top of sparkle pulse that's when it will do the fast blips. sparkle pulse by itself is a slower fading using PWM. This issue seems to be more of an animation settings issue than a library issue.

GithubUser99999999 commented 2 weeks ago

SparklePulse basically doesn't work because I cannot indicate how many pixels are supposed to be sparkling. With about 40 LEDs, it's almost invisible and almost nothing sparkles at all, no matter how fast or slow it is.

If I add Sparkle to this, it's just flickering again, and obviously I am aware about the speed variable, but that just changes how fast it's flickering. Flickering = abrupt changes in brightness of all or most LEDs instead of what this animation is supposed to do.

The only animation that actually works fine and sparkles is RainbowSparkle, but it cannot be forced to just use one colour apparently.