Chat freely about anything...

User avatar
By Sirquil
#78722 https://github.com/SodaqMoja/Sodaq_DS3231/tree/b10376017748beeec1de97d0d6125f2ee30847d6 Sodaq_DS3231 Library for Real Time Clock

I am unable get the example file "Adjust_via_NTP.ino" to reset the DS3231 RTC. Both port 123 and 2390 are open to udp traffic. I am using 10K pull-up resistors on SDA and SCL. Development board being used is a RobotDyn WiFi D1 R2. Pins labeled SDA and SCL are being used (GPIO4 and GPIO5).

Only Serial Monitor output; which repeats.:

2014-01-21 19:58:40 Sun
Seconds since Unix Epoch: 1390334320

I do see "Starting UDP" at the beginning of Serial Monitor output.

I have been able set correct time manually to the DS3231; so it is know to be good.

Help, please in finding a working solution.

William
Attachments
Removed ssid and password.
(2.82 KiB) Downloaded 234 times
User avatar
By rudy
#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);
}
User avatar
By Sirquil
#78728 Thank you rudy! Appreciate the help.

Line 130 of your code was changed to my timezone:

Code: Select allsetenv("TZ", "EST+5EDT,M3.2.0/2,M11.1.0/2", 0);  //setenv,(const char *__string, const char *__value, int __overwrite)


Everything time related works perfectly!

What is the web "update" purpose?

When I tried the update button; it produced: Update error: "ERROR[10]: Magic byte is wrong, not 0xE9."
I am using Chrome as my web browser.

William
User avatar
By rudy
#78741
Sirquil wrote:What is the web "update" purpose?

That is used to do a over the air update of the code. There is an example sketch,
https://github.com/esp8266/Arduino/blob ... pdater.ino

When I have the ESPs installed around the house, and I want to update the code, can do it through the web updater page. This is simpler to implement than setting up a server and doing automatic updates. The downside is that it isn't automatic and I would need to do this for every device. That's not a big deal to me.

In order to use it there needs to be a compiled binary and this is how to get it.

Image

That puts the compiled binary in the sketch folder (with the .ino file). That file is what you select, and then when you select the update button the new binary gets programmed into the esp.

https://arduino-esp8266.readthedocs.io/ ... eb-browser