Skip to content

Instantly share code, notes, and snippets.

@RudyFiero
Forked from tablatronix/resetaction.ino
Created July 17, 2017 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RudyFiero/e8a99d516614d3a8b68b5c76fa040958 to your computer and use it in GitHub Desktop.
Save RudyFiero/e8a99d516614d3a8b68b5c76fa040958 to your computer and use it in GitHub Desktop.
example to use eeprom to store reset states to trigger an action on purposeful resets
/**
* detect mutiple resets in order to trigger events using resets or power cycles alone
* reset board within resettimeout(5000ms) after boot and do so resetcnt(4) times
* has led indicator of reset window and serial output for better clarity
*
* This is blocking using a delay for timeout, can easily be changed to use a timer
* This is not wear leveled, but you could replace with spiffs(slower), or use a ring counter to level it
* You could also add a smaller window for reset by adding a pre-delay, to prevent reduce flash writes during glitchy or fast power cycles
* either way USE WITH CAUTION as you are writing twice every time your reset or repower the board, soft resets and wdt should not trigger this however.
*
* @author tablatronix
**/
#include <EEPROM.h>
#ifdef ESP8266
extern "C" {
#include "user_interface.h"
}
#endif
int addr = 0; // eeprom address to store reset cnt
int resetcnt = 4; // how many resets to trigger
int resettimeout = 5000; // ms to timeout
#define RESET_LED LED_BUILTIN
const char * const RST_REASONS[] =
{
"REASON_DEFAULT_RST",
"REASON_WDT_RST",
"REASON_EXCEPTION_RST",
"REASON_SOFT_WDT_RST",
"REASON_SOFT_RESTART",
"REASON_DEEP_SLEEP_AWAKE",
"REASON_EXT_SYS_RST"
};
void blinkled(int pin, int blinks){
for(int i=0;i<blinks-1;i++){
digitalWrite(RESET_LED, LOW);
delay(100);
digitalWrite(RESET_LED, HIGH); // leave led on
delay(100);
}
}
int getResetReason(){
const rst_info * resetInfo = system_get_rst_info();
Serial.print(F("system_get_rst_info() reset reason: "));
Serial.println(RST_REASONS[resetInfo->reason]);
return resetInfo->reason;
}
void setResetCounter(int cnt){
Serial.println("RESET write: " + (String)cnt);
EEPROM.write(addr,cnt);
EEPROM.commit();
}
void handleReset(){
// these are not the resets we are looking for
if(getResetReason() != REASON_EXT_SYS_RST) return;
pinMode(RESET_LED, OUTPUT);
digitalWrite(RESET_LED, HIGH); // turn led off
EEPROM.begin(512);
// get resets cnt
int resets = EEPROM.read(addr);
Serial.println("RESET Count: " + (String)resets);
// are we there yet?
if(resets == resetcnt-1){
setResetCounter(0);
blinkled(RESET_LED,8);
handleResetCallback();
return;
}
blinkled(RESET_LED,2);
digitalWrite(RESET_LED, LOW); // turn led off
// bump resets
resets++;
setResetCounter(resets);
// timeout
delay(resettimeout);
Serial.println("RESET timeout");
setResetCounter(0);
digitalWrite(RESET_LED, HIGH); // turn led off
}
void handleResetCallback(){
Serial.println("RESET CALLBACK");
// do stuff
}
// minimal function example
bool ifResetAction(){
int numresets = 4;
int resettimeout = 5000;
int addr = 0;
bool resetstate = false;
const rst_info * resetInfo = system_get_rst_info();
if(resetInfo->reason == 6){
EEPROM.begin(512);
int resetcnt = EEPROM.read(addr);
Serial.println("RESET: reset count = "+(String)(resetcnt+1));
resetstate = (resetcnt == numresets-1);
resetcnt = (resetcnt+1) % (numresets);
EEPROM.write(addr,resetcnt);
EEPROM.commit();
if(resetstate) return true;
Serial.printf("RESET: blocking for %d ms\n",resettimeout);
delay(resettimeout);
Serial.println("RESET: timeout reached");
EEPROM.write(addr,0);
EEPROM.commit();
}
return false;
}
void setup(){
Serial.begin(115200);
delay(500);
Serial.println("\nSetup");
handleReset();
// if(ifResetAction()) Serial.println("RESET: TRIGGERED"); // minimal example function
}
void loop(){
Serial.println(millis());
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment