Go Down

Topic: making FastLED faster! (Read 833 times) previous topic - next topic

nomotion7

Good evening,

I have posted the same issue on github under der FastLED Library but have not received a reply yet. And i really need to solve this problem because the installation is for an event at the end of the month. I was hoping to get some resonance here.

I am thankful for any help I can get.
Thanks in advance.

I have been working on a led project for some time. I recently finished my build of 4 large led matrices, each composed of 4 small 8x8 tiles and trying to control these over 4 different data lines. To achieve this I have also used the Library LEDMatrix and used a custom remapping function, similar to the one offered by NeoPixel for Tiled Matrices.

When running my prgramm the esp8266 randomly goes into reset mode or seems to crash after changing a very large amount of Leds and calling fastled FastLED.show(). Running simple sketches over just one data line with the same esp works fine.

My assumption: there is either something wrong with the power supply or changing that many leds at once simply takes to much time and revokes the watchdog timer.

But after countless hours of trying to really narrow the problem down and trying solutions that worked for other people like, FASTLED_ALLOW_INTERRUPTS 0, WiFi.forceSleepBegin(), flash frq 160hz, different types of delay, yield and and putting capacitors between the power supply of the esp, I am clueless on what to do next. Is it possible to shorten the time to pass the information to the chip on the LED?



My specs:

microcontroller esp8266 Lolin V3 nodeMCU 1.0 ESP12E
power supply 30A 5V (used for all components)
16x 8x8 U-64-LED-Panel
led Type WS2812B
total number of Leds 1048

When i turn on the serial at 115200 baud rate the last process I get on the stack before crashing is:

loop_wrapper()

Here is my code for adding the matrices together and trying to show simple objects:
Code: [Select]
//#define FASTLED_INTERRUPT_RETRY_COUNT 0
//#define FASTLED_ALLOW_INTERRUPTS 0
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER 1
#include <FastLED.h> //https://github.com/FastLED/FastLED
#include <LEDMatrix.h> //https://github.com/Jorgen-VikingGod/LEDMatrix
#include "ESP8266WiFi.h"

#define DATA_PIN 7
#define DATA2_PIN 2
#define DATA3_PIN 5
#define DATA4_PIN 6

#define COLOR_ORDER GRB
#define CHIPSET WS2812B

#define MATRIX_TILE_WIDTH 8 // width of EACH NEOPIXEL MATRIX (not total display)
#define MATRIX_TILE_HEIGHT 8 // height of each matrix
#define MATRIX_TILE_H 2 // number of matrices arranged horizontally
#define MATRIX_TILE_V 2 // number of matrices arranged vertically
#define MATRIX_SIZE (MATRIX_WIDTHMATRIX_HEIGHT)
#define MATRIX_PANEL (MATRIX_WIDTHMATRIX_HEIGHT)

#define MATRIX_WIDTH (MATRIX_TILE_WIDTHMATRIX_TILE_H)
#define MATRIX_HEIGHT (MATRIX_TILE_HEIGHTMATRIX_TILE_V)

#define NUM_LEDS (MATRIX_WIDTH*MATRIX_HEIGHT)

#define NUM_PANELS 4

#define TOTOALCOUNT NUM_LEDS*NUM_PANELS

// Putting together the 4 tiles for one matrix
cLEDMatrix<MATRIX_TILE_WIDTH, MATRIX_TILE_HEIGHT, HORIZONTAL_MATRIX, MATRIX_TILE_H, MATRIX_TILE_V, VERTICAL_ZIGZAG_BLOCKS> matrix;

#define BRIGHTNESS 50

#define TURQUOISE CRGB(80, 120, 120)
#define PURPLE CRGB(80, 0, 120)
#define YELLOW CRGB(243,146,0)
#define BLACK CRGB(0,0,0)
#define BLUE CRGB(0,0,160)
#define RED CRGB(160,0,0)

CRGBPalette16 simplePalette[] = {TURQUOISE, PURPLE , BLUE, RED};

CRGBPalette16 adobePalette[] = {CRGB(50, 164, 173), CRGB(207, 150, 195), CRGB(136, 85, 158), CRGB(108, 62, 145), CRGB(40, 42, 94)};

CRGBPalette16 bushPalette[] = {CRGB(25, 79, 38), CRGB(18, 99, 47), CRGB(3, 127, 57), CRGB(0, 145, 61), CRGB(0, 157, 88), CRGB(0, 151, 96), CRGB(5, 140, 99)};

