ESP32 'RTC' time update - it's not [SOLVED]

I am installing a new ESP32 and used existing working code from another
ESP32 installation for the new sketch.
The issue is after the time is retreived upon the processor initialization it is not being updatedrunning on the new sketch.
Since the time (hr,min,sec) integers are declared outside the getTime function calls I thought the time would then be updated to the processor to reflect "current time." But as you can see in the serial monitor printout the time is locked on the last scan values and only changes when the function is called again.
I have tried different processor assignments (DEV Module versus WROVER Module)
thinking maybe the issue was with the type assignment. On the working ESP it is a ESP32 WROOM but the new ESP is WiFi+BT+BLE MCU.

There is something I have overlooked somewhere but cannot put my finger on it.
Using IDE 2.32.


```cpp
#include <WiFi.h>
// #include <math.h>
// #include "time.h"
#include <esp_sntp.h>

WiFiClient client;
WiFiServer server(80);  

int Initial_Connect_Attempts = 0;
int Try_Count = 0;

char wifissid[18] = "Homestead-LAN_EXT"; 
char wifipass[13] = "********";           

unsigned long current_Millis = 0;
unsigned long request_time_Millis = 10000;  // 1 hour = 3600000
unsigned long timeHack_Millis = 0;

int time_month = 0;
int time_day = 0;
int time_hour = 0;
int time_min =  0;
int time_sec =  0;

void setup() {
  Serial.begin(115200);
  while (WiFi.status() != WL_CONNECTED) {
    Initial_Connect_Attempts++;
    Serial.println(F("Attempting to Connect To Local Network:   "));
    Serial.println(wifissid);
    WiFi.begin(wifissid, wifipass);
    delay(4000);
    if (Initial_Connect_Attempts == 5) {
      Serial.println(F("5 LAN connect attempts unsuccessful; going to connectToWifi()"));
      connectToWiFi();
    }
    Serial.print(".");
  }
  Serial.println("");
  Serial.print(F("Connected to WiFi network with IP Address: "));
  Serial.println(WiFi.localIP());
  Serial.println(F("Attempting to connect to local WPA network..."));

  initTime("CST6CDT,M3.2.0,M11.1.0");  // https://sites.google.com/a/usapiens.com/opnode/time-zones
  server.begin();
  // you're connected now, so print out the status:
  Serial.print("WiFi Status:  ");
  Serial.println(WiFi.status());
  Serial.println();
  Serial.print(F("ESP Board MAC Address:  "));
  Serial.println(WiFi.macAddress());
}

void loop() {
  current_Millis = millis();

  if ((current_Millis - timeHack_Millis) >= request_time_Millis) {  
    GetLocalTime();
    timeHack_Millis = current_Millis;
  }
  Serial.println();
  Serial.print("Time = Hr: ");
  Serial.print(time_hour);
  Serial.print(" Min: ");
  Serial.print(time_min);
  Serial.print(" Sec: ");
  Serial.print(time_sec);
  Serial.println();
delay(3000);  
}
void setTimezone(const char* timezone) {
  Serial.print(F("Setting Timezone to "));
  Serial.println(timezone);
  setenv("TZ", timezone, 1);
  tzset();
}
void initTime(const char* timezone) {
  struct tm timeinfo;
  Serial.println(F("Getting time from NTP server"));
  configTime(0, 0, "pool.ntp.org");  // First connect to NTP server, use 0 TZ offset
  if (!getLocalTime(&timeinfo)) {
    Serial.println(F("  Failed to obtain time"));
    return;
  }
  Serial.println(F("OK, Got the time from NTP"));
  setTimezone(timezone);  // then set your timezone
}
void GetLocalTime() {  // this function monitors current time of day to initiate
  struct tm timeinfo;  // pump counter reset at midnight
  if (!getLocalTime(&timeinfo)) {
    Serial.println(F("Failed to obtain time"));
    return;
  }
  time_hour = timeinfo.tm_hour;  // tm structure element "hour" from time.h
  time_min = timeinfo.tm_min;    //                     "minute"  "    "
  time_sec = timeinfo.tm_sec;    //                      "second"

  time_month = timeinfo.tm_mon + 1;  // + 1 is due to way time.h assigns month values (starts w/ 0)
  time_day = timeinfo.tm_mday;

  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z ");
  Serial.println();
}
void connectToWiFi() {
  Try_Count = 0;
  while (WiFi.status() != WL_CONNECTED) {
    Try_Count++;
    WiFi.disconnect();
    WiFi.begin(wifissid, wifipass);
    vTaskDelay(10000);
    if (Try_Count == 10) {
      Serial.println(F("..... 10 attempts failed....rebooting processor..."));
      ESP.restart();  // reboot processor!!!
    }
  }
  // WiFi.onEvent( WiFiEvent );    > define WiFiEvent to do ???
}

Serial Monitor Output:

Connected to WiFi network with IP Address: 192.168.1.178
Attempting to connect to local WPA network...
Getting time from NTP server
OK, Got the time from NTP
Setting Timezone to CST6CDT,M3.2.0,M11.1.0
WiFi Status: 3

ESP Board MAC Address: 24:DC:C3:98:8A:E0

Time = Hr: 0 Min: 0 Sec: 0
Friday, June 28 2024 14:10:13 zone CDT -0500

Time = Hr: 14 Min: 10 Sec: 13

Time = Hr: 14 Min: 10 Sec: 13

Time = Hr: 14 Min: 10 Sec: 13

Time = Hr: 14 Min: 10 Sec: 13
Friday, June 28 2024 14:10:25 zone CDT -0500

Time = Hr: 14 Min: 10 Sec: 25

Time = Hr: 14 Min: 10 Sec: 25

Time = Hr: 14 Min: 10 Sec: 25

Time = Hr: 14 Min: 10 Sec: 25
Friday, June 28 2024 14:10:37 zone CDT -0500

Time = Hr: 14 Min: 10 Sec: 37

What mechanism do you imagine would do that?

time_hour is a variable, no matter where it is declared, its value changes only when it appears on the left hand side of an assignment statement.

getLocalTime() is the only code that, um, gets the time. From the structure it fills in, more convenient variables are subsequently assigned values.

Leaving aside some things that just aren't happening in this sketch, there is no way to establish and exploit any kind of magic connection between what the RTC has in its registers and what is currently in a simple integer in your code.

This is a common beginner's misapprehension. Take this what I saw

// distance
unsigned long distance = speed * time;

distance is assigned an initial value, but distance will not track changes to speed or time should either change. If you want the distance, you must assign again to it the product of speed and time.

Code is literal and it is alive and in these dinky programs you don't get to use, or need to worry about, anything happening that isn't literally in the code.

Of course the RTC is cranking away in the background, but to know what is in its registers it must be interrogated again, in this case via getLocalTime(), or at a slightly higher level, a call to that function that is within your GetLocalTime() function.

Just call it, and it updates all those nice variables for the hour, minute and so forth.

I just noticed the names of those functions differs by only CapitalIZation. This is sufficient for the compiler, but burdens readers of your code as they must be as smart alla time to see which function it is you are calling anywhere either is in the source code.

And maybe yourself, too, one day. Just sayin'.

HTH

a7

You could see you are in good company, if I have understood your question, by searching these fora with this:

@alto777 "magic connection"

Haha, you'll get the same hits leaving off @alto777 - others have ceratinly pointed this out as necessary, but they must refer to it otherwise.

a7

The "GetLocalTime()" function is responsible for updating the time.
And it is only called every 10 seconds, (request_time_Millis = 10000;),
so printing h, m and s every delay of 3000 the value will always be the same.

Why do you use this 10 second variable and this 3 second delay?

If you put the printout of h, m and s inside the if that calls the GetLocalTime(0) function, it will print correctly.

Hth

Simulated @ ESP32Timer - Wokwi ESP32, STM32, Arduino Simulator

I am corrected. This is the magical connection I failed to see in the code. I see how it works, but don't have an eye for that kind of thing, as I am usually on my hands and knees doing wonderful things like that all by myseff.

Sry!

a7

1 Like

I guess what is confusing me is that the code works in another ESP. I can do a webpage request and have the time at the top of the displayed page. If I do another request within just a few seconds it gives me the correct current time; in that sketch I am doing a getTime function once an hour.

Please post that sketch

That is just for this test sketch. The 3 secs allows me to see the serial monitor text a little slower and the 10 seconds is actually a once an hour getTime call in the code that works.

But only when the if statement executes; which is every ten seconds as it currently is setup. I am wanting to reference the time variable that is being updated by the processor clock each void loop cycle.

Here ya go Bob -

Main sketch:


```cpp


