NTPで取得した時刻をRTCへセットする(続編2)

 「NTPで取得した時刻をRTCへセットする」の続編2です。


NTPとRTCを組み合わせる方法を考えてみました。

NTPから時刻を取得し、取得出来た時のみRTCを

合わせます。

(スケッチ例や作例を公開している方々に感謝します。)


今回は

ESPr One(ESP-WROOM-02)とDS3231 I2C RTCモジュール

を使って、スケッチ例NTPCilentを改変してやってみました。

ESPr OneとI2C RTC DS3231














スケッチを紹介します。

※変更のないところは省略していますので、オリジナルの

スケッチ例からコピペして下さい。わかりやすくするため、

変更がなくても表示している所もあります。

include行は < から < へ修正して下さい。


#include <ESP8266WiFi.h>//< を < に直して下さい

#include <WiFiUdp.h>

#include <Time.h>

#include <TimeLib.h>

#include <Wire.h>

#include "RTClib.h"

#define UTC_TOKYO +9


#ifndef STASSID

#define STASSID "your-ssid"

#define STAPSK "your-password"

#endif


const char * ssid = STASSID; // your network SSID (name)

const char * pass = STAPSK; // your network password


unsigned int localPort = 2390; // local port to listen for UDP packets


/* Don't hardwire the IP address or we won't get the benefits of the pool.

Lookup the IP address for the host name instead */

//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server

IPAddress timeServerIP; // time.nist.gov NTP server address

const char* ntpServerName = "time.nist.gov";


const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message


byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets


unsigned long unixtime;//

char date_ymdhms[21]; // yyyy/mm/dd,hh:mm:ssn0

unsigned long previousMillis = 0;//

const long interval = 60000;//600000 :10分 3600000 :1h

int ntpAccsCount = 0;//NTP accsess count

int accsInterval = 60;//NTP accsess interval


// A UDP instance to let us send and receive packets over UDP

WiFiUDP udp;

RTC_DS3231 rtc;


void setup() {

//変更のないところ中略

if (! rtc.begin()) {

Serial.println("Couldn't find RTC");

while (1);

}

if (rtc.lostPower()) {

Serial.println("RTC lost power, lets set the time!");

// following line sets the RTC to the date & time this sketch was compiled

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

// This line sets the RTC with an explicit date & time, for example to set

// January 21, 2014 at 3am you would call:

// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

}

}


void loop() {

//get a random server from the pool

WiFi.hostByName(ntpServerName, timeServerIP);


/* 起動初期はRTC時刻は合っていない。rtc.lostPower()の時はコンパイル時刻が設定されている。起動初期だけ早くNTP時刻を取得して、RTC時刻を合わせたい。通常動作時のNTPアクセス頻度は1日あたり3回(RTCの日差を補正できる妥当な回数を設定)

intervalを1分ぐらいにしておいて、繰返し回数をカウント、指定回数になったらNTPアクセス。起動時ntpAccsCountは0でNTPアクセス、アクセス後Udp.parsePacket()の戻り値がなかったら繰返し カウントを指定回数まで進めて、NTPアクセス頻度を上げる。*/

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;

if (ntpAccsCount == 0) {


sendNTPpacket(timeServerIP); // send an NTP packet to a time server

// wait to see if a reply is available

delay(1000);


int cb = udp.parsePacket();

if ( cb ) {

//変更がないところ中略

// print Unix time:

//Serial.println(epoch);

unixtime = epoch;//追加箇所

//変更がないところ中略

time_t t = unixtime + (UTC_TOKYO * 60 * 60);//日本時間へ調整

// wait ten seconds before asking for the time again

//delay(10000);

//adjust RTC time

rtc.adjust(DateTime(year(t), month(t), day(t), hour(t), minute(t), second(t)));

Serial.println("adjust RTC time");

} else {

Serial.println("no packet yet");

ntpAccsCount = accsInterval;/*NTPアクセスできなかった時はカウント値を変えて

アクセスタイミングを早める。*/

}

}

ntpAccsCount++;//NTP accsess count

if (ntpAccsCount >= accsInterval) {//accsess interval

ntpAccsCount = 0;

}

}

delay(1000);

DateTime now = rtc.now();//RTCの現在時刻を読む

sprintf(date_ymdhms, "%04d/%02d/%02d,%02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());//

Serial.println(date_ymdhms);//

}

//以降変更がないので省略


無保証自己責任でよろしくおねがいします。

ESPr-One、I2C RTC DS3231 NTP to RTC


コメント

このブログの人気の投稿

ESP32pcntカウンタをテストしてみた

データロガーで温湿度記録計を作る。