Help with LED Matrix Animations on Arduino Uno R4 WiFi Board

Hello everyone,

I'm currently working on a project using the Arduino Uno R4 WiFi board, specifically focusing on utilizing the LED matrix. After reviewing the Arduino documentation, I noticed that the gallery.h file offers a variety of predefined animations, which I'm eager to display on my matrix.

https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix/#frame-gallery

To achieve this, I've written a program intended to cycle through these animations. Unfortunately, I'm encountering an issue where, after running for a while, the program seems to freeze, and the LED matrix starts showing random dots instead of the animations. I added some serial output to debug, but it appears that the code gets stuck and never reaches the "out loop" print statement.

Here's the code snippet I'm working with:

#include "Arduino_LED_Matrix.h"  // Include the LED_Matrix library

ArduinoLEDMatrix matrix;

const size_t num_sequences = 8;
uint32_t (*animation_sequences[])[4] = {
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_STARTUP),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_TETRIS_INTRO),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_ATMEGA),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_WIFI_SEARCH),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_OPENSOURCE),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_SPINNING_COIN),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_TETRIS),
  const_cast<uint32_t (*)[4]>(LEDMATRIX_ANIMATION_WIFI_SEARCH)
};

void setup() {
  Serial.begin(115200);
  matrix.begin();
}

void loop() {
  Serial.println("in loop");
  for (size_t i = 0; i < num_sequences; ++i) {
    matrix.loadSequence(animation_sequences[i]);
    matrix.play(false);
    while (1) {
      if (matrix.sequenceDone() == 1) {
        break;
      }
    }
  }
  Serial.println("out loop");
}

If anyone has experienced similar issues or has suggestions on how to fix this freezing behavior, your input would be greatly appreciated. I'm especially interested in knowing if there could be a problem with how I'm managing the animation loops or a potential memory overflow issue related to handling the animations.

Thank you all in advance for your help and advice!

1 Like

any compiler warning?

1 Like

Thank you for your reply! I am using the default settings of Arduino IDE. The output from Arduino IDE is:

Sketch uses 58120 bytes (22%) of program storage space. Maximum is 262144 bytes.
Global variables use 6900 bytes (21%) of dynamic memory, leaving 25868 bytes for local variables. Maximum is 32768 bytes.

It seems that there are no warnings

can you try defining your array as

constexpr const uint32_t (* animation_sequences[])[4] = {LEDMATRIX_ANIMATION_STARTUP, LEDMATRIX_ANIMATION_TETRIS_INTRO, LEDMATRIX_ANIMATION_ATMEGA, LEDMATRIX_ANIMATION_WIFI_SEARCH}; 

constexpr size_t num_sequences = sizeof animation_sequences / sizeof * animation_sequences;
1 Like

Thank you for your suggestion. I tried, but the situation remains the same.

I had a look in the source code, it only works if you use the exact name of the sequence because they pathetically use a macro...

as they say, it's dangerous (an ugly lazy hack)...

can you try this (I don't have this arduino so can't test)

#include "Arduino_LED_Matrix.h"  // Include the LED_Matrix library
ArduinoLEDMatrix matrix;
struct Animation {
  const uint32_t (*sequence)[4];
  size_t size;
};

Animation animations[] = {
  {LEDMATRIX_ANIMATION_STARTUP,       sizeof LEDMATRIX_ANIMATION_STARTUP},
  {LEDMATRIX_ANIMATION_TETRIS_INTRO,  sizeof LEDMATRIX_ANIMATION_TETRIS_INTRO},
  {LEDMATRIX_ANIMATION_ATMEGA,        sizeof LEDMATRIX_ANIMATION_ATMEGA},
  {LEDMATRIX_ANIMATION_WIFI_SEARCH,   sizeof LEDMATRIX_ANIMATION_WIFI_SEARCH},
  {LEDMATRIX_ANIMATION_OPENSOURCE,    sizeof LEDMATRIX_ANIMATION_OPENSOURCE},
  {LEDMATRIX_ANIMATION_SPINNING_COIN, sizeof LEDMATRIX_ANIMATION_SPINNING_COIN},
  {LEDMATRIX_ANIMATION_TETRIS,        sizeof LEDMATRIX_ANIMATION_TETRIS},
  {LEDMATRIX_ANIMATION_WIFI_SEARCH,   sizeof LEDMATRIX_ANIMATION_WIFI_SEARCH},
};

