#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
+dht DHT; // just testing
// UPS (un-interruptible supply) software
// Peter Scargill 2017 - https://tech.scargill.net
// Blog has more - as does this video https://www.youtube.com/watch?v=44Lvdf7o4GQ
// Now set up for the 32-pixel displays - got everything down to 4 lines
// Device address for the SSD1306 display
uint8_t watchdogTimer = 0;
uint8_t watchdogState = 0;
uint8_t secondsCounter = 0;
void LcdP(char *fmt, ...)
uint8_t updateTimeout = 0;
char *theState = "standby";
void gotoXY(int x, int y)
analogReference(INTERNAL);
- if (eeSave.check != 0x52d3)
+ if (eeSave.check != 0x52d1)
watchdogState = digitalRead(WATCHDOG);
- if (digitalRead(SET) == 1)
+ if (digitalRead(SET) == 1)
- { if (sKeypressed<LONGPRESS_SET)
- if (showGraph) { showGraph=0; oled.clear(); instate=255 ; sKeypressed=0; refresh=1; }
+ { if (sKeypressed < LONGPRESS_SET)
- if (sKeypressed==LONGPRESS_SET) showGraph = SHOWGRAPH;
- if (sKeypressed>>LONGPRESS_SET) sKeypressed--;
+ if (sKeypressed == LONGPRESS_SET) showGraph = SHOWGRAPH;
+ if (sKeypressed >> LONGPRESS_SET) sKeypressed--;
if (digitalRead(UP) == 1) // special case long press is reset...
- if (uKeypressed<LONGPRESS_UP)
+ if (uKeypressed < LONGPRESS_UP)
case 1 : if (eeSave.highV < 4.3) eeSave.highV += 0.1; break;
case 9 : eeSave.smon = 1; break;
case 10 : eeSave.watchdog++;
watchdogTimer = eeSave.watchdog; watchdogTrigger = 0; break;
- case 11: eeSave.pause++; break;
+ case 11: if (eeSave.pause < 5) eeSave.pause++; break;
+ case 12: if (eeSave.twarn < 99) eeSave.twarn++; break;
- if (uKeypressed==LONGPRESS_UP) triggerShutdown = 1;
- if (uKeypressed>LONGPRESS_UP) uKeypressed--;
+ if (uKeypressed == LONGPRESS_UP) triggerShutdown = 1;
+ if (uKeypressed > LONGPRESS_UP) uKeypressed--;
if (digitalRead(DOWN) == 1)
- if (dKeypressed<LONGPRESS_DOWN)
+ if (dKeypressed < LONGPRESS_DOWN)
case 10 : if (eeSave.watchdog) eeSave.watchdog--;
watchdogTimer = eeSave.watchdog; watchdogTrigger = 0; break;
case 11 : if (eeSave.pause) eeSave.pause--; break;
+ case 12 : if (eeSave.twarn) eeSave.twarn--; break;
- if (dKeypressed==LONGPRESS_DOWN) average=0;
- if (dKeypressed>LONGPRESS_DOWN) dKeypressed--;
+ if (dKeypressed == LONGPRESS_DOWN) average = 0;
+ if (dKeypressed > LONGPRESS_DOWN) dKeypressed--;
if (eeSave.highV <= eeSave.lowV) eeSave.highV = eeSave.lowV + 0.1;
LcdP("Serial mon On/Off: %d", eeSave.smon); oled.clearToEOL();
case 10: if (updated == 0)
case 11: if (updated == 0)
- LcdP("Log period=%d mins",eeSave.pause); oled.clearToEOL();
+ case 0 : LcdP("Log period=NONE"); break;
+ case 1 : LcdP("Log period=1 sec"); break;
+ case 2 : LcdP("Log period=10 secs"); break;
+ case 3 : LcdP("Log period=1 min"); break;
+ case 4 : LcdP("Log period=10 mins"); break;
+ case 5 : LcdP("Log period=1 hr"); break;
+ default : LcdP("Log period=??"); break;
+ case 12: if (updated == 0)
+ LcdP("Twarning=%d%%", eeSave.twarn); oled.clearToEOL();
- case 12: if (updated == 0)
+ case 13: if (updated == 0)
LcdP("Version=%s", VER); oled.clearToEOL();
- case 13: updated = 0; instate = 0; break;
+ case 14: updated = 0; instate = 0; break;
if (mymillis <= millis())
mymillis += 1000; // every second we do this
+ int chk = DHT.read22(DHT22_PIN);
average = ((average * 7) + analogRead(VOLTAGE)) / 8; //i.e. average over 8 seconds 0-1023 = 0-5v - might make testing longer in the end
vol = (((float)average) * 5.0 / 824.0) * (float)eeSave.batteryOffset / 400.0; //10k/2k2
- if (eeSave.pause) { if ((mySecs%60)==0) logPause++; } else logPause++;
+ if ((mySecs % 60) == 0) logPause++;
+ if (eeSave.pause == 1) {
+ logPause++; // 1 second
+ else if (eeSave.pause == 2) {
+ if ((mySecs % 10) == 0) logPause++; // 10 seconds
+ else if (eeSave.pause == 3) {
+ if ((mySecs % 60) == 0) logPause++; // 1 minute
+ else if (eeSave.pause == 4) {
+ if ((mySecs % 600) == 0) logPause++; // 10 minutes
+ else if (eeSave.pause == 5) {
+ if ((mySecs % 3600) == 0) logPause++; // 1 hour
- if (logPause>eeSave.pause) // log 128 values 0-30 = 0-5v - 2 secs updating for testing
+ if (logPause > eeSave.pause) // log 128 values 0-30 = 0-5v - 2 secs updating for testing
- for (int a=0;a<127;a++) logit[a]=logit[a+1];
- logit[126]=((int)(vol*6.0));
+ for (int a = 0; a < 127; a++) logit[a] = logit[a + 1];
+ logit[126] = ((int)(vol * 6.0));
- if (showGraph==SHOWGRAPH)
+ if (showGraph == SHOWGRAPH)
+ for (int a = 0; a < 128; a++)
- for (int a=0;a<128;a++)
- uint32_t point=(0x80000000>>logit[a])|0x80000001;
- if ((a==0)||(a==127)) point=0xffffffff;
- oled.setCursor(a,0); oled.ssd1306WriteRamBuf((uint8_t)((point)&255));
- oled.setCursor(a,1); oled.ssd1306WriteRamBuf((uint8_t)((point>>8)&255));;
- oled.setCursor(a,2); oled.ssd1306WriteRamBuf((uint8_t)((point>>16)&255));
- oled.setCursor(a,3); oled.ssd1306WriteRamBuf((uint8_t)((point>>24)&255));
+ //uint32_t point=(0x80000000>>logit[a])|0x80000001;
+ uint32_t point = (((0x80000000 >> logit[a]) - 1) ^ 0xffffffff) | 0x80000001;
+ if ((a == 0) || (a == 127)) point = 0xffffffff;
+ oled.setCursor(a, 0); oled.ssd1306WriteRamBuf((uint8_t)((point) & 255));
+ oled.setCursor(a, 1); oled.ssd1306WriteRamBuf((uint8_t)((point >> 8) & 255));;
+ oled.setCursor(a, 2); oled.ssd1306WriteRamBuf((uint8_t)((point >> 16) & 255));
+ oled.setCursor(a, 3); oled.ssd1306WriteRamBuf((uint8_t)((point >> 24) & 255));
- showGraph--; if (showGraph==0) refresh=1;
+ showGraph--; if (showGraph == 0) refresh = 1;
- case POWERUP_STATE : // powered up everything off
- if ((stateCounter == eeSave.startTimeout) || (refresh)) {
- if (stateCounter) --stateCounter;
- gotoXY(0, 1); LcdP("Bat="); showBattery();
- gotoXY(0, 2); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
- digitalWrite(WARNING, WARNINGON); // no warning
- digitalWrite(POWER, POWEROFF);
- if (vol > eeSave.highV)
- if (stateCounter == 0) {
- stateCounter = eeSave.goodTimeout;
+ case POWERUP_STATE : // powered up everything off
+ if ((stateCounter == eeSave.startTimeout) || (refresh)) {
- if (stateCounter == 0) {
- stateCounter = eeSave.offTimeout;
+ if (stateCounter) --stateCounter;
+ gotoXY(0, 1); LcdP("Bat="); showBattery();
+ gotoXY(0, 2); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
+ digitalWrite(WARNING, WARNINGON); // no warning
+ digitalWrite(POWER, POWEROFF);
+ if (vol > eeSave.highV)
+ if (stateCounter == 0) {
+ stateCounter = eeSave.goodTimeout;
+ if (stateCounter == 0) {
+ stateCounter = eeSave.offTimeout;
- case GOOD_STATE : // battery is above upper threshold
- if ((stateCounter == eeSave.goodTimeout) || (refresh)) {
- LcdP("** Pi Power %s **", VER);
- watchdogTimer = eeSave.watchdog;
- if (stateCounter) --stateCounter;
- if (++secondsCounter == 60)
- watchdogTimer--; // only do this when battery is ok
- if (watchdogTimer == 0) watchdogTrigger = 1;
+ case GOOD_STATE : // battery is above upper threshold
+ if ((stateCounter == eeSave.goodTimeout) || (refresh)) {
+ LcdP("** Pi Power %s **", VER);
+ watchdogTimer = eeSave.watchdog;
- watchdogTrigger = 0; // reboot
- stateCounter = eeSave.warningTimeout;
- gotoXY(0, 1); if (watchdogTimer) LcdP("WDT: %d:%02d ",watchdogTimer,59-secondsCounter);
- LcdP("Bat: "); showBattery();
- gotoXY(0, 2); LcdP("HiV=%d.%dv LoV=%d.%dv", int(eeSave.highV), ((int(eeSave.highV * 100)) % 100) / 10, int(eeSave.lowV), ((int(eeSave.lowV * 100)) % 100) / 10); oled.clearToEOL();
- digitalWrite(WARNING, WARNINGOFF); // no warning
- digitalWrite(POWER, POWERON);
- gotoXY(0, 3); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
- if (stateCounter == 0) {
+ if (stateCounter) --stateCounter;
+ if (++secondsCounter == 60)
+ watchdogTimer--; // only do this when battery is ok
+ if (watchdogTimer == 0) watchdogTrigger = 1;
+ watchdogTrigger = 0; // reboot
stateCounter = eeSave.warningTimeout;
- stateCounter = eeSave.goodTimeout - 1;
- if ((instate == 0) && (vol >= eeSave.lowV))
+ if (watchdogTimer) LcdP("WDT: %d:%02d ", watchdogTimer, 59 - secondsCounter);
- LcdP("On= %04ldd %02ld:%02ld:%02ld", upSecs / 86400, (upSecs / 3600) % 24, (upSecs % 3600) / 60, upSecs % 60);
+ temperatureReading = (int)DHT.temperature;
+ humidityReading = (int)DHT.humidity;
+ if (mySecs & 2) LcdP("Tem=%dc ", temperatureReading); else LcdP("Hum=%d%% ", humidityReading);
+ if (temperatureReading>eeSave.twarn) tone(TONE, eeSave.tone, 100);
- LcdP("Off=%04ldd %02ld:%02ld:%02ld", downSecs / 86400, (downSecs / 3600) % 24 , (downSecs % 3600) / 60, downSecs % 60);
+ LcdP("Bat="); showBattery();
+ gotoXY(0, 2); LcdP("HiV=%d.%dv LoV=%d.%dv", int(eeSave.highV), ((int(eeSave.highV * 100)) % 100) / 10, int(eeSave.lowV), ((int(eeSave.lowV * 100)) % 100) / 10); oled.clearToEOL();
+ digitalWrite(WARNING, WARNINGOFF); // no warning
+ digitalWrite(POWER, POWERON);
+ gotoXY(0, 3); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
+ if (stateCounter == 0) {
+ stateCounter = eeSave.warningTimeout;
+ stateCounter = eeSave.goodTimeout - 1;
+ if ((instate == 0) && (vol >= eeSave.lowV))
+ LcdP("On= %04ldd %02ld:%02ld:%02ld", upSecs / 86400, (upSecs / 3600) % 24, (upSecs % 3600) / 60, upSecs % 60);
+ LcdP("Off=%04ldd %02ld:%02ld:%02ld", downSecs / 86400, (downSecs / 3600) % 24 , (downSecs % 3600) / 60, downSecs % 60);
- case TIMEOUT_STATE : // battery has dropped below upper threshold - ALWAYS timeout to OFF_STATE
- if ((stateCounter == eeSave.warningTimeout) || (refresh)) { refresh=0; oled.clear(); }
- gotoXY(0, 0); LcdP("Timoutout. Bat="); showBattery();
- gotoXY(0, 1); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
- digitalWrite(WARNING, WARNINGON); // warning
- digitalWrite(POWER, POWERON);
- if (eeSave.tone) tone(TONE, eeSave.tone, 100);
- if (stateCounter) --stateCounter;
- if (stateCounter == 0 ) {
- stateCounter = eeSave.offTimeout;
- case OFF_STATE : // everything off
- if ((stateCounter == eeSave.offTimeout) || (refresh)) { refresh=0; oled.clear(); }
- if (stateCounter) --stateCounter;
- if (vol <= eeSave.highV) {
- digitalWrite(WARNING, WARNINGON); // LEAVE ON ie LOW
- digitalWrite(POWER, POWEROFF);
- if (vol > eeSave.highV)
- gotoXY(0, 0); LcdP("Warming up. Bat="); showBattery();
+ case TIMEOUT_STATE : // battery has dropped below upper threshold - ALWAYS timeout to OFF_STATE
+ if ((stateCounter == eeSave.warningTimeout) || (refresh)) {
+ gotoXY(0, 0); LcdP("Timoutout. Bat="); showBattery();
gotoXY(0, 1); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
- if (stateCounter == 0) {
- stateCounter = eeSave.goodTimeout;
+ digitalWrite(WARNING, WARNINGON); // warning
+ digitalWrite(POWER, POWERON);
+ if (eeSave.tone) tone(TONE, eeSave.tone, 100);
+ if (stateCounter) --stateCounter;
+ if (stateCounter == 0 ) {
+ stateCounter = eeSave.offTimeout;
- stateCounter = eeSave.offTimeout - 1; // avoid clearscreen
- // gotoXY(0, 3); oled.clearToEOL();
- case SHUTDOWN_STATE: // everything off and stays off... hold the SET button.... set state to SHUTDOWN_STATE and stateCounter to SHUTDOWN_PERIOD
- if ((stateCounter == SHUTDOWN_PERIOD) || (refresh))
- gotoXY(0, 2); LcdP("Shutdown commencing.."); oled.clearToEOL();
- digitalWrite(WARNING, WARNINGON); // warning
+ case OFF_STATE : // everything off
+ if ((stateCounter == eeSave.offTimeout) || (refresh)) {
+ if (stateCounter) --stateCounter;
+ if (vol <= eeSave.highV) {
+ digitalWrite(WARNING, WARNINGON); // LEAVE ON ie LOW
+ digitalWrite(POWER, POWEROFF);
+ if (vol > eeSave.highV)
- gotoXY(0, 2); LcdP("Shutdown COMPLETE"); oled.clearToEOL();
- digitalWrite(WARNING, WARNINGON); // LEAVE ON ie LOW
- digitalWrite(POWER, POWEROFF);
+ gotoXY(0, 0); LcdP("Warming up. Bat="); showBattery();
+ gotoXY(0, 1); LcdP("Wait=%03d secs", stateCounter); oled.clearToEOL();
+ if (stateCounter == 0) {
+ stateCounter = eeSave.goodTimeout;
+ stateCounter = eeSave.offTimeout - 1; // avoid clearscreen
+ // gotoXY(0, 3); oled.clearToEOL();
- else if (digitalRead(DOWN) == 0) {
- stateCounter = eeSave.startTimeout;
+ case SHUTDOWN_STATE: // everything off and stays off... hold the SET button.... set state to SHUTDOWN_STATE and stateCounter to SHUTDOWN_PERIOD
+ if ((stateCounter == SHUTDOWN_PERIOD) || (refresh))
+ gotoXY(0, 2); LcdP("Shutdown commencing.."); oled.clearToEOL();
+ digitalWrite(WARNING, WARNINGON); // warning
+ gotoXY(0, 2); LcdP("Shutdown COMPLETE"); oled.clearToEOL();
+ digitalWrite(WARNING, WARNINGON); // LEAVE ON ie LOW
+ digitalWrite(POWER, POWEROFF);
+ else if (digitalRead(DOWN) == 0) {
+ stateCounter = eeSave.startTimeout;