/*
      Hardware/Web assignments: ID: esp32-EAA4C8    MAC:   C4:DD:57:EA:A4:C8
    
*/
#include "hashtag_includes.h"  // see tabs at top
#include "constants.h"

//  ***************** VOID SETUP ***************
void setup() {
  startup_Millis = millis();

  pinMode(System_Alm_LED, OUTPUT);  // Onboard Visual Alm Indicator
  pinMode(ONBOARD_LED, OUTPUT);     //  Blink LED function
  pinMode(Alarm_Relay, OUTPUT);     //  Alarm relay
  pinMode(Pressure_Switch, INPUT);  // Alarm Input
  pinMode(Pump_Run_Status, INPUT);  // Spare Dry Contacts on 220v pump contactor
  pinMode(System_Reset, INPUT);     // Reset/clear system alarms

  digitalWrite(Alarm_Relay, LOW);

  // delay(300000);  // allow voltage stabilization on startup & time for routers to reset after a power outage

  Serial.begin(115200);
  while (WiFi.status() != WL_CONNECTED) {
    Initial_Connect_Attempts++;
    Serial.println("Attempting to Connect To Local Network:   ");
    Serial.println(wifissid);
    WiFi.begin(wifissid, wifipass);
    delay(4000);
    if (Initial_Connect_Attempts == 5) {
      Serial.println("5 LAN connect attempts unsuccessful; going to connectToWifi()");
      connectToWiFi();
    }
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Attempting to connect to local WPA network...");

  initTime("CST6CDT,M3.2.0,M11.1.0");  // https://sites.google.com/a/usapiens.com/opnode/time-zones
  server.begin();
  // you're connected now, so print out the status:
  Serial.print("WiFi Status:  ");
  Serial.println(WiFi.status());
  Serial.println();
  Serial.print("ESP Board MAC Address:  ");
  Serial.println(WiFi.macAddress());

  DS18B20.begin();                      // initialize the DS18B20 space sensor
  DS18B20.setWaitForConversion(false);  // this speeds up processor throughput/execution time
}

void loop() {
  UNO_run_cycle_start = millis();
  current_Millis = millis();

  printLocalTime();  // used to determine midnight reset of "daily" pump counters
  //                                                    ************************* Processor Run LED ************************
  if (current_Millis - previous_LED_Millis >= interval) {
    previous_LED_Millis = current_Millis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ONBOARD_LED, ledState);
  }
  if ((current_Millis - read_Temps_Time) >= read_Temps_interval) {  // delay reading DS18B20s to every X seconds for added stability
    space_temp_1 = DS18B20.getTempFByIndex(0);                      // read temperature in °F
    read_Temps_Time = current_Millis;
  }
  DS18B20.requestTemperatures();         // send the command to get temperatures
  sp_temp_1 = space_temp_1 + tmp_adj_1;  // sensor calibration

  pressure_switch_state = digitalRead(Pressure_Switch);  //Pressure Switch Input Pin Read
  pump_run_contacts = digitalRead(Pump_Run_Status);      // spare set of contacts from 220 volt contactor
  alarm_reset = digitalRead(System_Reset);               // switch input activated by human operator

  //                            ************************* System Alarm LED ************************
  if (bldg_alarm_state == true)
    if ((current_Millis - system_alm_LED_Millis) >= interval_1) {
      system_alm_LED_Millis = current_Millis;
      if (Sys_Alm_ledState == LOW) {
        Sys_Alm_ledState = HIGH;
      } else {
        Sys_Alm_ledState = LOW;
      }
      digitalWrite(System_Alm_LED, Sys_Alm_ledState);
    }
  //               ***************** System Alarm Reset/Clear **************
  if (alarm_reset == HIGH) {  // reset flags & audibles
    strcpy(Bldg_Alarm, "OFF");
    strcpy(Alm_Relay, "OFF");
    strcpy(Temp_Alm, "OFF");
    strcpy(Pump_Alm, "OFF");
    strcpy(Pressure_Alm, "OFF");

    bldg_alarm_state = false;
    bldg_alm_flag = false;
    pump_alarm = false;
    pump_alarm_state = false;
    pressure_alarm = false;
    press_alarm_state = false;

    alm_temp_hour = 0;
    alm_temp_min = 0;
    alm_press_hour = 0;
    alm_press_min = 0;
    alm_pmp_run_hour = 0;
    alm_pmp_run_min = 0;

    temp_alarm = false;
    temp_alarm_state = false;
    confirm_temp_alm_state = false;
    pump_run_state = false;

    highest_space_tmp = 0;
    lowest_space_tmp = 80;
    
    digitalWrite(Alarm_Relay, LOW);
    digitalWrite(System_Alm_LED, LOW);
    delay(2000);
    digitalWrite(System_Alm_LED, HIGH);  //      pulse LED to show reset in process
    delay(300);
    digitalWrite(System_Alm_LED, LOW);
    delay(600);
    digitalWrite(System_Alm_LED, HIGH);
    delay(300);
    digitalWrite(System_Alm_LED, LOW);
    delay(600);
    digitalWrite(System_Alm_LED, HIGH);  //     LED stays ON during pump recovery period
    delay(20000);                        //          20 seconds to allow pump time to rebuild line pressure
    digitalWrite(System_Alm_LED, LOW);
    delay(1000);
    digitalWrite(System_Alm_LED, HIGH);  //         pulse LED to show pump delay period has expired
    delay(500);
    digitalWrite(System_Alm_LED, LOW);
  }
  //              ***************** Pump Run Time Monitor & Alarm/Report Function ********
  if (pump_run_contacts == HIGH) {
    pump_ON = true;
    pmp_run_state = 1;
    pump_OFF_timeHack = false;
    pmp_OFF_hr = 0;
    pmp_OFF_min = 0;
    pmp_OFF_month = 0;
    pmp_OFF_day = 0;
    strcpy(Pump_Status, "ON");
  } else {
    pump_ON = false;
    pmp_run_state = 0;
    strcpy(Pump_Status, "OFF");
  }
  if (pump_ON == true && pump_run_state == false) {
    pump_ON_Millis = current_Millis;
    pump_run_state = true;
  }
  if (pump_ON == true) {
    current_pump_cycle = (current_Millis - pump_ON_Millis);
    current_pump_cycle_sec = current_pump_cycle / 1000;
    current_pump_cycle_min = current_pump_cycle / 60000;
    current_pump_cycle_run_min = current_pump_cycle_min % 60;
    current_pump_cycle_run_sec = current_pump_cycle_sec % 60;
    if (current_pump_cycle >= max_pump_runtime) {
      pump_alarm = true;
    }
  }
  if (pump_run_state == true && pump_ON == false) {  // timestamp pump turning off
    pump_OFF_Millis = current_Millis;
    pump_run_state = false;
    current_pump_cycle_run_sec = 0;
    current_pump_cycle_min = 0;

    last_pump_cycle_Millis = pump_OFF_Millis - pump_ON_Millis;
    last_pump_cycle_sec = (last_pump_cycle_Millis / 1000);

    daily_run_Millis = (last_pump_cycle_Millis + daily_run_Millis);
    daily_run_seconds = (daily_run_Millis / 1000);  // daily_run_seconds
    daily_pump_run_sec = daily_run_seconds % 60;
    daily_run_minutes = (daily_run_seconds / 60);
    int hr = daily_run_minutes / 60;
  }
  if (pump_ON == false && pump_OFF_timeHack == false) {
    pmp_OFF_hr = time_hour;  // TOD = Time of Day [webpage descriptor]
    pmp_OFF_min = time_min;
    pmp_OFF_month = time_month;
    pmp_OFF_day = time_day;
    pump_OFF_timeHack = true;
  }
  if (pmp_run_state != last_pump_state) {  // compare the pump run status to its previous state
    if (pump_ON == true)                   // if the state has changed to ON increment the counter;
    {                                      // goal is to only increment counter ONLY when pump comes ON
      on_off_cycle_count++;
    }
    last_pump_state = pmp_run_state;  // save current state as last state, for next time thru loop
  }
  if (counter_reset == true) {  // clear daily counters & temp hi/lo at midnight
    daily_run_Millis = 0;
    daily_run_seconds = 0;
    daily_run_minutes = 0;
    on_off_cycle_count = 0;
    pump_OFF_Millis = 0;
    pmp_OFF_interval = 0;
    highest_space_tmp = 0;
    lowest_space_tmp = 80;
    counter_reset = false;
  }
  if (pump_ON == false) {
    pump_alarm = false;
    // pump_run_state = false;
    //  current_pump_cycle = 0;
    pump_ON_Millis = 0;
  }  //  ************ Monitor if pump ON too long in one cycle *********
  if (pump_alarm == true && pump_alarm_state == false) {
    strcpy(Pump_Alm, "ON");
    alm_pmp_run_hour = time_hour;
    alm_pmp_run_min = time_min;
    pump_alarm_state = true;
    bldg_alarm_state = true;
    sendToPushingBox(DEVID3);
  }  //              ***************** Low Water Pressure Alarm Function ********
  if (pressure_switch_state == HIGH) {
    delay(5000);
    reread_press_switch = digitalRead(Pressure_Switch);  // avoid false input reading with a delayed reread
    if (reread_press_switch == HIGH) {
      pressure_alarm = true;
    }
  }
  if (pressure_alarm == true && press_alarm_state == false) {  // check if pressure switch has changed state
    strcpy(Pressure_Alm, "ON");                                // AND alm state "was" false; this ensures alm is not repeatedly sent to API.
    alm_press_hour = time_hour;                                // timestamp alarm
    alm_press_min = time_min;
    press_alarm_state = true;
    bldg_alarm_state = true;
    sendToPushingBox(DEVID2);
  }
  //               ***************** Low Temp Alarm Function ***************
  if ((sp_temp_1 <= Low_Tmp_Alm) && confirm_temp_alm_state == false) {
    delay(5000);
    space_temp_1 = DS18B20.getTempFByIndex(0);  // reread temperature after delay to confirm value
    DS18B20.requestTemperatures();
    if (sp_temp_1 <= Low_Tmp_Alm) {
      temp_alarm = true;
      confirm_temp_alm_state = true;  // temp verified in alarm so lockout temp check
    }
  }
  if (temp_alarm == true && temp_alarm_state == false) {
    strcpy(Temp_Alm, "ON");
    alm_temp_hour = time_hour;  // timestamp alarm
    alm_temp_min = time_min;
    temp_alarm_state = true;  // Send request to PushingBox ONCE when temp alm is true
    bldg_alarm_state = true;
    sendToPushingBox(DEVID1);
  }  //                                *********** Building Alarm/Activate Audible Warning **************
  if (bldg_alarm_state == true && bldg_alm_flag == false) {
    bldg_alm_flag = true;
    digitalWrite(Alarm_Relay, HIGH);
    strcpy(Bldg_Alarm, "ON");
    strcpy(Alm_Relay, "ON");
    if (DEBUG) { Serial.println("           Turn Horn ON & kill pump !!!          "); }
  }
  //                                       *********************** Record Temp High/Low **********************
  if (sp_temp_1 >= (highest_space_tmp + .2)) {
    highest_space_tmp = sp_temp_1;
  }
  if (sp_temp_1 <= (lowest_space_tmp - .2)) {
    lowest_space_tmp = sp_temp_1;
  }
  //                                                  ******************** WiFiWebServer Code***********
  if (WiFi.status() != WL_CONNECTED && current_Millis - startup_Millis > wait_interval)  //  && millis() - last_Connection_Attempt_At_Ms  > 15000ul )
  {
    WiFi.disconnect();  // last_Connection_Attempt_At_Ms = millis();
    delay(2000);
    WiFi.begin(wifissid, wifipass);
    delay(4000);
    restart_Flag = true;
    connectToWiFi();
  }
  if (WiFi.status() == WL_CONNECTED && restart_Flag == true) {
    restart_Flag = false;
    startup_Millis = millis();
    server.begin();
  }
  int rssi = WiFi.RSSI();
  WiFiClient client = server.available();  // listen for incoming clients
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n')  //     && currentLineIsBlank)
        {
          client.print("       ");
          client.print(rssi);
          StackString<75> XString = StackString<75>(" dBm Signal Strength [RSSI] ");
          XString.append("/ RTC Hr: ");
          XString.append(time_hour);
          XString.append(" : Min: ");
          XString.append(time_min);
          XString.append(" : Sec: ");
          XString.append(time_sec);
          client.println(XString.c_str());
          client.println();
          StackString<75> YString = StackString<75>("     MAC Address: ");
          YString.append(MAC_Address);
          YString.append(" / INO Version: ");
          YString.append(INO_Version);
          YString.append(" / Void Loop (Ms): ");
          YString.append(UNO_cycle_time);
          client.println(YString.c_str());
          client.println();
          StackString<75> AString = StackString<75>("                         Pump House: ESP WROOM-32");
          client.println(AString.c_str());
          StackString<75> BString = StackString<75>("                         ************************");
          client.println(BString.c_str());
          client.println();
          StackString<75> HString = StackString<75>("                                  Pump Status =  ");
          HString.append(Pump_Status);
          client.println(HString.c_str());
          client.println();
          StackString<75> KString = StackString<75>("                 Current Pump Cycle [seconds] =  ");
          KString.append(current_pump_cycle_run_sec);
          client.println(KString.c_str());
          client.println();
          StackString<75> LString = StackString<75>("                 Current Pump Cycle [minutes] =  ");
          LString.append(current_pump_cycle_min);
          client.println(LString.c_str());
          client.println();
          StackString<75> MString = StackString<75>("                    Last Pump Cycle [seconds] =  ");
          MString.append(last_pump_cycle_sec);
          client.println(MString.c_str());
          client.println();
          StackString<75> NString = StackString<75>("                Daily Total Runtime [minutes] =  ");
          NString.append(daily_run_minutes);
          client.println(NString.c_str());
          client.println();
          StackString<75> PString = StackString<75>("                Daily Total Runtime [seconds] =  ");
          PString.append(daily_pump_run_sec);
          client.println(PString.c_str());
          client.println();
          StackString<75> OString = StackString<75>("                          Daily On-Off Cycles =  ");
          OString.append(on_off_cycle_count);
          client.println(OString.c_str());
          client.println();
          StackString<95> VString = StackString<95>("                    Last Cycle Shut Off [TOD] =  Hr: ");
          VString.append(pmp_OFF_hr);
          VString.append("  Min: ");
          VString.append(pmp_OFF_min);
          client.println(VString.c_str());
          client.println();
          StackString<95> WString = StackString<95>("                    Last Cycle Shut Off [M/D] =  Month: ");
          WString.append(pmp_OFF_month);
          WString.append("  Day: ");
          WString.append(pmp_OFF_day);
          client.println(WString.c_str());
          client.println();
          StackString<75> CString = StackString<75>("                              Pump House Temp =  ");
          CString.append(sp_temp_1);
          client.println(CString.c_str());
          client.println();
          StackString<75> QString = StackString<75>("                                   Max: ");
          QString.append(highest_space_tmp);
          QString.append("  Min: ");
          QString.append(lowest_space_tmp);
          client.println(QString.c_str());
          client.println();
          StackString<75> DString = StackString<75>("                          Temp Alarm Setpoint =  ");
          DString.append(Low_Tmp_Alm);
          client.println(DString.c_str());
          client.println();
          StackString<75> IString = StackString<75>("                               Building Alarm =  ");
          IString.append(Bldg_Alarm);
          client.println(IString.c_str());
          client.println();
          StackString<75> JString = StackString<75>("                  Audible Alarm/Pump Shutdown =  ");
          JString.append(Alm_Relay);
          client.println(JString.c_str());
          client.println();
          StackString<113> EString = StackString<113>("                               Low Temp Alarm =  ");
          EString.append(Temp_Alm);
          EString.append("  Hr: ");
          EString.append(alm_temp_hour);
          EString.append("  Min: ");
          EString.append(alm_temp_min);
          client.println(EString.c_str());
          client.println();
          StackString<93> FString = StackString<93>("                           Low Pressure Alarm =  ");
          FString.append(Pressure_Alm);
          FString.append("  Hr: ");
          FString.append(alm_press_hour);
          FString.append("  Min: ");
          FString.append(alm_press_min);
          client.println(FString.c_str());
          client.println();
          StackString<93> GString = StackString<93>("                    Pump Continuous Run Alarm =  ");
          GString.append(Pump_Alm);
          GString.append("  Hr: ");
          GString.append(alm_pmp_run_hour);
          GString.append("  Min: ");
          GString.append(alm_pmp_run_min);
          client.println(GString.c_str());
          break;
        }
      }
    }

    delay(2000);    // give the web browser time to receive the data
    client.stop();  // close the connection:
    Serial.println("client disonnected");
  }
  if (!client.connected() && lastConnected) {
    if (DEBUG) { Serial.println(); }
    if (DEBUG) { Serial.println("             disconnecting"); }
    client.stop();
  }
  lastConnected = client.connected();

  UNO_run_cycle_stop = millis();
  UNO_cycle_time = UNO_run_cycle_stop - UNO_run_cycle_start;
}
// **************************** END OF VOID LOOP() ****************************************
void sendToPushingBox(char devid[])  // Function for sending the request to PushingBox
{
  client.stop();
  delay(2000);
  if (DEBUG) { Serial.println("      connecting..."); }
  if (client.connect(serverName, 80)) {
    if (DEBUG) { Serial.println("     connected"); }
    if (DEBUG) { Serial.println("          sending request to PushingBox API"); }
    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: ESP32");
    client.println();
  } else {
    if (DEBUG) { Serial.println("            connection failed"); }
  }
}

