Search code examples
cesp32arduino-esp32

Saving some data in power failure using brown out interrupt


I am trying to save some data to the flash memory of esp32 when power failure occurs it saves the data when brown out is called .I am using some code i found here but brown out is not triggered all the time when power is out and i dont understand how the code works can any one help in understanding and editting this for a relaiable output

#include <Arduino.h>
#include "esp_system.h"
#include "soc/soc.h"
#include "soc/cpu.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_cntl.h"
#include "esp_compiler.h"
#include <EEPROM.h>

typedef  void (*functiontype)  ( void*);

#ifdef CONFIG_BROWNOUT_DET_LVL
#define BROWNOUT_DET_LVL CONFIG_BROWNOUT_DET_LVL
#else
#define BROWNOUT_DET_LVL 5
#endif //CONFIG_BROWNOUT_DET_LVL

#define CONFIG_BROWNOUT_DET_LVL_SEL_5 1

#define countaddress 507
#define ribbonaddress 509

#define ONE_BYTES 1
#define TWO_BYTES 2
#define THREE_BYTES 3

volatile int ribbonlength=0;
volatile int count=0;

void  low_voltage_save()
 {
      byte countbytehigher = count>>8 ;
      byte countbytelower  = count& 0xFF ;
      EEPROM.write(countaddress,countbytelower);
      EEPROM.write(countaddress+1,countbytehigher);
      byte bytehigher= ribbonlength>>16;
      byte bytemid= ribbonlength>>8;
      byte bytelower=ribbonlength&0xFF;
      EEPROM.write(ribbonaddress,bytelower);
      EEPROM.write(ribbonaddress+1,bytemid);
      EEPROM.write(ribbonaddress+2,bytehigher);
      EEPROM.commit();
      Serial.println("Brown Out Function Triggerd");
            REG_WRITE(RTC_CNTL_INT_CLR_REG, RTC_CNTL_BROWN_OUT_INT_CLR);
        esp_cpu_stall(!xPortGetCoreID());
        while(1){}
        
}




void brownout_init()
{
    REG_WRITE(RTC_CNTL_BROWN_OUT_REG,
            RTC_CNTL_BROWN_OUT_ENA /* Enable BOD */
            | RTC_CNTL_BROWN_OUT_PD_RF_ENA /* Automatically power down RF */
            /* Reset timeout must be set to >1 even if BOR feature is not used */
            | (2 << RTC_CNTL_BROWN_OUT_RST_WAIT_S)
            | (BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S));

   ESP_ERROR_CHECK(rtc_isr_register((functiontype)low_voltage_save, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M) );
    // printf("Initialized BOD\n");

    REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_BROWN_OUT_INT_ENA_M);
}


int EEPROM_READ(int address,int noofbytes)
  {
    if (noofbytes== TWO_BYTES)
    {
      byte bytehigher = EEPROM.read(address+1);
      byte bytelower =  EEPROM.read (address);
    
      return(bytehigher<<8)+bytelower;
    }
    else if (noofbytes ==THREE_BYTES)
    {
      byte bytehigher= EEPROM.read (address+2);
      byte bytemid= EEPROM.read (address+1);
      byte bytelower=EEPROM.read (address);

      return(bytehigher<<16)+(bytemid<<8)+bytelower;
    }
    else if (noofbytes ==ONE_BYTES)
     {
      return EEPROM.read (address);
     }
     
     
  }
  void incrementfun()
  {
    if(ribbonlength==100000)
    {
      ribbonlength=0;
    }
    if(count==10000)
    {
      count=0;
    }
    ribbonlength++;
    count++;
    Serial.println("current count "+String(count)+" currentlength "+String(ribbonlength));
    delay(500);
  }
void setup()
 {
  brownout_init();
  Serial.begin(115200);
  EEPROM.begin(512);
  count=EEPROM_READ(countaddress,TWO_BYTES);
  ribbonlength=EEPROM_READ(ribbonaddress,THREE_BYTES);
  Serial.println("count read "+String(count));
  Serial.println("ribbonlength read "+String(ribbonlength));
 }

void loop() {
  incrementfun();
}

brown out function working in power brown out function failed to trigger


Solution

  • The ESP32's on-board BOD is mainly intended to inhibit operations that might cause corruption if they happened with too low a voltage. So it is exactly the opposite when a BOD is detected that you should carry out some i/o read/write operation to some media. The whole purpose of BOD detection is to halt the operation.

    What you need to do is:

    1. Have a voltage sensing circuit to detect the present of power supply (on VUSB or VIN);
    2. A small back-up battery or super-capacitor-based that will continue the ESP32's power for long enough for you to save the data and power down.

    You can setup the interrupt when power outage occured via your voltage sensing circuit and you do what you need to do while the power remains stable.