Problem with Smartmatrix library and another Led strip

Hi everyone !

I have a problem when using simultaneously a led matrix screen and a led strip on a smartmatrix shield.

Here is the hardware I use:

  • A smartmatrix shield with a Teensy 3.2
  • A 64x32 led matrix (works like a charm !)
  • A 144 Led strip (connected to the pin 13, 5v and Ground of the Smartmatrix shield)

Using 64x32 matrix only :
Everything works fine when I display something on my 64x32 led matrix (great).

Led strip only:
Everything is ok whith a simple example based on the FastLED.h libray to make all 144 leds blink on my led strip.

BUT:
If I use simultaneously the matrix and the led strip then I can only switch on 5 leds out of the 144 leds on the strip.

Memory problem ?

I try to change the “kDmaBufferRows” to 1 (what a shame !) and all 144 leds works (with the same code)

Is someone have a solution for me ?

Thanks !

Mike

Here is my code:

A red background with a “BLINK” message on it (it works)
and a blinked LED strip with all 144 LEDs. (but error : only 5 LEDs blinks…) :frowning:

/* 
 *  Test with 64x32 Matrix and 144 led Strip 
 */
 
#include <SmartMatrix3.h>
#include <FastLED.h>

//Smartmatrix Const
#define COLOR_DEPTH 24                  // known  working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 64;        // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 16, 32, 48, 64
const uint8_t kRefreshDepth = 24;       // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 2;       // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE);      // see http://docs.pixelmatix.com/SmartMatrix for options
const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE);
const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE);
const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions);
SMARTMATRIX_ALLOCATE_SCROLLING_LAYER(scrollingLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kScrollingLayerOptions);
SMARTMATRIX_ALLOCATE_INDEXED_LAYER(indexedLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);

//LED Strip : pin 13 (CLK), 5v, Gnd with Smartmatrix shield 
#define NUM_LEDS 144
#define DATA_PIN 13
CRGB leds[NUM_LEDS];

const int defaultBrightness = 100*(255/100);    // full brightness
const int defaultScrollOffset = 6;
const rgb24 defaultBackgroundColor = {0x00, 0x00, 0x00};
const rgb24 redColor = {0xff, 0, 0};
const rgb24 whiteColor = {0xff, 0xff, 0xff};

void setup() {

  //Strip LED
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  //Matrix init
  matrix.addLayer(&backgroundLayer); 
  matrix.addLayer(&scrollingLayer); 
  matrix.addLayer(&indexedLayer); 
  matrix.begin();
  matrix.setBrightness(defaultBrightness);
  scrollingLayer.setOffsetFromTop(defaultScrollOffset);
  backgroundLayer.enableColorCorrection(true);

  //Display BLINK with red Background
  backgroundLayer.setFont(font8x13);
  backgroundLayer.fillScreen({0xc8, 0, 0});
  backgroundLayer.drawString(12, 10, {0xff, 0xff, 0xff}, "BLINK");
  backgroundLayer.swapBuffers();
    
  
}

void loop() {
    
    // Switch on all 144 LEDs
    for(int dot = 0; dot < NUM_LEDS; dot++) { 
            leds[dot] = CRGB::Red;     
    }
    FastLED.show();
    delay(1000);
    for(int dot = 0; dot < NUM_LEDS; dot++) { 
            leds[dot] = CRGB::Black;     
    }
    FastLED.show();
    delay(1000); 
}

Hi Mike,

Could be a memory problem, or could be an interrupt problem. I assume you’re using a WS2812 LED strip, and those have specific timing required for updating the LEDs. The SmartMatrix Library uses interrupts to keep refreshing the panel, and one of those interrupts may be messing up the timing of the code (adding in a long pause) that is refreshing the LED strip.

To see if it’s a memory problem, set your sketch up temporarily to drive a 32x32 panel, so you free up a bunch of memory. See if it works.

You can drop down the refresh color depth from the default of 36 to 24, that will also free up memory.

Hi Louis,

Thanks for your answer !
Well I think the interrupt option may be the good one because I have already tried to reduce to 32x32…with no change…
What can I change to my code in order to use my strip with your interrupt function ?

Thanks and have a merry Christmas !!! :snowman_with_snow:️:snowman:️:snowman_with_snow:️

Mike

Hi Mike,

Sorry for the late reply, I’m visiting family over Christmas. I don’t know what you can change. This article explains the FastLED interrupt usage, and it looks like FastLED already is disabling interrupts when writing WS2812 data, so I don’t know why your code isn’t working.

