I am trying to hack together a sketch that updates an led matrix I

fastled-samples
gplus
(Roger Guess) #1

I am trying to hack together a sketch that updates an led matrix I built from data from an http request. I understand on the ESP32, that delay does not work as expected and that you need to use mills() instead. What I do not understand is how code written for the ESP32 works fine when deployed by itself (examples HttpClient > BasicHttpClient). When I being to integrate fastled into the sketch, delay() stops working. The http example also stops working ( I am assuming because of it’s use of delay() ) and by stops working, it seems to crash/reset the board. Once the first call to matrix->show() has been made, delay() no longer works. Can someone help me understand this?

if anyone is curious about the code:

#include <Arduino.h>

#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#define USE_SERIAL Serial

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

// Allow temporaly dithering, does not work with ESP32 right now
#ifndef ESP32
//#define delay FastLED.delay
#endif

#if defined(ESP32) or defined(ESP8266)
#define PIN 4
#else
#define PIN 4
#endif

//#define P32BY8X4
//#define P16BY16X4
#define P32BY8X3
#if defined(P32BY8X4) || defined(P16BY16X4) || defined(P32BY8X3)
#define BM32
#endif

#ifdef BM32
//#include “google32.h”
// Anything with black does not look so good with the naked eye (better on pictures)
//#include “linux32.h”
#endif

// Max is 255, 32 is a conservative value to not overload
// a USB power supply (500mA) for 12x12 pixels.
#define BRIGHTNESS 100

// Define full matrix width and height.
#if defined(P32BY8X4) || defined(P16BY16X4)
#define mw 42
#define mh 8
#elif defined(P32BY8X3)
#define mw 42
#define mh 8
#else
#define mw 42
#define mh 8
#endif

#define NUMMATRIX (mw*mh)
CRGB leds[NUMMATRIX];

WiFiMulti wifiMulti;

// MATRIX DECLARATION:
// Parameter 1 = width of EACH NEOPIXEL MATRIX (not total display)
// Parameter 2 = height of each matrix
// Parameter 3 = number of matrices arranged horizontally
// Parameter 4 = number of matrices arranged vertically
// Parameter 5 = pin number (most are valid)
// Parameter 6 = matrix layout flags, add together as needed:
// NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
// Position of the FIRST LED in the FIRST MATRIX; pick two, e.g.
// NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
// NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs WITHIN EACH MATRIX are
// arranged in horizontal rows or in vertical columns, respectively;
// pick one or the other.
// NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns WITHIN
// EACH MATRIX proceed in the same order, or alternate lines reverse
// direction; pick one.
// NEO_TILE_TOP, NEO_TILE_BOTTOM, NEO_TILE_LEFT, NEO_TILE_RIGHT:
// Position of the FIRST MATRIX (tile) in the OVERALL DISPLAY; pick
// two, e.g. NEO_TILE_TOP + NEO_TILE_LEFT for the top-left corner.
// NEO_TILE_ROWS, NEO_TILE_COLUMNS: the matrices in the OVERALL DISPLAY
// are arranged in horizontal rows or in vertical columns, respectively;
// pick one or the other.
// NEO_TILE_PROGRESSIVE, NEO_TILE_ZIGZAG: the ROWS/COLUMS OF MATRICES
// (tiles) in the OVERALL DISPLAY proceed in the same order for every
// line, or alternate lines reverse direction; pick one. When using
// zig-zag order, the orientation of the matrices in alternate rows
// will be rotated 180 degrees (this is normal – simplifies wiring).
// See example below for these values in action.

#ifdef P32BY8X4
// Define full matrix width and height.
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(42, 7, 1, 1, 1,
NEO_MATRIX_TOP + NEO_MATRIX_left +
NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG +
// progressive vs zigzag makes no difference for a 4 arrays next to one another
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_PROGRESSIVE);
#elif defined(P16BY16X4)
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, 16, mh, mw/16, mh/16,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG +
NEO_TILE_TOP + NEO_TILE_LEFT + NEO_TILE_ZIGZAG);
#elif defined(P32BY8X3)
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, 42, 7, 1, 1,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);
#else
// Define matrix width and height.
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, mw, mh,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);
#endif

// This could also be defined as matrix->color(255,0,0) but those defines
// are meant to work for adafruit_gfx backends that are lacking color()
#define LED_BLACK 0

#define LED_RED_VERYLOW (3 << 11)
#define LED_RED_LOW (7 << 11)
#define LED_RED_MEDIUM (15 << 11)
#define LED_RED_HIGH (31 << 11)

#define LED_GREEN_VERYLOW (1 << 5)
#define LED_GREEN_LOW (15 << 5)
#define LED_GREEN_MEDIUM (31 << 5)
#define LED_GREEN_HIGH (63 << 5)

#define LED_BLUE_VERYLOW 3
#define LED_BLUE_LOW 7
#define LED_BLUE_MEDIUM 15
#define LED_BLUE_HIGH 31

#define LED_ORANGE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
#define LED_ORANGE_LOW (LED_RED_LOW + LED_GREEN_LOW)
#define LED_ORANGE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM)
#define LED_ORANGE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH)

