Teensy 4.1 with 64x16 APA104 LED Matrix flashing regularly but not constantly

Status
Not open for further replies.

ksmth

Member
Hey everyone!

As the title already tells you, I'm having a bit of trouble figuring out what's wrong with my little project. I've tried searching this forum and googling, but apart from the general recommendations "use a capacitor and resistor", I haven't had much luck. Most problems I've seen are about constant flickering or other problems that appear to be the same as the one I'm experiencing. I'm also not sure whether this forum or the Project Guidance forum is best suited for this question, but since I am in fact using a Teensy 4.1 for this, I thought it'd be best put here.

Hardware used:
  • Teensy 4.1
  • Level Shifter
  • 1000µF Capacitor
  • 300 Watts Power Supply
  • 4 x 16x16 APA104 Matrix

Here's a wiring diagram:
View attachment 24027

It's a Teensy 3.1 in the diagram, but I'm using a Teensy 4.1. I'm using PIN 6 as the output to the APA104 matrix. The whole 16x64 matrix consists of four 16x16 matrices.

The issue I'm experiencing is that roughly once every minute the panel flashes. I measured voltage across all the LED panels inputs, but it's the same everywhere, so I've ruled out a significant drop. I've tried inserting a 470Ω resistor between the level shifter and the LED panel, but then the LED panel didn't light up at all anymore. I've contemplated using panels with different LEDs (APA102 specifically), but given they're not that cheap, I'd like to explore all other alternatives first.

Here are two videos, one of which is in slow-mo:

I'm using large parts of Marc Merlins code, here are the most relevant parts:
Code:
// neomatrix_config.h
#ifndef neomatrix_config_h
#define neomatrix_config_h

#include <Adafruit_GFX.h>
#include <FastLED.h>
#include <LEDMatrix.h>
#include <FastLED_NeoMatrix.h>

// control if we decode in 32x32 or 64x64, or something else
#define gif_size 32
#define FSO SD
#define FSOSD
#define SD_CS BUILTIN_SDCARD
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

uint8_t matrix_brightness = 15;

// used by LEDMatrix
const uint16_t MATRIX_TILE_WIDTH = 16; // width of EACH NEOPIXEL MATRIX (not total display)
const uint16_t MATRIX_TILE_HEIGHT= 16; // height of each matrix
const uint8_t MATRIX_TILE_H     = 4; // number of matrices arranged horizontally
const uint8_t MATRIX_TILE_V     = 1; // number of matrices arranged vertically

// used by NeoMatrix
const uint16_t mw = MATRIX_TILE_WIDTH *  MATRIX_TILE_H;
const uint16_t mh = MATRIX_TILE_HEIGHT * MATRIX_TILE_V;

cLEDMatrix<
  MATRIX_TILE_WIDTH,
  -MATRIX_TILE_HEIGHT,
  HORIZONTAL_ZIGZAG_MATRIX,
  MATRIX_TILE_H,
  MATRIX_TILE_V,
  HORIZONTAL_BLOCKS
> ledmatrix(false);

CRGB *matrixleds;

FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(
  matrixleds,
  MATRIX_TILE_WIDTH,
  MATRIX_TILE_HEIGHT,
  MATRIX_TILE_H,
  MATRIX_TILE_V,
  NEO_MATRIX_TOP +
  NEO_MATRIX_RIGHT +
  NEO_MATRIX_ROWS + 
  NEO_MATRIX_ZIGZAG +
  NEO_TILE_TOP +
  NEO_TILE_RIGHT +
  NEO_TILE_ROWS
);

const uint8_t MATRIXPIN = 6;
    
//----------------------------------------------------------------------------

// Compat for some other demos
const uint32_t NUMMATRIX = mw * mh;
const uint32_t NUM_LEDS = NUMMATRIX;
const uint16_t MATRIX_HEIGHT = mh;
const uint16_t MATRIX_WIDTH = mw;

const uint16_t kMatrixWidth = mw;
const uint16_t kMatrixHeight = mh;

uint8_t gHue = 0; // rotating "base color" used by many of the patterns
uint16_t speed = 255;

float matrix_gamma = 0.5; // higher number is darker, needed for Neomatrix more than SmartMatrix

// Like XY, but for a mirror image from the top (used by misconfigured code)
int XY2( int x, int y, bool wrap=false) {
    wrap = wrap; // squelch compiler warning
    return matrix->XY(x,MATRIX_HEIGHT-1-y);
}

uint16_t XY( uint8_t x, uint8_t y) {
    return matrix->XY(x,y);
}

