Brownout issues with WaveShare’s ESP32-S3-Touch-LCD-4.3
I bought some ESP32-S3-Touch-LCD-4.3 devices from WaveShare. Up until now I’ve only developed Arduino devices, and I wanted something else. For another project of mine I built a custom thermostat solution based on Home Assistant. I wanted to use these devices to build my own thermostat screens.
The device itself is very nice. It’s a combination of an ESP32-S3 dev board and a 4.3" LCD screen with capacitive touch. They provide source code to give you enough to build anything you want on it. I chose ESP-IDF with Visual Studio Code and LVGL to build the UI. The end result is very nice.
However, as the title suggests, I’ve had severe brownout issues. I didn’t want to have the screen on all the time. There’s a PIR motion sensor in the device and the screen only turns on if it sees motion, or if you touch the panel.
To do this, I’m using code provided by WaveShare on their Wiki:
int ret;
uint8_t write_buf = 0x01;
ret = i2c_master_write_to_device(I2C_MASTER_NUM, 0x24, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
ESP_LOGI(TAG,"0x48 0x01 ret is %d",ret);
write_buf = 0x0E;
ret = i2c_master_write_to_device(I2C_MASTER_NUM, 0x38, &write_buf, 1, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
ESP_LOGI(TAG,"0x70 0x00 ret is %d",ret);It really wasn’t obvious that this was the code to turn on or off the LCD backlight. After some cleanup I ended up with this code:
constexpr uint8_t IO_EXPANDER_TOUCH_PANEL_RESET = 1 << 1;
constexpr uint8_t IO_EXPANDER_LCD_BACKLIGHT = 1 << 2;
constexpr uint8_t IO_EXPANDER_LCD_RESET = 1 << 3;
constexpr uint8_t IO_EXPANDER_SD_CS = 1 << 4;
constexpr uint8_t IO_EXPANDER_USB_SELECT = 1 << 5;
void set_ch422g_pins(uint8_t pins) {
uint8_t write_buf = 0x01;
ESP_ERROR_CHECK(i2c_master_write_to_device(I2C_MASTER_NUM, ESP_IO_EXPANDER_I2C_CH422G_ADDRESS_000, &write_buf, 1,
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS));
write_buf = pins;
ESP_ERROR_CHECK(i2c_master_write_to_device(I2C_MASTER_NUM, CH422G_REG_OUT, &write_buf, 1,
I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS));
}
set_ch422g_pins(IO_EXPANDER_TOUCH_PANEL_RESET | IO_EXPANDER_LCD_BACKLIGHT | IO_EXPANDER_LCD_RESET);You add or remove the IO_EXPANDER_LCD_BACKLIGHT flag based on whether you want to have the LCD backlight on or off. Don’t forget to add locking around I2C calls. In the case of the WaveShare device, add it around the call to this method, and the calls into the esp_lcd_touch methods inside the lvgl_touch_cb method provided in the WaveShare samples. See the FreeRTOS documentation on xSemaphoreTake on how to do this. Before I added locking I got spurious “I2C read error!” error messages that the device wouldn’t recover from.
This works, but, it causes brownout issues. The first thing I noticed is that every time I turned the backlight on, the USB connection would drop. You would hear the disconnect and connect sounds in Windows. However, after I installed the devices, I started getting restartes because of the brownout watchdog being triggered in ESP-IDF.
Get Pieter van Ginkel’s stories in your inbox
Join Medium for free to get updates from this writer.
There are different reasons for brownout restarts in ESP:
- Bad adapter.
- Bad cables.
- WiFi or Bluetooth starting up.
- Insufficient capacitors.
I’ve tried the following before ending up with the solution below:
- Better adapter and short, good cables. This helps somewhat, but the problems still persist.
- Putting WiFi and the CPU into a low power state. This didn’t help at all.
- Putting a capacitor into the USB power cable helped slightly, but not close to enough.
- Adding a Li-Po battery didn’t have any result. The device wouldn’t draw power from the battery unless I disconnected the USB cable.
I ended up adding a capacitor to the board. It’s not unheard of to do this. Tom Nardi wrote up a similar solution in his Hackaday article where he mods his Raspberry Pi board.
I’ve installed a 470 µF electrolytic capacitor over the output pins of the LDO:
The LDO is responsible for converting the input power into 3.3V for the board. Putting the capacitor over the output pins helps handling power drops in the board. Because the device wasn’t drawing power from the battery, I concluded that adding a capacitor over the input pins wouldn’t help.
Also, the pins of the LDO are quite big, which helps soldering on the capacitor.
The data sheet for the capacitor is here: SGM2212, and the pinout is as follows:
On the board, the top pin is the GND, and the middle pin the VOUT. Electrolytic capacitors are polarized, so take care to put it in right. The end result looks like this:
It’s not the prettiest solution, but it did completely get rid of my brownout issues. I put in a 470 µF capacitor because I had them available and I have room in the case to support it. A smaller one may suffice, but I didn’t attempt it.









