Timer that persists through restarts

I’m using an arduino uno with ethernet shield along with some clipon coil current sensors for a power meter solution on a boat (along with some temp/humidity). I’ve got almost everything working but I’m stuck trying to get a “time since reset” display for my kilowatt hour counter. So far my process has been to use the rtc to get a start time and then use the difference between the start time and now() to get a run time. problem is I want to have the start time saved to blynk so that the reboots wont restart the timer.

Pretty embarrassed by the state of my code since i’m definitely a copy paste coder but hopefully someone can see through the mess to point me in the right direction

#define BLYNK_PRINT Serial

#include <SPI.h>
#include <TimeLib.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <WidgetRTC.h>
#include "DHT.h"
#include "EmonLib.h"  

WidgetRTC rtc;

#define DHTPIN A5  
#define DHTTYPE DHT11  
DHT dht(DHTPIN, DHTTYPE);
EnergyMonitor emon1, emon2;   
#define W5100_CS  10
#define SDCARD_CS 4
double kilos = 0;
unsigned long startTime;
unsigned long runTime;



char auth[] = "be7167e86b374047be1414f12a05cb16";


BLYNK_WRITE(V3)
{
  kilos = param.asInt();
}

BLYNK_WRITE(V13)
{
  startTime = param.asInt();
}

BLYNK_WRITE(V10)
{
  int resetButton = param.asInt();
  if (resetButton == 1){
    kilos = 0;
    startTime = now();
    Blynk.virtualWrite(V13, startTime );
     
  }
}

BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
}

BlynkTimer timer;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void myTimerEvent()
{
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V10, millis() / 1000);


  double Irms1 = emon1.calcIrms(1480);  // Calculate Irms only
  double Irms2 = emon2.calcIrms(1480);  // Calculate Irms only
  int Power = (Irms1 + Irms2) * 120;
  kilos = kilos + (Power * (2.05/60/60/1000));
  
  Blynk.virtualWrite(V0, Irms1);

  Blynk.virtualWrite(V1, Irms2);

  Blynk.virtualWrite(V2, Power);

  Blynk.virtualWrite(V3, kilos);

 float h = dht.readHumidity();
 
 float f = dht.readTemperature(true);

 float hif = dht.computeHeatIndex(f, h);

  Blynk.virtualWrite(V4, f);

  Blynk.virtualWrite(V5, h);

  Blynk.virtualWrite(V6, hif);

  Blynk.virtualWrite(V7, (kilos * 0.15));

  runTime = now() - startTime;

  Blynk.virtualWrite(V12, runTime );

 
  
  
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  emon1.current(0, 30);
  emon2.current(1, 30);

  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card

  Blynk.begin(auth);
  // You can also specify server:
  //Blynk.begin(auth, "blynk-cloud.com", 80);
  //Blynk.begin(auth, IPAddress(192,168,1,100), 8080);

  Blynk.syncVirtual(V3);
  Blynk.syncVirtual(V13);
  // Setup a function to be called every second
  timer.setInterval(1000L, myTimerEvent);

 
}

void loop()
{
  Blynk.run();
  rtc.begin();
  timer.run(); // Initiates BlynkTimer
}

https://examples.blynk.cc/?board=ESP8266&shield=ESP8266%20WiFi&example=More%2FServerAsDataStorage%2FServerAsDataStorage_SingleValue

Save it to Blynk and sync the pin when board reset (re-connect to the Cloud)

2 Likes

As @ldb said. Which you basically are doing. I would just move your

Blynk.syncVirtual(V3);
Blynk.syncVirtual(V13); 

into

BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
}

So the sync command(s) are only executed once BLYNK is connected. You can also group the pins into one sync command.

BLYNK_CONNECTED() {
  // Synchronize time on connection
  rtc.begin();
Blynk.syncVirtual(V3, V13);
}
1 Like

Thanks for the help! Works perfectly now