mrcodetastic / ESP32-HUB75-MatrixPanel-DMA

An Adafruit GFX Compatible Library for the ESP32, ESP32-S2, ESP32-S3 to drive HUB75 LED matrix panels using DMA for high refresh rates. Supports panel chaining.
MIT License
977 stars 215 forks source link

Brownout detector triggered using `drawRGBBitmap` or when on low brightness #574

Closed andrewmunro closed 10 months ago

andrewmunro commented 10 months ago

Heya,

I'm trying to drive two panels to an Wroom ESP32 D1 Mini. I'm powering the board using @witnessmenow 's https://github.com/witnessmenow/ESP32-i2s-Matrix-Shield and a 5v 8a power adapter, but I'm seeing instability issues where the esp errors with "Brownout detector was triggered" and reboots.

Most examples work fine on high brightness, but it triggers constantly when I try setting the brightness low with dma_display->setBrightness8(10);

My main usecase for this is to dump pixel data from a websocket and utilise drawRGBBitmap to draw it to a screen. It seems to work for a few frames, but then triggers the brownout detector again.

Any ideas on this? Also worth mentioning it works fine if I power the board and the sign separately, so Here's my current code:

#include <stdlib.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include <WiFiManager.h>
#include <ArduinoWebsockets.h>

#define PANEL_WIDTH 64
#define PANEL_HEIGHT 32
#define PANELS_NUMBER 2
#define E_PIN_DEFAULT 18

const char* wifiSsid = "xxx";
const char* wifiPass = "xxx";

const char* websockets_connection_string = "ws://rgb.mun.sh/sub"; //Enter server adress
using namespace websockets;

MatrixPanel_I2S_DMA* dma_display;
WebsocketsClient client;

void onMessageCallback(WebsocketsMessage message) {
    uint16_t* uint16_data = (uint16_t *) message.c_str();
    dma_display->drawRGBBitmap(0, 0, uint16_data, 128, 32);
}

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("Connnection Opened");
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("Connnection Closed");
        delay(2000);
        ESP.restart();
    }
}

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

  HUB75_I2S_CFG mxconfig;
  mxconfig.mx_height = PANEL_HEIGHT;      // we have 64 pix heigh panels
  mxconfig.chain_length = PANELS_NUMBER;  // we have 2 panels chained
  mxconfig.gpio.e = E_PIN_DEFAULT;        // we MUST assign pin e to some free pin on a board to drive 64 pix height panels with 1/32 scan
  // mxconfig.latch_blanking = 4;
  // mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M;
  mxconfig.clkphase = false;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);

  // Allocate memory and start DMA display
  if (not dma_display->begin())
    Serial.println("****** !KABOOM! I2S memory allocation failed ***********");

  dma_display->setBrightness8(255);  // range is 0-255, 0 - 0%, 255 - 100%

  dma_display->fillScreenRGB888(0, 0, 255);
  dma_display->setTextSize(1);
  dma_display->setTextWrap(true);
  dma_display->setCursor(0,0);
  dma_display->print("Connecting...");

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifiSsid, wifiPass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  // run callback when messages are received
  client.onMessage(onMessageCallback);

  // run callback when events are occuring
  client.onEvent(onEventsCallback);

  // Connect to server
  bool connected = client.connect(websockets_connection_string);
  if(!connected) {
    Serial.println("Connnection Closed");
    dma_display->fillScreenRGB888(255, 0, 0);
    dma_display->setTextSize(1);
    dma_display->setTextWrap(true);
    dma_display->setCursor(0,0);
    dma_display->print("Server failed >:(");

    delay(2000);
    ESP.restart();
  }
}

void loop() {
  client.poll();
}

And here's the dump from when it crashes:

Brownout detector was triggered

ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1184
load:0x40078000,len:13260
load:0x40080400,len:3028
entry 0x400805e4

I realise this is likely not an issue with the library, but if anyone could suggest tips on how I diagnose this I would be extremely grateful!

witnessmenow commented 10 months ago

It sounds like it's a power supply issue, almost certainly confirmed by the fact it works when powering them separately.

a lot of the cheaper power supplies voltage drops fairly quickly as load increases, it's possible the voltage is dropping below what the esp32 needs. but It's weird that it works ok on higher brightness settings, I would have expected the opposite.

There is a diode on that board to stop USB from powering the Matrix when you don't want it to. A side effect of this is would drop voltage from the PSU to the esp32 even further. You could try setting the jumper to "diode bypass", which should remove this voltage drop from the diode

NOTE: if you do this, you should not plug in USB and the PSU at the same time as the PSU will be connected directly to your USB

andrewmunro commented 10 months ago

be6baa2bff

Thanks for the quick reply @witnessmenow, interestingly with the diode bypass set (top two pins) and just the USB plugged in, it seems to be working flawlessly 🙌! I suspect you're right about the power supply, it's a cheap one off Aliexpress so I'm not surprised if it's unstable.

but It's weird that it works ok on higher brightness settings, I would have expected the opposite.

I was also super confused by this as I'd anticipated the opposite too. Do you think there are any concerns powering the two panels + esp via USB long term, or should I try invest in a better PSU?

image

witnessmenow commented 10 months ago

It really depends on the project The USB is only capable of doing 500mA. Your project is pretty text heavy, which means a lot of unlit pixels, so maybe it's ok?

Does it work with diode bypass and just the PSU?

I have similar PSU and it has worked for me, so maybe it's just a bad one. The other thing to check is your soldering on the board. The fact the USB powers the matrix makes me think it's not a problem, but just something to check

Looks like a cool project!

andrewmunro commented 10 months ago

Does it work with diode bypass and just the PSU?

It works fine without the jumper, powering via USB and PSU. It doesn't work off just the PSU (jumper on bottom two pins).

Could also be the soldering on the board, but I've double checked it and all looks fine 🤷

witnessmenow commented 10 months ago

It sounds to me like the voltage from the PSU is too low by the time it gets to the esp32 in the normal setup. The diode bypass removes the voltage drop across the diode that's normally there, and that must bring it above the threshold. I've never heard of someone having this issue with these boards before.

I did redesign this section for the esp32 Trinity (the successor to the board your using) but it was more to do with allowing more current from the USB to the matrix (it uses usb-c) and the diode is still there in normal operation

The diode bypass is fine once you only power the board with either the USB or the PSU though. Or even cut the 5v line from the USB to esp32 and you could have both plugged in

andrewmunro commented 10 months ago

Sorry for the delay. I managed to burn out my old ESP by powering everything off USB with insufficient voltage/current (at-least that was my guess, I plugged it into a powerbank and the micro-usb port started smoking and died 🙈).

Anyway, I've now got two brand new ESP32s all soldered up. After some quick tests, they seem much more stable...I haven't seen a single brown out issue. Either I had a faulty ESP with a sensitive brownout trigger, or more likely my pins weren't soldered properly.

Anyway, everything looks to be running smoothly so I'll be closing this issue. Really appreciate all the help, and thanks again for the amazing library, tutorials and resources 🙌!