void setTimezone(const char* timezone) {
  Serial.print("Setting Timezone to ");
  Serial.println(timezone);
  setenv("TZ", timezone, 1);
  tzset();
}

void initTime(const char* timezone) {
  struct tm timeinfo;

  Serial.println("Getting time from NTP server");
  configTime(0, 0, "pool.ntp.org");  // First connect to NTP server, use 0 TZ offset
  if (!getLocalTime(&timeinfo)) {
    Serial.println("  Failed to obtain time");
    return;
  }
  Serial.println("OK, Got the time from NTP");
  setTimezone(timezone);  // then set your timezone
}

void printLocalTime() {  // this function monitors current time of day to initiate
                         // pump counter reset at midnight
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  time_hour = timeinfo.tm_hour;  // tm structure element "hour" from time.h
  time_min = timeinfo.tm_min;    //                     "minute"  "    "
  time_sec = timeinfo.tm_sec;    //                      "second"

  time_month = timeinfo.tm_mon + 1;  // + 1 is due to way time.h assigns month values (starts w/ 0)
  time_day = timeinfo.tm_mday;

  if (time_hour == hour_trigger && time_min == min_trigger && time_sec == sec_trigger) {
    Serial.println("Reset counters...");
    counter_reset = true;
    delay(3000);  // used to avoid conflict as time rolls over to new day
  }

  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z ");
  Serial.println();
  Serial.println("Month [timeinfo.tm_mon] is: ");
  Serial.print(time_month);
  Serial.println();
}

