- Thu Oct 18, 2018 5:09 pm
#78723
This is what I came up with. It also uses the Sodaq library. I wanted something that would work with sub second timing, to be used for data logging. If there is no internet the RTC is used for time. If a new time can be obtained from the internet then that is used to sync the RTC.
I did this last winter, so it has been a while an I don't remember too much about the details.
As a side note. I don't like when you zip your code and I have to download it to have a look. If it is one file then why not just post it wrapped in the code tags? I hate when I have directories of stuff that I have no idea why it is there, months later. Most of the time I wouldn't even look at your code because of this.
Note that in the setup function I use GPIO0 and GPIO2 for I2C.
Code: Select all// Date and time functions using RTC and NTP.
// Use RTC for initial time. Switch to NTP after connect.
// When NTP is updated the RTC is also updated.
// If gettimeofday() returns microseconds > 0.5 second then round up RTC sync
#include <time.h> // time() ctime()
#include <sys/time.h> // struct timeval
#include <coredecls.h> // settimeofday_cb()
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <Wire.h>
#include "Sodaq_DS3231.h"
const int led15 = 15;
const char* ssid = "sidsissid";
const char* password = "xxxxxxxxxxx";
const char* WiFi_hostname = "DS3231-NTP";
unsigned int localPort = 5000; // local port to listen for UDP packets
unsigned int timezone = -6;
unsigned int dst = 1;
char weekDay[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
//year, month, date, hour, min, sec and week-day(starts from 0 and goes to 6)
//writing any non-existent time-data may interfere with normal operation of the RTC.
//Take care of week-day also.
DateTime dt(2011, 11, 10, 15, 18, 0, 5);
uint32_t ts = 1510592825; // 1510592825 = Monday 13 November 2017 17:07:05 UTC
const int SW4 = 4;
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;
//--------------------------------------------------
timeval cbtime; // time set in callback
bool cbtime_set = false;
void ntpSetTimeCB(void) {
gettimeofday(&cbtime, NULL);
cbtime_set = true;
digitalWrite(led15, 0);
if (cbtime.tv_usec>500000) {
cbtime.tv_sec++;
digitalWrite(led15, 1);
}
rtc.setEpoch(uint32_t (cbtime.tv_sec)); // Set the RTC using timestamp (seconds since epoch)
Serial.println("----ntpSetTimeCB---------- settimeofday() was called ------------------");
Serial.print(cbtime.tv_sec);
Serial.print(".");
Serial.println(cbtime.tv_usec);
}
//--------------------------------------------------
/*void SetTime(time_t time_stamp) { // set
timeval tv = { time_stamp, 0 };
timezone tz = { 0, 0 };
settimeofday(&tv, &tz);
}
*/
//--------------------------------------------------
void connectToNetwork()
{
Serial.println("---------------------");
Serial.println("");
Serial.println("DS3231-NTP-template.ino");
WiFi.hostname(WiFi_hostname);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password); //setting up Station
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.print(WiFi.localIP());
Serial.print(":");
Serial.println(localPort);
Serial.println(WiFi_hostname);
Udp.begin(localPort);
Serial.printf("UDP at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localPort);
Serial.println("---------------------");
// Set up mDNS responder:
// - first argument is the domain name, in this example domain name is "esp8266.local",
// - second argument is the IP address to advertise
if (!MDNS.begin(WiFi_hostname)) {
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// MDNS.begin(host);
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", WiFi_hostname);
MDNS.addService("esp", "udp", 8266);
Serial.println("ESP UDP service added on port 8266");
Serial.println("---------------------");
configTime(0, 0, "pool.ntp.org"); // bool configTime(int timezone, int daylightOffset, char *server1, char *server2, char *server3, bool enable);
setenv("TZ", "CST6CDT,M3.2.0,M11.1.0", 0); //setenv,(const char *__string, const char *__value, int __overwrite)
// configTime(timezone * 3600, dst * 3600, "pool.ntp.org"); //
}
//--------------------------------------------
void testing()
{
timeval tv = { ts, 0 };
time_t now1;
Serial.print(" I gettimeofday ");
gettimeofday(&tv, nullptr);
now1 = time(nullptr);
// EPOCH+tz+dst
Serial.print(" time:");
Serial.print((uint32_t)now1);
Serial.print(gettimeofday(&tv, nullptr));
Serial.println();
delay(1000);
}
//==================================================
void setup ()
{
digitalWrite(led15, 0);
pinMode(led15, OUTPUT);
pinMode(SW4, INPUT_PULLUP);
Serial.begin(115200);
Wire.begin(0, 2);
rtc.begin();
Serial.println("Start");
delay(9);
ESP.eraseConfig();
Serial.println("eraseConfig");
if (digitalRead(SW4) == 0) {
/* Serial.println("2011/11/10 15:18:00");
rtc.setDateTime(dt); //Adjust date-time as defined 'dt' above
}
else
{*/
Serial.println("Monday 13 November 2017 17:07:05 UTC");
rtc.setEpoch(uint32_t (ts)); // Set the RTC using timestamp (seconds since epoch)
}
//-----------------------------------
Serial.println("Get time from RTC");
DateTime now = rtc.now(); // get the current date-time from rtc
uint32_t ts = now.getEpoch(); // Sodaq, seconds since Unix epoch (1970-01-01)
timeval tv = { ts, 0 };
// timezone tz = { 0, 0 };
// settimeofday(&tv, &tz);
settimeofday(&tv, NULL);
testing();
testing();
testing();
testing();
settimeofday_cb(ntpSetTimeCB); // ntp set time callback
Serial.println("go connectToNetwork");
connectToNetwork();
Serial.println("done connectToNetwork");
//-----------------------------------
}
timeval tv;
time_t now1;
//===================================================
void loop ()
{
httpServer.handleClient();
DateTime now = rtc.now(); // get the current date-time from rtc
uint32_t ts = now.getEpoch(); // Sodaq, seconds since Unix epoch (1970-01-01)
uint32_t ts1 = now.get(); // seconds since 1/1/2000
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.date(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
// Serial.println();
Serial.print(" Seconds since Unix Epoch: ");
Serial.print(ts, DEC);
gettimeofday(&tv, nullptr);
// now1 = time(nullptr);
Serial.print(" gtod:");
Serial.print((uint32_t)tv.tv_sec);
Serial.print("s ");
Serial.print((uint32_t)tv.tv_usec);
Serial.print("us ");
// Serial.println();
time_t tnow = time(nullptr);
tnow = time(nullptr);
Serial.print(ctime(&tnow)); // prints 'Tue Jan 30 15:37:59 2018'
//---------------------------------------------------------
time_t rawtime;
struct tm *info;
char buffer[80];
time( &rawtime );
info = localtime( &rawtime );
strftime(buffer,80,"%x - %I:%M%p", info);
printf("Formatted date & time : |%s|\n", buffer );
strftime(buffer,80,"%FT%T", info); // http://strftime.net/
printf("Formatted date & time : %s\n", buffer );
//---------------------------------------------------------
delay(1000);
}