int wrapX(int x) {
    if (x < 0 ) return 0;
    if (x >= MATRIX_WIDTH) return (MATRIX_WIDTH-1);
    return x;
}

void show_free_mem(const char *pre=NULL) {
    Framebuffer_GFX::show_free_mem(pre);
}

void die(const char *mesg) {
    Serial.println(mesg);
    while(1) delay((int32_t)1); // while 1 loop only triggers watchdog on ESP chips
}

void *mallocordie(const char *varname, uint32_t req) {
    Serial.print("Malloc ");
    Serial.print(varname);
    Serial.print(" . Requested bytes: ");
    Serial.println(req);
    
    void *mem;
    mem = malloc(req);

    if (mem) {
        return mem;
    } else {
        Serial.print("FATAL: ");
        Serial.print("malloc failed for ");
        Serial.println(varname);
        show_free_mem();
        while (1); // delay(1);  Adding this seems to cause an ESP32 bug
    }
    return NULL;
}

bool init_done = 0;
void matrix_setup(int reservemem = 40000) {
    reservemem = reservemem; // squelch compiler warning if var is unused.
    if (init_done) {
        Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> BUG: matrix_setup called twice");
        return;
    }
    
    init_done = 1;
    
    delay(3000);
    
    Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Serial.begin");
    show_free_mem("Memory after setup() starts");
    
    matrixleds = (CRGB *) mallocordie("matrixleds", sizeof(CRGB) * NUMMATRIX);
    matrix->newLedsPtr(matrixleds);
    show_free_mem("After matrixleds malloc");
    ledmatrix.SetLEDArray(matrixleds);
   
    //==================================================  ==========================================
    // Matrix Init Start
    //==================================================  ==========================================
    FastLED.addLeds<1, APA104, MATRIXPIN, GRB>(matrixleds, NUMMATRIX);
    Serial.print("Neomatrix total LEDs: ");
    Serial.print(NUMMATRIX);
    Serial.print(" running on pin: ");
    Serial.println(MATRIXPIN);
    //==================================================  ==========================================
    // Matrix Init End
    //==================================================  ==========================================

    matrix->begin();

    Serial.print("Setting Brightness: ");
    Serial.println(matrix_brightness);
    FastLED.setBrightness(matrix_brightness);
    
    Serial.print("Gamma Correction: ");
    Serial.println(matrix_gamma);
    matrix->precal_gamma(matrix_gamma);

    Serial.println("matrix_setup done");

    while(Serial.available() > 0) { char t = Serial.read(); t = t; }
}
#endif // neomatrix_config_h

Code:
// matrix.h
// By Marc MERLIN <marc_soft@merlins.org>
// License: Apache v2.0
//

#ifndef matrix_h
#define matrix_h

#include "neomatrix_config.h"
#include "Drawable.h"

const int MATRIX_CENTER_X = MATRIX_WIDTH / 2;
const int MATRIX_CENTER_Y = MATRIX_HEIGHT / 2;

const byte MATRIX_CENTRE_X = MATRIX_CENTER_X - 1;
const byte MATRIX_CENTRE_Y = MATRIX_CENTER_Y - 1;

#define mmin(a,b) (a<b)?(a):(b)
#define mmax(a,b) (a>b)?(a):(b)

#include "Effects.h"
Effects effects;

#endif

Code:
// main.h
void loop() {
    pattern.drawFrame();
    matrix->show();
}

void setup() {
    delay(1000);
    Serial.begin(115200);

    matrix_setup();
    Serial.print("Matrix Size: ");
    Serial.print(mw);
    Serial.print(" ");
    Serial.println(mh);
    matrix->begin();
    matrix->setBrightness(matrix_brightness);
    matrix->setTextWrap(false);

    effects.leds = matrixleds;
    effects.Setup();
    pattern.start();
    matrix->clear();
}

Regards
Kevin
 
In the mean time I've tried these things, none of which lead to any improvement:
- using parallel output
- using just one panel instead of all four
- using the parallel output test code
 
Hi Kevin,

Your wiring diagram "Attachment 24027" does not show up:
Invalid Attachment specified. If you followed a valid link, please notify the administrator

Paul
 
Hi Kevin,

Your wiring diagram "Attachment 24027" does not show up:

Paul

Oh, I wasn't aware of that, thanks for letting me know! Let me try again:
Bildschirmfoto 2021-03-12 um 10.17.01.jpg
 
I've now switched from the Teensy to a ESP32 and the flicker is gone &#55358;&#56631;&#55356;&#57340;*♂️
 
Status
Not open for further replies.
Back
Top