void connectToWiFi() {
  Try_Count = 0;
  while (WiFi.status() != WL_CONNECTED) {
    Try_Count++;
    WiFi.disconnect();
    WiFi.begin(wifissid, wifipass);
    vTaskDelay(10000);
    if (Try_Count == 10) {
      Serial.println("..... 10 attempts failed....rebooting processor...");
      ESP.restart();  // reboot processor!!!
    }
  }
  // WiFi.onEvent( WiFiEvent );    > define WiFiEvent to do ???
}

Constants.h:


OneWire oneWire(SENSOR_PIN);
DallasTemperature DS18B20(&oneWire);

int status = WL_IDLE_STATUS;  // the Wifi radio's status

WiFiClient client;

WiFiServer server(80);  // added for testing 2/4

int Initial_Connect_Attempts = 0;
int Try_Count = 0;

char wifissid[18] = "Homestead-LAN_EXT";  //     "Homestead-LAN_EXT" for in house testing
char wifipass[13] = "********";           //

char DEVID1[] = "v5A61F203ED29211";  //   token/key low temp alarm    [ v5A61F203ED29211 ]
char DEVID2[] = "v9072310CAE86043";  //   token/key low wtr pressure alarm [ v9072310CAE86043 ]
char DEVID3[] = "va71BBE853590654";  //   pump runtime alarm   [  va71BBE853590654  ]

