I'm trying to set the MCP internal clock to actual NTP time.
I'm using the SV-Zanshin library for the MCP7940N and Arduino Version: 2.2.2-nightly-20231024 on debian 12.2.
The chip has the compile time after disconnecting power which is the default of the library function when called without any parameters.
I made a as simple possible version to test and the output suggests the chip does have the correct time & date after a NTP sync, but then disconnecting and reconnecting power, the chip has the compile time again:
Setting up time: NTPServer=europe.pool.ntp.org, TZ-Name=Europe/Amsterdam, TZ=CET-1CEST,M3.5.0,M10.5.0/3
Received time adjustment from NTP
localtime: Thursday, October 26 2023 10:44:54 zone CEST +0200
RTC has: 2023-10-26 10:03:25
Adjusting RTC with: 2023,10,26,10,44,54
RTC has: 2023-10-26 10:44:54
End of NTP callback function.
After power disconnect and reconnect the rtc time in not correct:
Received time adjustment from NTP
localtime: Thursday, October 26 2023 10:47:24 zone CEST +0200
RTC has: 2023-10-26 10:03:24
Adjusting RTC with: 2023,10,26,10,47,24
RTC has: 2023-10-26 10:47:24
End of NTP callback function.
#include <Arduino.h>
#include <WiFiManager.h>
#include <WiFiManagerTz.h>
#include <MCP7940.h>
#include <string.h>
#include "sntp.h"
#include <stdio.h>
#include <WiFiUdp.h>
#include "sntp.h"
/***************************************************************************************************
** Declare all program constants **
***************************************************************************************************/
const uint32_t SERIAL_SPEED{115200}; // Set the baud rate for Serial I/O
const uint8_t LED_PIN{13}; // Arduino built-in LED pin number
const uint8_t SPRINTF_BUFFER_SIZE{32}; // Buffer size for sprintf()
char inputBuffer[SPRINTF_BUFFER_SIZE]; // Buffer for sprintf()/sscanf()
#define TZ_INFO "UTC2"
#define ntpServer "0.europe.pool.ntp.org"
#define SERIAL_BAUD 115200
// TEST OPTION FLAGS
bool TEST_CP = true; // always start the configportal, even if ap found
int TESP_CP_TIMEOUT = 10; // test cp timeout
bool TEST_NET = true; // do a network test after connect, (gets ntp time)
bool WMISBLOCKING = true; // use blocking or non blocking mode, non global params wont work in non blocking
bool configSaved = false;
/***************************************************************************************************
** create objects **
***************************************************************************************************/
MCP7940_Class MCP7940;
WiFiManager wifiManager;
/***************************************************************************************************
** callback function, fired when NTP gets updated. **
** Used to print the updated time or adjust an external RTC module. **
***************************************************************************************************/
void on_time_available(struct timeval *t)
{
Serial.println("Received time adjustment from NTP");
struct tm timeInfo;
getLocalTime(&timeInfo, 1000);
Serial.println(&timeInfo, "localtime: %A, %B %d %Y %H:%M:%S zone %Z %z ");
DateTime now = MCP7940.now();
sprintf(inputBuffer, "RTC has: %04d-%02d-%02d %02d:%02d:%02d",now.year(),now.month(), now.day(), now.hour(), now.minute(),now.second()); // date/time with leading zeros
Serial.println(inputBuffer);
sprintf(inputBuffer, "Adjusting RTC with: %04d,%02d,%02d,%02d,%02d,%02d",timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday, timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);
Serial.println(inputBuffer);
MCP7940.adjust(DateTime(timeInfo.tm_year + 1900,timeInfo.tm_mon + 1,timeInfo.tm_mday,timeInfo.tm_hour,timeInfo.tm_min,timeInfo.tm_sec));
DateTime now2 = MCP7940.now();
sprintf(inputBuffer, "RTC has: %04d-%02d-%02d %02d:%02d:%02d",now2.year(),now2.month(), now2.day(), now2.hour(), now2.minute(),now2.second()); // date/time with leading zeros
Serial.println(inputBuffer);
Serial.println("End of NTP callback function.");
}
void setup() {
Serial.begin(SERIAL_SPEED); // Start serial port at Baud rate
delay(1000);
while (!MCP7940.begin()) { // Initialize RTC communications
Serial.println(F("Unable to find MCP7940M. Checking again in 3s.")); // Show error text
delay(3000); // wait a second
} // of loop until device is located
Serial.println(F("MCP7940 initialized."));
while (!MCP7940.deviceStatus()) { // Turn oscillator on if necessary
Serial.println(F("Oscillator is off, turning it on."));
bool deviceStatus = MCP7940.deviceStart(); // Start oscillator and return state
if (!deviceStatus) { // If it didn't start
Serial.println(F("Oscillator did not start, trying again.")); // Show error and
delay(1000); // wait for a second
} // of if-then oscillator didn't start
} // of while the oscillator is off
MCP7940.adjust(); // Set to library compile Date/Time
// optionally attach external RTC update callback
WiFiManagerNS::NTP::onTimeAvailable( &on_time_available );
// attach NTP/TZ/Clock-setup page to the WiFi Manager
WiFiManagerNS::init( &wifiManager );
// /!\ make sure "custom" is listed there as it's required to pull the "Setup Clock" button
std::vector<const char *> menu = {"wifi", "info", "custom", "param", "sep", "restart", "exit"};
wifiManager.setMenu(menu);
wifiManager.setConnectRetries(10); // necessary with sluggish routers and/or hidden AP
wifiManager.setCleanConnect(true); // ESP32 wants this
wifiManager.setConfigPortalBlocking(false); // /!\ false=use "wifiManager.process();" in the loop()
wifiManager.setConfigPortalTimeout(120); // will wait 2mn before closing portal
wifiManager.setSaveConfigCallback([](){ configSaved = true;}); // restart on credentials save, ESP32 doesn't like to switch between AP/STA
if(wifiManager.autoConnect("AutoConnectAP", "12345678")){
Serial.print("Connected to Access Point, visit http://");
Serial.print(WiFi.localIP());
Serial.println(" to setup the clock or change WiFi settings");
wifiManager.startConfigPortal();
} else {
Serial.println("Configportal is running, no WiFi has been set yet");
}
if(WiFi.status() == WL_CONNECTED){
WiFiManagerNS::configTime();
}
}
void loop() {
wifiManager.process();
delay(1000);
}
The example SimpleBatteryBackup is working ok:
Starting SimpleBatteryBackup program
- Compiled with c++ version 8.4.0
- On Oct 26 2023 at 10:34:34
MCP7940N initialized.
Power failure mode detected!
Power failed at ....-10-26 10:31:..
Power restored at ....-10-26 10:31:..