ESP32-Cam Brownout Faults

ESP32-Cam Brownout Faults

The ESP32-Cam module is an inexpensive platform that can be developed for many purposes. It does have some drawbacks. Compiling with the Arduino IDE can be much slower compared to native AVR platforms. Another issue is the “Brownout detector was triggered” message on the debug window. Slow compilation was covered in another post, https://www.cloudacm.com/?p=3998. This post will explore some ways to deal with the brownout fault.

When the ESP32-Cam module boots, it will perform a series of checks and either run or halt if a brownout detection occurs. If a serial debug window isn’t active, the module will just appear to be broken. It’s important to note that the serial debug is the only simple way to know if a brownout is occurring. Here are the suggested causes and fixes for brownout faults.

Verify that the power source is adequate. According to this site https://www.dfrobot.com/product-1879.html, a 5V 2A source should be sufficient.

Filter noise from the power source using a capacitor between the VCC and GND pins. This site seemed to suggest that it improved the operation, https://stackoverflow.com/questions/65762611/esp32-why-wifi-connection-causes-brownout-detector-was-triggered-after-deep-sl

Perform a hardware reset. The onboard reset button is not always accessible, some have modified the board for no good reason. The ground reset pin is located next to GPIO 1. This is repeatedly documented incorrectly and is more often than not labelled as GND, when in fact it is the RESET. Bringing that pin to GND will hardware reset the module.

Perform a software reset. This however will not address the brownout fault, as the module will fail to load the software to do a reset. But it is worth mentioning as it can provide a reset for other circumstances. The code to do so is “ESP.restart();”, see https://techtutorialsx.com/2017/12/03/esp32-arduino-software-reset/ for more details.

Use a GPIO pin as a hardware reset. Set the GPIO pin high with a high value resistor connected between the GPIO pin and the reset ground pin located next to GPIO 1. Then set the GPIO pin low when a reset is needed. Again, this doesn’t address an boot brownout trigger, but is a viable reset option.

Disabling the ESP32 Brownout detector using this code. This code is needed in its entirety, more details can be found here, https://iotespresso.com/how-to-disable-brownout-detector-in-esp32-in-arduino/

#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
void initialize() {
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
}

Delay initializing power intensive resources until the boot process completes. The module sub devices that fall into this scope are the Wifi, MicroSD storage, and Camera modules. Some mention was in this link, https://stackoverflow.com/questions/65762611/esp32-why-wifi-connection-causes-brownout-detector-was-triggered-after-deep-sl.

Use external peripheral power controls using GPIO pins to control power of external peripherals that share the power rail or draw power from the onboard regulator. This could be done by using a MOSFET or some other switching transistor. This can also be a useful technique for battery powered operation. As the battery supply voltage starts to drop, once it crosses a threshold, peripherals could be powered off to extend battery life.

Eliminate any peripheral overdraw. Be sure that the system can handle the load. Are all peripherals within the limits of what the supply and regulator can handle? Verify with measurements that they operate as defined in the datasheets.

Use a voltage supervisor to only operate the module within acceptable ranges. It has been demonstrated that under voltage states can induce unexpected behavior by devices. This post expands on that concept by leveraging that condition as a vulnerability.

This covers most of the common reasons for brownout faults on the ESP32-Cam module. A combined approach should eliminate these types of faults.

It’s worth noting that some timer functions that rely on millis() could suffer from rollover faults. Although this is a different class of fault, it is worth mention. Some code suggestions offer ways to avoid this, https://davidmac.pro/posts/2020-12-22-arduino-millis-roll-over/. Another way to address this is by performing software resets at set intervals or thresholds.

While on the topic of millis(), it is still common for code examples to use delay(). This is quick and easy but it essentially pauses all operation of the device for that delay period. Here are two code examples of a blinking LED. Using miilis() lets the system run other tasks and is less wasteful.

// Delay Code

const int ledPin = 33;  
const long interval = 1000; 

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin( 115200 );
}

void loop() {
  Serial.println(millis());
  digitalWrite(ledPin, HIGH);   
  delay(interval);                      
  digitalWrite(ledPin, LOW);   
  delay(interval);                     
}
// Millis Code

const int ledPin = 33;  
const long interval = 1000; 

int ledState = LOW; 
unsigned long previousMillis = 0; 
unsigned long currentMillis = 0; 

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledState == LOW) {
      Serial.println(millis());
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    digitalWrite(ledPin, ledState);
  }
}

 

Comments are closed.