char INO_Version[3] = "8S";
char MAC_Address[18] = "C4-DD-57-EA-A4-C8";

int time_month = 0;
int time_day = 0;
int time_hour = 0;
int time_min =  0;
int time_sec =  0;

unsigned long previous_LED_Millis = 0;
const long interval = 1000;  // Run LED Blink rate
const long interval_1 = 500; // System Alarm LED blink rate
unsigned long system_alm_LED_Millis = 0;

int UNO_cycle_time = 0;
unsigned long UNO_run_cycle_stop = 0;  
unsigned long UNO_run_cycle_start = 0;
int ledState = LOW;
int Sys_Alm_ledState = LOW;

unsigned long startup_Millis = millis();  // static uint32_t last_Connection_Attempt_At_Ms = millis();
unsigned long current_Millis = 0;
int wait_interval = 300000;  // 5 minutes of no wifi connection
int hour = 3600000;              // 3,600,000 millis per hr
int minute = 60000;
// int min = 60;                 // 60,000 millis per minute
// int hr  = 60;


unsigned long pump_ON_Millis = 0;
unsigned long pump_OFF_Millis = 0;
unsigned long last_pump_cycle_Millis = 0;
int last_pump_cycle_sec = 0;
unsigned long daily_run_Millis = 0;
int daily_run_seconds = 0;
int daily_run_minutes = 0;