#define LED_PURPLE_VERYLOW (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
#define LED_PURPLE_LOW (LED_RED_LOW + LED_BLUE_LOW)
#define LED_PURPLE_MEDIUM (LED_RED_MEDIUM + LED_BLUE_MEDIUM)
#define LED_PURPLE_HIGH (LED_RED_HIGH + LED_BLUE_HIGH)

#define LED_CYAN_VERYLOW (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_CYAN_LOW (LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_CYAN_MEDIUM (LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_CYAN_HIGH (LED_GREEN_HIGH + LED_BLUE_HIGH)

#define LED_WHITE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_WHITE_LOW (LED_RED_LOW + LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_WHITE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_WHITE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH + LED_BLUE_HIGH)

void display_text_right(String textIn) {
//uint8_t size = max(int(mw/8), 1);
//matrix_clear();
matrix->setTextWrap(false); // we don’t wrap text so it scrolls nicely
matrix->setTextSize(.5);
matrix->setRotation(0);
long delayfor = 0;
for (int8_t iy = 0 ; iy < mh + 1 ; iy++)
{
matrix->clear();
matrix->fillScreen(LED_RED_MEDIUM);
matrix->setCursor(0, mh - iy);
matrix->setTextColor(LED_WHITE_MEDIUM);
matrix->print(textIn);
matrix->show();
switch (iy){
case 0:
delayfor = 20;
break;
case 1:
delayfor = 20;
break;
case 2:
delayfor = 20;
break;
case 3:
delayfor = 30;
break;
case 4:
delayfor = 40;
break;
case 5:
delayfor = 80;
break;
case 6:
delayfor = 100;
break;
case 7:
delayfor = 130;
break;
}
esp_delay(delayfor);
}
esp_delay(1000);
}

void esp_delay(long ms)
{
long continueWhen = millis() + ms;

  //USE_SERIAL.print("delay requested ");
  //USE_SERIAL.print(ms);
  //USE_SERIAL.print(" delay+start ");
  //USE_SERIAL.print(continueWhen);
  //USE_SERIAL.print(" current millis ");
  //USE_SERIAL.println(millis());
 
  while (millis() < continueWhen)
  {
    //lastAction = millis();
  }

}

void matrix_clear() {
// clear does not work properly with multiple matrices connected via parallel inputs
memset(leds, 0, sizeof(leds));
}

void setup() {

USE_SERIAL.begin(115200);

USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();

for(uint8_t t = 4; t > 0; t--) {
    USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
    USE_SERIAL.flush();
    delay(1000);
}

USE_SERIAL.println("begin addAP");
wifiMulti.addAP("your ap", "your password");
USE_SERIAL.println("end addAP");

 FastLED.addLeds<NEOPIXEL,PIN>(leds, mw*mh).setCorrection(TypicalLEDStrip);
// Parallel output
//FastLED.addLeds<WS2811_PORTA,3>(leds, NUMMATRIX/3).setCorrection(TypicalLEDStrip);
// Time for serial port to work?
delay(1000);
//Serial.begin(115200);
USE_SERIAL.print("Matrix Size: ");
USE_SERIAL.print(mw);
USE_SERIAL.print(" ");
USE_SERIAL.println(mh);
matrix->begin();
matrix->setTextWrap(false);
matrix->setBrightness(BRIGHTNESS);
USE_SERIAL.println("If the code crashes here, decrease the brightness or turn off the all white display below");
// Test full bright of all LEDs. If brightness is too high
// for your current limit (i.e. USB), decrease it.
//matrix->fillScreen(LED_RED_HIGH);
//matrix->show();
delay(3000);

}

void loop() {

USE_SERIAL.println("begin delay 5000");
delay(5000);
USE_SERIAL.println("begin esp_delay 5000");
esp_delay(5000);
USE_SERIAL.println("end delay test");

// wait for WiFi connection
USE_SERIAL.println("begin wifi run");
if((wifiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;

    USE_SERIAL.print("[HTTP] begin...\n");
    esp_delay(1000);
    // configure traged server and url
    //http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS
    http.begin("http://example.com/index.html"); //HTTP

    USE_SERIAL.print("[HTTP] GET...\n");
    esp_delay(1000);
    // start connection and send HTTP header
    int httpCode = http.GET();

    // httpCode will be negative on error
    if(httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

        // file found at server
        if(httpCode == HTTP_CODE_OK) {
            String payload = http.getString();
            USE_SERIAL.println(payload);
        }
    } else {
        USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }
    esp_delay(1000);
    http.end();
}

matrix_clear();
display_text_right("1234567890ABCDEFG");

USE_SERIAL.println("begin delay 5000");
delay(5000);
USE_SERIAL.println("begin esp_delay 5000");
esp_delay(5000);
USE_SERIAL.println("end delay test");

matrix_clear();
matrix->show();

esp_delay(5000);

}

(Sam Guyer) #2

@Roger_Guess Are you using my branch of the ESP32 support? Either way, I don’t recommend using FastLED.delay. I think it causes problems with the synchronization in the driver.

(Roger Guess) #3

I am not trying to use delay(), but I believe the code for httpclient for the esp32 uses it. Soon as a call is made to matrix->show(), the wifiMulti or httpclient stops working. Yes, I am using your fork.