CRGBPalette16 warmPalette[] = {CRGB(210, 123, 16), CRGB(194, 25, 27), CRGB(177, 28, 27), CRGB(167, 29, 25), CRGB(139, 26, 21)};

CRGBPalette16 warmOcPalette1[] = {CRGB(80, 190, 200), CRGB(143, 206, 198), CRGB(142, 201, 164), CRGB(172, 208, 133)};

CRGBPalette16 warmOcPalette2[] = {CRGB(12, 176, 191), CRGB(102, 193, 189), CRGB(104, 189, 153), CRGB(146, 197, 118)};

CRGBPalette16 grenishPalette[] = {CRGB(43, 170, 90), CRGB(122, 185, 58), CRGB(118, 184, 43), CRGB(154, 195, 30), CRGB(149, 164, 36), CRGB(134, 106, 41), CRGB(92, 81, 46), CRGB(81, 57, 41), CRGB(48, 40, 35), CRGB(32, 32, 26)};

//unnaturalInfusionPalette: 10 ELEMENTS
CRGBPalette16 unnatInfusionPalette[] = {CRGB(221,75,93), CRGB(188,60,94), CRGB(164,52,123),CRGB(149,47,136),CRGB(119,34,122),
CRGB(221,10,43),CRGB(193,23,40),CRGB(174,24,44),CRGB(132,22,40),CRGB(101,18,33)};

//naturalInfusionPalette: 10 ELEMENTS
CRGBPalette16 natInfusionPalette[] = {CRGB(38,130,130),CRGB(43,132,111),CRGB(56,140,94),CRGB(62,158,72),CRGB(81,176,72),
CRGB(31,66,47),CRGB(36,76,49),CRGB(38,97,44),CRGB(35,125,52),CRGB(41,158,56)};

//BubbleFrontPalette: 5 ELEMENTS
CRGBPalette16 bubbleFrontPalette[] = {CRGB(240, 147, 64), CRGB(237, 125, 50), CRGB(232, 102, 32), CRGB(207, 78, 22), CRGB(193, 45, 24)};

CRGBPalette16 purpleGreen[] = {CRGB(23, 119, 116), CRGB(28, 132, 132), CRGB(41, 120, 150), CRGB(53, 88, 164), CRGB(71, 71, 151), CRGB(90, 90, 164), CRGB(119, 103, 171)};
//CRGBPalette16 pacificaPalette[] = {0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117,
// 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50
// };

void stableDelay(int delaytime)
{
yield();
delayMicroseconds(delaytime);
}

void matrix_clear() {
//FastLED[1].clearLedData();
// clear does not work properly with multiple matrices connected via parallel inputs
memset(matrix[0], 0, TOTOALCOUNT-1);
}

void total_clear(bool showing)
{
matrix_clear();
FastLED.clear(showing);
}

void setup()
{

WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
//WiFi.setSleepMode(WIFI_NONE_SLEEP);
// Serial.begin(115200);
// WiFi.forceSleepBegin();
// stableDelay(50);
//Serial.println("test");
//delay(100);

//Adding all 4 Matrices into one large led array

FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(matrix[0], 0, matrix.Size());//.setCorrection(TypicalSMD5050);
FastLED.addLeds<CHIPSET, DATA2_PIN, COLOR_ORDER>(matrix[0], matrix.Size(), matrix.Size());//.setCorrection(TypicalSMD5050);
FastLED.addLeds<CHIPSET, DATA3_PIN, COLOR_ORDER>(matrix[0], matrix.Size()*2, matrix.Size());//.setCorrection(TypicalSMD5050);
FastLED.addLeds<CHIPSET, DATA4_PIN, COLOR_ORDER>(matrix[0], matrix.Size()*3, matrix.Size());//.setCorrection(TypicalSMD5050);
//FastLED.setBrightness(BRIGHTNESS);
//total_clear(false);
}

void loop()
{
total_clear(false);
stableDelay(5000);
japan();
stableDelay(5000);
japan2(1);
stableDelay(5000);
total_clear(false);
stableDelay(5000);
}
}