int daily_pump_run_sec = 0;
// int daily_run_secs = 0;
// int daily_run_mins = 0;

int current_pump_cycle = 0;
int current_pump_cycle_sec = 0;
int current_pump_cycle_min = 0;
int on_off_cycle_count = 0;
int current_pump_cycle_run_min = 0;
int current_pump_cycle_run_sec = 0;

int last_pump_state = 0;
int pmp_run_stat = 0;
int pmp_run_state = 0;

unsigned long pmp_OFF_interval = 0;
int pmp_OFF_min = 0;
int pmp_OFF_hr = 0;
int pmp_OFF_month = 0;
int pmp_OFF_day = 0;

//  static uint32_t pump_alm_stop_Millis  = 0;
int max_pump_runtime = 300000;  // 5 minutes (300000) maximum run time before an alarm
// static uint32_t pump_runtime = 0;

static bool restart_Flag = false;


boolean DEBUG = true;  // Debug mode     !!!!

boolean currentLineIsBlank = false;  //added 10/31/22 debugging

char serverName[19] = "api.pushingbox.com";  //  [  api.pushingbox.com   ]

//  int keyIndex = 0;       WiFi Communication Parameter      NEEDED????

const int Alarm_Relay = 4;  // Alarm Relay output pinMode(GIOP4/D2, OUTPUT)

