All,
At the risk of sharing something that is blindingly obvious, I wanted to close the loop on what happened with this week’s outage and how I had not prepared my battery powered device to cope.
My electron sits out in a park about a mile from the parking lot and the nearest outlet. When the telecom provider mishap occurred, it got stuck in an endless attempt to connect (flashing green) and drained the battery overnight. My usual error corrections (soft and hard reset) did not take it out of this state.
What I realized is that I should rewrite my code so that the device will function correctly (counting people) and only attempt to connect for a few tries every hour. The first step in this was to rewrite the Setup() of my code so, there is no connection to Particle. Here is what I came up with:
void setup() // Note: Disconnected Setup()
{
pinMode(intPin,INPUT); // PIR Sensor Interrupt pin
pinMode(wakeUpPin,INPUT); // This pin is active HIGH
pinMode(blueLED, OUTPUT); // declare the Blue LED Pin as an output
pinMode(tmp36Shutdwn,OUTPUT); // Supports shutting down the TMP-36 to save juice
digitalWrite(tmp36Shutdwn, HIGH); // Turns on the temp sensor
pinMode(donePin,OUTPUT); // Allows us to pet the watchdog
pinMode(hardResetPin,OUTPUT); // For a hard reset active HIGH
power.begin(); // Settings for Solar powered power management
power.disableWatchdog();
power.disableDPDM();
power.setInputVoltageLimit(4840); //Set the lowest input voltage to 4.84 volts. This keeps my 5v solar panel from operating below 4.84 volts (defauly 4360)
power.setInputCurrentLimit(900); // default is 900mA
power.setChargeCurrent(0,0,0,0,0,0); // default is 512mA matches my 3W panel
power.setChargeVoltage(4112); // default is 4.112V termination voltage
power.enableDPDM();
attachInterrupt(wakeUpPin, watchdogISR, RISING); // The watchdog timer will signal us and we have to respond
attachInterrupt(intPin,sensorISR,RISING); // Will know when the PIR sensor is triggered
char responseTopic[125];
String deviceID = System.deviceID(); // Multiple Electrons share the same hook - keeps things straight
deviceID.toCharArray(responseTopic,125);
Particle.subscribe(responseTopic, UbidotsHandler, MY_DEVICES); // Subscribe to the integration response event
Particle.variable("HourlyCount", hourlyPersonCount); // Define my Particle variables
Particle.variable("DailyCount", dailyPersonCount); // Note: Don't have to be connected for any of this!!!
Particle.variable("Signal", Signal);
Particle.variable("ResetCount", resetCount);
Particle.variable("Temperature",temperatureF);
Particle.variable("Release",releaseNumber);
Particle.variable("stateOfChg", stateOfCharge);
Particle.function("startStop", startStop); // Define my Particle functions
Particle.function("resetFRAM", resetFRAM);
Particle.function("resetCounts",resetCounts);
Particle.function("Reset",resetNow);
Particle.function("HardReset",hardResetNow);
Particle.function("SleepInFive",sleepInFive);
Particle.function("SendNow",sendNow);
if (!fram.begin()) { // You can stick the new i2c addr in here, e.g. begin(0x51);
snprintf(Status,13,"Missing FRAM"); // Can't communicate with FRAM - fatal error
state = ERROR_STATE;
}
else if (FRAMread8(VERSIONADDR) != VERSIONNUMBER) { // Check to see if the memory map in the sketch matches the data on the chip
snprintf(Status,13,"Erasing FRAM");
ResetFRAM(); // Reset the FRAM to correct the issue
if (FRAMread8(VERSIONADDR) != VERSIONNUMBER) state = ERROR_STATE; // Resetting did not fix the issue
}
resetCount = FRAMread8(RESETCOUNT); // Retrive system recount data from FRAMwrite8
if (System.resetReason() == RESET_REASON_PIN_RESET) // Check to see if we are starting from a pin reset
{
resetCount++;
FRAMwrite8(RESETCOUNT,static_cast<uint8_t>(resetCount)); // If so, store incremented number - watchdog must have done This
}
Time.zone(-5); // Set time zone to Eastern USA daylight saving time
takeMeasurements();
StartStopTest(1); // Default action is for the test to be running
timeTillSleep = sleepDelay; // Set initial delay for 60 seconds
lastEvent = millis();
if (state != ERROR_STATE) state = IDLE_STATE; // IDLE unless error from above code
}
Now, if Particle’s telecommunications partners drop the ball in the future, my device will just keep counting and not drain the battery.
Hope this helps and please let me know if I missed anything.
Chip