hiro yamamoto works

マイコンハード、ソフトを作ったりしています。
お家や現場のお困りごと解決に!
内容利用は自己責任でお願いします。

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

2020-08-24 08:58:00 | マイコンハードウェア
「NTPで取得した時刻をRTCへセットする」の続編2です。

こちらもどうぞ
NTPで取得した時刻をRTCへセットする(ESP32)

NTPとRTCを組み合わせる方法を考えてみました。
NTPから時刻を取得し、取得出来た時のみRTCを
合わせます。
(スケッチ例や作例を公開している方々に感謝します。)

今回は
ESPr One(ESP-WROOM-02)とDS3231 I2C RTCモジュール
を使って、スケッチ例NTPCilentを改変してやって
みました。
NTPで取得した時刻をRTCへセットするESP編

スケッチを紹介します。
※変更のないところは省略していますので、オリジナルの
スケッチ例からコピペして下さい。わかりやすくするため、
変更がなくても表示している所もあります。
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

最新の画像もっと見る

コメントを投稿