int hour_trigger = 23;        // hour to reset pump counters to zero
int min_trigger = 59;         // minute            (23 : 59 : 59)
int sec_trigger = 59;         // second             HR   MIN  SEC

boolean counter_reset = false;

boolean bldg_alm_ON = false;
boolean bldg_alarm_state = false;
boolean bldg_alm_flag = false;

boolean temp_alarm = false;
boolean temp_alarm_state = false;
boolean confirm_temp_alm_state = false;

boolean lastConnected = false;

boolean pump_ON = false;
boolean pump_run_state = false;
boolean pump_alarm = false;
boolean pump_OFF_timeHack = false;
   
int alm_pmp_run_hour = 0;
int alm_pmp_run_min = 0;

//  ************* I/O assignments ***********
const int Pressure_Switch = 25;  // Board Digital Input GIOP25;  pinMode(GIOP#, INPUT);
const int Pump_Run_Status = 22;  // Dig Input for pump run status
const int System_Reset = 23;     // Reset/clear alarms switch input; GPIO21, D21
const int System_Alm_LED = 32;   // Onboard Red LED

int reread_press_switch = 0;
int pressure_switch_state = 0;
int alarm_reset = 0;
int pump_run_contacts = 0;

boolean pressure_alarm = false;
boolean press_alarm_state = false;
boolean pump_alarm_state = false;