The fact that your code works if you reduce kDmaBufferRows down to 1 is interesting. I recommend using the value of 2 as a minimum, but I can’t remember why. I think if the value is 1, then the SmartMatrix code can’t work to compute the next row’s data until it’s done shifting out the current row to the matrix. That should result in a poor framerate, but a side effect is that it seems to work better for you with your WS2812 LEDs. Sorry I can’t explain this or to try to improve this code right now. If you open up a GitHub Issue in the SmartMatrix Library repo, and link to this thread, then it will be in my queue for the next time I’m working on the library.

If you aren’t tied to the WS2812, and can buy a APA102 strip, I recommend using that over the WS2812s.

Hi Louis,

I tried something : I opened the “fastled_config.h” file (in Fastled directory) and forced this:
#define FASTLED_ALLOW_INTERRUPTS 0

The strip worked again but my SmartMatrix screen became black.

:frowning:

Ok… I’ll try with a APA102 strip … :slight_smile:

Thanks a lot and have an happy ending year !

Mike

Hi Mike,

That’s actually progress! Let’s not give up yet (though I do think you’ll be better off with an APA102 strip). Try increasing the value for kDmaBufferRows with FASTLED_ALLOW_INTERRUPTS set to 0.

Happy New Year to you as well!

Louis

Hi Louis,

I tried to increase kDmaBufferRows to 4 but with no effect (Black screen also)
So I tried to use the Adafruit_NeoPixel.h in place of FastLED.h

It worked ! :slight_smile:
But the noInterrupt() function in Adafruit_NeoPixel.c causes artefacts on my Smartmatrix screen ! (Flashing white pixels displayed randomly).

I really should learn to use interruptions on Arduino because I play wizard apprentices here ! :smile:

Have an Happy New Year too from France Louis and thank you very much for your help !

Mike

I opened an issue for this to track it, I have a feeling the fix is simple (disable DMA so it doesn’t keep going if the ISR can’t be reached in time). It might be some time before I get around to fixing it though, but it’s in the system:

Hi Louis !

A big thank you for your involvement in solving my problem!

If you need, I can send you my WS2812 strip so you’ll be able to test with a real hardware.
Can you send me your mailing address on my email address? My e-mail: mike.dauria(at)wanadoo.fr I send you this as soon as possible!

Did you see my project?: www.arduibag.com
(An opensource connected backpack for bike driver ! :slight_smile: )

Mike

Hi Mike, great project! I already have some WS2812s, but thanks for the offer.

I just stumbled on this while reading some bugs, and realized this is very much going to affect my project :slight_smile:
@mdauria I can help with the neopixel part of how things work. You probably understand things by now, but if not, see:

This shows the issue Neopixel + IR: Part 4/6 - Arduiny328p IR or Stable Neopixels - YouTube
You can also see what’s going on when you don’t disable interrupts at all, around offset 2:40

This video shows what’s going on: Neopixel + IR: Part 5/6 - Teensy IR and Neopixels - YouTube on teensy which can re-enable interrupts for a short time
The adafruit library does bit banging and disables interrupts the entire time on any chip, so that’s not going to work.

The only ways this can work are:
0) don’t use neopixel, use a strip with a clock line.

  1. have smartmatrix do its own bit banging in between 2 neopixel pixel updates. This is not a lot of time, and honestly even on a teensy 3.6, it’s not very likely to work.
    Having 2 timing sensitive ISRs running at the same time is not quite impossible but not likely to work
    This is another way to say that until someone writes a DMA driver for neopixels on teensy, I don’t expect them to work with SmartMatrix running at the same time.

  2. use a neopixel driver that uses DMA. See my page again:
    Marc's Blog: arduino - Arduino 328P Uno Teensy3.1 ESP8266 ESP32 IR and Neopixels

On teensy, FastLED does not use DMA to talk to neopixels. It’s probably possible to use some DMA capability on the chip to do it, but no one has AFAIK.
On ESP8266 (not supported by SmartMatrix), you can do neopixel with I2S DMA
On ESP32 (alpha supported by SmartMatrix now), the RMT driver allows you to do DMA for Neopixels (FastLED supports it out of the box).
I’m not sure how @Louis wrote his SmartMatrix code on ESP32 (haven’t looked yet) , so maybe there is an incompatibility on how he uses DMA/RMT and how FastLED does, but with 8 RMT channels, both ought to be able to work at the same time.

So, this a lot of words to say that what you’d like (turns out me too) is likely to work on ESP32 now or soon.

I did some testing, here are the results: SmartMatrix + FastLED Neopixels + Interrupt driven IR
TL;DR: ESP32 can be made to work. Teensy does not work meaningfully with the current FastLED driver.