void japan()
{

matrix.DrawFilledRectangle(0, 0, ((16*2) - 1), (5 - 1), CRGB(150, 0, 255));

uint16_t r = min(((matrix.Width()*NUM_PANELS) - 1) / 2, (matrix.Height() - 1) / 2) - 1;
matrix.DrawFilledCircle(((matrix.Width()*1) - 1) , (matrix.Height() - 1) / 2, r, CRGB(255, 0, 0));
FastLED.show();
}
void japan2(bool c)
{

if(c)
{
matrix.DrawFilledRectangle(162, 0, ((164) - 5), 5, CRGB(100, 50, 200));
//uint16_t r = min(((matrix.Width()NUM_PANELS) - 1) / 2, (matrix.Height() - 1) / 2) - 1;
//matrix.DrawFilledCircle(((matrix.Width()NUM_PANELS) - 1) , (matrix.Height() - 1) / 2, r, CRGB(0, 0, 255));
FastLED.show();
}
else
{
matrix.DrawFilledRectangle(163, 0, ((164) - 1), 10, CRGB(100, 50, 0));
//uint16_t r = min(((matrix.Width()*NUM_PANELS) - 1) / 2, (matrix.Height() - 1) / 2) - 1;
//matrix.DrawFilledCircle(((matrix.Width()*NUM_PANELS) - 1) , (matrix.Height() - 1) / 2, r, CRGB(0, 0, 255));
FastLED.show();
}
}

void testMatrix()
{
for (int i_1= 0;i_1< 16; i_1++)
{
for (int i_2 = 0; i_2< 32;i_2++)
{
matrix.DrawPixel(i_2, i_1, CRGB(255, 0, 0));
FastLED.show();
}
}
matrix.DrawPixel(6, 6, CRGB(255, 255, 0));
FastLED.show();
delay(100);
}

Grumpy_Mike

Quote
Is it possible to shorten the time to pass the information to the chip on the LED?
No.

Basically there is no way to speed up the refreshing rate of the WS2812 LEDs.
The only thing you can do is to shuffle around when you send the data.

You might want to try and offload the refresh of the data off to another processor or processors that maintains their own buffer and do the refresh on request. If your main processor talks to the slave ones and tells it what to change in the buffer this can cut down on the traffic.

It might be possible by using a faster processor like the Teensy 4.0 or 4.1 then the allow interrupts call might make the difference.

hzrnbgy

Each Neopixel LED requires 3 bytes (8 bits per red, green, blue)

For 1048 LEDs would need 3 kB of SRAM which the ESP8266 has more than enough.

When the ESP8266 crashes, what sort of error do you get on boot-up?

nomotion7

Each Neopixel LED requires 3 bytes (8 bits per red, green, blue)

For 1048 LEDs would need 3 kB of SRAM which the ESP8266 has more than enough.

When the ESP8266 crashes, what sort of error do you get on boot-up?
thanks for the reply, my first aproach was using an arduino nano, but after realising that sram wasnt enough i moved to the esp.

this is the boot message i get:
Quote
20:58:29.950 ->  ets Jan  8 2013,rst cause:4, boot mode:(3,6)
20:58:29.950 ->
20:58:29.950 -> wdt reset
20:58:29.984 -> load 0x4010f000, len 3584, room 16
20:58:29.984 -> tail 0
20:58:29.984 -> chksum 0xb0
20:58:29.984 -> csum 0xb0
20:58:29.984 -> v2843a5ac
20:58:29.984 -> ~ld

PaulRB

What is MATRIX_WIDTHMATRIX_HEIGHT ?

nomotion7

No.

You might want to try and offload the refresh of the data off to another processor or processors that maintains their own buffer and do the refresh on request. If your main processor talks to the slave ones and tells it what to change in the buffer this can cut down on the traffic.

It might be possible by using a faster processor like the Teensy 4.0 or 4.1 then the allow interrupts call might make the difference.
Okay, do you mean moving to another processor on the esp or using a different extern processor?
I don't have any experience using the Teensy, how about using an arduino mega for a stable setup?
I tried allowing interrupts again, that didnt work.

What is MATRIX_WIDTHMATRIX_HEIGHT ?
somehow it did not copy the asterix, in the ide it is:  MATRIX_WIDTH*MATRIX_HEIGHT

hzrnbgy

The issue seems to be watchdog reset

Code: [Select]
20:58:29.950 -> wdt reset

Not very familiar with ESP but you might be able to disable the WDT before calling fastled.show

Grumpy_Mike

Quote
Okay, do you mean moving to another processor on the esp or using a different extern processor?
That was two possible solutions to your problem.

Quote
how about using an arduino mega for a stable setup?
That will not help in getting your refreshes faster.

The Teensy will allow you to use the no interrupt option and allow other stuff to be done at the same time.

nomotion7

okay thanks for the response.
upon further investigation it turns out, the remapping function i use, takes a long time being called for 1000 leds, so i will try to speed it up.
finally making progess ^^

Relign

You might also look at your power supply, maybe it can't deliver enough Amps, causing  your processor to go into shock.

Go Up