These are the answers to some frequently asked questions regarding the CircuitPython LED Animation library.

Does the LED Animation library run on the SAMD21 microcontroller?

Technically, yes.

However, the entire library does not fit on SAMD21 non-Express boards. Any SAMD21-based microcontroller that does not have external flash available is considered a SAMD21 non-Express board, such as Trinket or NeoTrinkey. If you want to run LED Animations on SAMD21 non-Express boards, you must load only the parts of the library you intend to use.

Further, due to the memory limitations of the SAMD21, it is not possible to run all of the animations available in the LED Animation library. The following animations will not run:

  • rainbow_sparkle
  • sparkle_pulse

All animations not listed above will work standalone on the SAMD21.

It is not possible to run a significant number of animations together in sequence. Simpler animations can be run together. For example, you can use AnimationSequence to run blink and chase together in sequence. Adding more animations to the sequence, or adding more complicated animations to the sequence may fail. If you intend to run multiple animations, consider using a SAMD51 based microcontroller board or similar.

Animation groups do not run on the SAMD21.

On a SAMD21 non-Express board, why does my animation slow down if I leave it running for a while?

The LED Animation library uses time.monotonic() for animation timing. This allows for the animations to be non-blocking, meaning you are able to do other things in your code while animating your LEDs. See this link for more details - but, basically, at any given point in time, time.monotonic() is equal to the number seconds since your board was last power-cycled. (The soft-reboot that occurs with the auto-reload when you save changes to your CircuitPython code, or enter and exit the REPL, does not start it over.)

Due to the limitations of CircuitPython on a SAMD21 (M0) non-Express microcontroller board, the time.monotonic() value begins to lose accuracy after about an hour (1.165 hours to be exact) has passed. It is like a clock that functions initially, but after running for an hour, only ticks every two seconds in two second intervals, and after another two hours, ticks every four seconds in four second intervals, and so on. Using this device to keep track of time in seconds would be quite frustrating! You can hard-reset the board manually to resolve this - but you would have to do this each time it reaches the loss of accuracy to keep your animation running properly. It is simpler to reset your board using code.

This example uses CircuitPython to reset the board every time an hour passes since the last time the board was power-cycled. Save the following as to your CIRCUITPY drive:

# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries
# SPDX-License-Identifier: MIT

This example shows how to reset the microcontroller to avoid the animation slowing down over time
due to the limitations of CircuitPython for the SAMD21 (M0) microcontroller. The example
animates a purple comet that bounces from end to end of the strip, and resets the board if the
specified amount of time has passed since the board was last reset.

See this FAQ for details:

For QT Py Haxpress and a NeoPixel strip. Update pixel_pin and pixel_num to match your wiring if
using a different board or form of NeoPixels.

This example will run on SAMD21 (M0) Express boards (such as Circuit Playground Express or QT Py
Haxpress), but not on SAMD21 non-Express boards (such as QT Py or Trinket).
import time
import microcontroller
import board
import neopixel

from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.color import PURPLE

# Update to match the pin connected to your NeoPixels
pixel_pin = board.A3
# Update to match the number of NeoPixels you have connected
pixel_num = 30

pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.5, auto_write=False)

comet = Comet(pixels, speed=0.02, color=PURPLE, tail_length=10, bounce=True)

while True:

    if time.monotonic() > 3600:  # After an hour passes, reset the board.
        microcontroller.reset()  # pylint: disable=no-member

The relevant parts of this example are:

import time
import microcontroller

while True:
    if time.monotonic() > 3600:

The code above checks the value of time.monotonic(), and when it is greater than 3600 seconds, it resets the board. That's it! Include this with your animation code to keep your animations running at the speed you expect.

This guide was first published on May 27, 2020. It was last updated on Jul 15, 2024.

This page (FAQs) was last updated on Jul 15, 2024.

Text editor powered by tinymce.