constexpr size_t animationCount = sizeof animations / sizeof * animations;

void setup() {
  matrix.begin();
  for (size_t i = 0; i < animationCount; ++i) {
    matrix.loadWrapper(animations[i].sequence, animations[i].size);
    matrix.play(false);
    while (! matrix.sequenceDone()) yield();
  }
}

void loop() {}
1 Like

I have just tried it. There was a closing bracket missing in

while (! matrix.sequenceDone() yield();

should be

while (! matrix.sequenceDone()) yield();

With that fixed it works

3 Likes

thanks - typed the code here...

I fixed the typo in the original code

Thank you, Jackson. The Code works. Your contribution has been very helpful!

Also, I'd like to share the code I worked on yesterday since I couldn't enhance the original source code; hence, I opted for a different approach which may not be as elegant.

#include "Arduino_LED_Matrix.h"  

ArduinoLEDMatrix matrix;

template<size_t N>
uint32_t calculateTotalDuration(const uint32_t (&array)[N][4]) {
  uint32_t totalDuration = 0;
  for (size_t i = 0; i < N; i++) {
    totalDuration += array[i][3];
  }
  return totalDuration;
}

template<size_t N>
void handleAnimation(const uint32_t (&animation)[N][4]) {
  matrix.loadSequence(animation);                      // Load the animation sequence
  matrix.play();                                       // Play the animation
  uint32_t total = calculateTotalDuration(animation);  // Calculate total duration
  delay(total + 500);                                  // Delay to allow the animation to complete and add some pause
}

void setup() {
  Serial.begin(115200);
  matrix.begin();
  // handleAnimation(LEDMATRIX_ANIMATION_STARTUP);  // Handle startup animation
}

void loop() {
  handleAnimation(LEDMATRIX_ANIMATION_STARTUP);
  handleAnimation(LEDMATRIX_ANIMATION_TETRIS_INTRO);
  handleAnimation(LEDMATRIX_ANIMATION_ATMEGA);
  handleAnimation(LEDMATRIX_ANIMATION_LED_BLINK_HORIZONTAL);
  handleAnimation(LEDMATRIX_ANIMATION_LED_BLINK_VERTICAL);
  handleAnimation(LEDMATRIX_ANIMATION_ARROWS_COMPASS);
  handleAnimation(LEDMATRIX_ANIMATION_AUDIO_WAVEFORM);
  handleAnimation(LEDMATRIX_ANIMATION_BATTERY);
  handleAnimation(LEDMATRIX_ANIMATION_BOUNCING_BALL);
  handleAnimation(LEDMATRIX_ANIMATION_BUG);
  handleAnimation(LEDMATRIX_ANIMATION_CHECK);
  handleAnimation(LEDMATRIX_ANIMATION_CLOUD);
  handleAnimation(LEDMATRIX_ANIMATION_DOWNLOAD);
  handleAnimation(LEDMATRIX_ANIMATION_DVD);
  handleAnimation(LEDMATRIX_ANIMATION_HEARTBEAT_LINE);
  handleAnimation(LEDMATRIX_ANIMATION_INFINITY_LOOP_LOADER);
  handleAnimation(LEDMATRIX_ANIMATION_LOAD_CLOCK);
  handleAnimation(LEDMATRIX_ANIMATION_LOAD);
  handleAnimation(LEDMATRIX_ANIMATION_LOCK);
  handleAnimation(LEDMATRIX_ANIMATION_NOTIFICATION);
  handleAnimation(LEDMATRIX_ANIMATION_OPENSOURCE);
  handleAnimation(LEDMATRIX_ANIMATION_SPINNING_COIN);
  handleAnimation(LEDMATRIX_ANIMATION_TETRIS);
  handleAnimation(LEDMATRIX_ANIMATION_WIFI_SEARCH);
}

1 Like