int alm_press_hour = 0;
int alm_press_min = 0;

//  ***************** Webpage Descrptors ***************
char Pump_Status[4] = "OFF";
char Pump_Alm[4] = "OFF";
char Temp_Alm[4] = "OFF";
char Pressure_Alm[4] = "OFF";
char Alm_Relay[4] = "OFF";
char Bldg_Alarm[4] = "OFF";

//    const int B = 4275;                 // B value of the thermistor;  +- 275 = .6 C (1.0 F)
//   const uint32_t R0 = 100000;            // R0 = 100k; int type uint32_t required (unsigned 32 bit)

unsigned long read_Temps_Time = 0;
unsigned long read_Temps_interval = 5000;
int tmp_adj_1 = 0;  // sensor 1 calibration adjustment

float space_temp_1;  //    Dallas DS18B20 temp sensor
int sp_temp_1;

int alm_temp_hour = 0;
int alm_temp_min = 0;
int Low_Tmp_Alm = 36.00;  // Low Alarm Setpoint

int highest_space_tmp = 0;
int lowest_space_tmp = 80;

hashtag_includes.h:


#include <SPI.h>
#include <WiFi.h>
#include <math.h>
#include "time.h"

#include <StackString.hpp>  // save memory using this function: character arrays
using namespace Stack;

//    #include <DS18B20.h>

#include <OneWireNg.h>
#include <DallasTemperature.h>

#define SENSOR_PIN 14  // ESP32 pin GPIO14; D14 silkscreen connected to DS18B20
#define ONBOARD_LED 2

Here's a way to slow down the printing in your test sketch. It print when the seconds change. Not the seconds in the RTC, but the ones in time_sec:

  static int printedSeconds;
  if (printedSeconds != time_sec) {
    Serial.println();
    Serial.print("Time = Hr: ");
    Serial.print(time_hour);
    Serial.print(" Min: ");
    Serial.print(time_min);
    Serial.print(" Sec: ");
    Serial.print(time_sec);
    Serial.println();
 
    printedSeconds = time_sec;
  }


// delay(3000); no need for this, lose it.

As I read it now, this controlled printing will happen every request_time_Millis milliseconds, that is to say every ten seconds here.

It's back to needing to assign to those handy simple variables, which it appears you understand only happens when the function is called.

You could call it more frequently. A bit of googling suggests the call is inexpensive (no network traffic, not much time to perform) so there's no good reason not to call it at the top of your free running loop, or just when and if you need those variables to hold the current time.

The time in those simlple variables will not change during the loop pass, obvsly I hope.

a7

a7

That is definitely a cleaner way to do the serial output. :+1: :+1:

Ok folks,

I had a eureka moment and it looks like I failed (as usual) to get all the necessary
code I plagiarized from the earlier working sketch.
I left out an important function needed in the void loop:

printLocalTime();

There is a liability when you start copying old code to make a new sketch.
If anyone has a surefire method that eliminates oversights I am all ears, ouside of writing it from scratch. Lol...

@alto777
hello again!

@edthewino
why does the topic say, "it's not [SOLVED]"?
it's clearly solved.

HaHa...
You had me going there for a moment. :cold_sweat:

@edthewino
wait, so it's not solved? umm... okay. :confused:

Ok, to be clear about this:

Original title: "ESP32 'RTC' time update - it's not"

Solved title: "ESP32 'RTC' time update - it's not [SOLVED]"

I can change it to " ... it's not updating...[SOLVED]" if you
think it would be less confusing.

okay, so it IS solved, if it's solved you put "[SOLVED]", i should be doing that!

1 Like

It might be helpful, especially for the coders on here whose main interest is expediently helping others and would rather not spend time on issues not needing their attention.