電子工作
PR

【電子工作】RTC NTP時刻書込み テストボードの製作

ぽちお
記事内に商品プロモーションを含む場合があります

RTCを利用するにあたり、時刻情報の確認やNTPサーバから時刻情報を取得し、時刻合わせが可能な ”RTC簡易テスト時計”を製作します。

RTCとは

RTC:リアルタイムクロックの略称、年月日・時刻などの情報を処理する専用の電子部品、モジュールまたそれらのソフトウエアを指します。

RTCとは?(初心者向け)基本的に、わかりやすく説明
RTCとは?(初心者向け)基本的に、わかりやすく説明 日々の生活日常で、私たちは幾度となく時を確かめ、時間に従って生活していますよね、時計・最近ではスマホ等で「時」を得る日常ではないでしょ...

構成

簡易・テスト用に便利なブレッドボードで構成し組上げます。

マイコン

Wi-Fi機能を搭載した小型マイコンボード「XIAO ESP32C3」を使用します。

BluetoothとWi-Fi機能を搭載したマイコンボード。
21 x 17.5 mmと小型(ポータブル・軽量)で、IoT、簡易アプリケーションに最適

ディスプレイ

マイコン接続で定評のある、有機LED(OLED)を用い、
I2C接続、128×64グラフィックディスプレイモジュールを使用します。

機能

RTCに設定されている現状の時刻情報をディスプレイに表示
(年月日+時分秒を簡易秒単位にて時計表示)

初期状態やバックアップ電池交換時等のリセット、または時刻ずれ時等
 WI-FI接続によるNTPサーバーから時刻情報を取得し再設定を行います。

廉価タイプ

通販でお馴染みのアマゾンにて、比較的容易に入手可能で汎用的な、
ブランド:FTVOGUE DS3231搭載 RTCモジュール 
安価ですが、品質には問題がありそうです(実験には十分ですが・・・)


 ※本モジュール入手時、はんだ付けに難があり劣化(腐食)が見られました

その他の構成する主要部品も、同アマゾンで入手可能な製品にて構成してみました。

  • RTC

  • マイコン

回路図

プログラム(スケッチ)

#include <WiFi.h>
#include <time.h>              
#include <DS3232RTC.h>
#include <esp_sntp.h>

#include <stdio.h>
#include <string.h>
#include <Wire.h>

#include "SSD1306Wire.h"
SSD1306Wire display(0x3c, 6, 7);

DS3232RTC myRTC(false);

const char* weekStr[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};

// const char* ssid      = "your ssid";
// const char* password  = "your password";
const char* ssid      = "SSSSSSSS";
const char* password  = "pppppppp";

const char* ntpServer = "ntp.nict.jp";
const long  gmtOffset_sec = 32400;
const int   daylightOffset_sec = 0;
const long  tmmYear = 0;

struct tm timeInfo;

char rdate[30], rtime[30];

// d-s/w , W-LED
#define int_pin 20
#define deb_pin 8


void setup() {

pinMode(int_pin, INPUT);
pinMode(deb_pin, OUTPUT);

// SSD1306 Initial pocess;
  display.init();                               //  初期化
  display.flipScreenVertically();               //  反転
  display.setFont(ArialMT_Plain_10);            //  10フォント
  display.drawString(0,0,"= DS3231 Setting board =");    //  TITLE文字
  display.display();                            // 初期表示
  delay(500);
  display.setFont(ArialMT_Plain_16);            //  16フォント

// TIME Initial process;
  Serial.begin(9600);
  myRTC.begin();

  digitalWrite(deb_pin, LOW);

}


void loop() {

// RTC 表示
  rtc_disp();

// time set S/W 判定
	if(digitalRead(int_pin) == HIGH) {
    jst_time_set();
    digitalWrite(deb_pin, LOW);
	}
  delay(1000);
}


// RTC DISP process
void rtc_disp() {
// RTCから時刻取得
  tmElements_t tm;
  myRTC.read(tm);

// LCD表示
  display.clear();
  display.setFont(ArialMT_Plain_10);            //  10フォント
  display.drawString(0,0,"= DS3231 Setting board =");    //  TITLE
  display.setFont(ArialMT_Plain_16);            //  16フォント

  sprintf(rdate, " %04d/%02d/%02d [%s]",
        tm.Year+1970, tm.Month, tm.Day,  weekStr[tm.Wday - 1]);
  
  sprintf(rtime, " %02d:%02d:%02d", 
        tm.Hour, tm.Minute, tm.Second);

  display.drawString(0, 32,rdate);
  display.drawString(18, 48,rtime);
  display.display();

}


// W-TIME process
void jst_time_set() {
  digitalWrite(deb_pin, HIGH); 

//  Wi-Fi接続
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
  display.drawString(0, 16,"Wi-Fi connecting..");
  display.display();
  delay(500);
  }
//  Wi-Fi接続表示
  display.clear();
  display.drawString(0, 16,"Wi-Fi Connected");
  delay(1000);
  display.display();  
  display.clear();

//  NTPからJST取得
  configTime(gmtOffset_sec, daylightOffset_sec,ntpServer);
  display.drawString(0, 16,"JST Getting...");
  display.display();
  delay(2000);
  display.clear();

//  RTC - NTP マッチング
  while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET) {
    display.drawString(0, 16,">...");
    display.display();
    delay(500);
  }

//  RTC Setting表示
  display.clear();
  display.drawString(0, 16,"TIME Setting...");
  display.display();
  delay(1000);

// RTC時刻取得
  getLocalTime(&timeInfo);

// setTime(16, 0, 0, 12, 12, 2023);  // 時刻設定(時、分、秒、日、月、年) 手動設定 , Debug
  setTime(timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec, timeInfo.tm_mday, timeInfo.tm_mon + 1, timeInfo.tm_year + 1900);
  myRTC.set(now());

//  Wi-Fi切断
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

}

汎用タイプ

セイコーエプソン “RX-8025NB” を使用した、「秋月電子」のRTCモジュールを利用します。

モジュール化されていますが、バックアップ処理が未搭載の回路構成ですので、
同、秋月電子にて入手可能のリチウムボタン電池にてバックアップ回路を追加しました。

回路図

プログラム(スケッチ)

#include <WiFi.h>
#include <Wire.h>
#include <TimeLib.h>              

#include <RTC_RX8025NB.h>

RTC_RX8025NB rtc;

#include <esp_sntp.h>

#include <stdio.h>
#include <string.h>
#include <Wire.h>

#include "SSD1306Wire.h"
SSD1306Wire display(0x3c, 6, 7);

const char* weekStr[7] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};

// const char* ssid      = "your ssid";
// const char* password  = "your password";
const char* ssid      = "ssssssss";
const char* password  = "pppppppp";

const char* ntpServer = "ntp.nict.jp";
const long  gmtOffset_sec = 32400;
const int   daylightOffset_sec = 0;
const long  tmmYear = 0;

struct tm timeInfo;

tmElements_t tm;

char rdate[30], rtime[30];

int i_year, i_mon, i_mday, i_hour, i_min, i_sec;

// d-s/w , W-LED
#define int_pin 20
#define deb_pin 8


void setup() {

  pinMode(int_pin, INPUT);
  pinMode(deb_pin, OUTPUT);

// SSD1306 Initial pocess;
  display.init();                               //  初期化
  display.flipScreenVertically();               //  反転
  display.setFont(ArialMT_Plain_10);            //  10フォント
  display.drawString(0,0,"= 8025NB Setting board =");    //  TITLE文字
  display.display();                            // 初期表示
  delay(500);
  display.setFont(ArialMT_Plain_16);            //  16フォント

// TIME Initial process;
  Serial.begin(9600);
  Wire.begin();

}


// 曜日算出 Zeller's congruence
// in : year,month,day  out : 0:日 ~ 6:土
byte calc_dayweek( int year, int month, int day ) {
	if( month <= 2 ) {
		month += 12;
		year--;
	}
	return (byte)((year + year/4 - year/100 + year/400 + ((13 * month + 8)/5) + day) % 7);
}


void loop() {

// RTC 表示
  rtc_disp();

// time set S/W 判定
	if(digitalRead(int_pin) == HIGH) {
    jst_time_set();
    digitalWrite(deb_pin, LOW);
	}

  delay(1000);
}




// W-TIME process
void jst_time_set() {
  digitalWrite(deb_pin, HIGH); 

//  Wi-Fi接続
  WiFi.begin(ssid, password);
  while(WiFi.status() != WL_CONNECTED) {
  display.drawString(0, 16,"Wi-Fi connecting..");
  display.display();
  delay(500);
  }
//  Wi-Fi接続表示
  display.clear();
  display.drawString(0, 16,"Wi-Fi Connected");
  delay(1000);
  display.display();  
  display.clear();

//  NTPからJST取得
  configTime(gmtOffset_sec, daylightOffset_sec,ntpServer);
  display.drawString(0, 16,"JST Getting...");
  display.display();
  delay(2000);
  display.clear();

//  RTC - NTP マッチング
  while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET) {
    display.drawString(0, 16,">...");
    display.display();
    delay(2000);
  }

//  RTC Setting表示
  display.clear();
  display.drawString(0, 16,"TIME Setting...");
  display.display();
  delay(1000);


// RTC時刻取得

  getLocalTime(&timeInfo);

  tm.Year = timeInfo.tm_year;
  tm.Month = timeInfo.tm_mon+1;
  tm.Day = timeInfo.tm_mday;
  tm.Hour = timeInfo.tm_hour;
  tm.Minute = timeInfo.tm_min;
  tm.Second = timeInfo.tm_sec;

  rtc.setDateTime(tm.Year, tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second);

// rtc.setDateTime(2024, 7, 1, 12, 12, 12);  // 時刻設定(時、分、秒、日、月、年) 手動設定 , Debug  

//  Wi-Fi切断
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

}



// RTC DISP process
void rtc_disp() {

  tmElements_t tm = rtc.read();
  char s[20];

// Serial info , Debug 
  sprintf(s, "%d/%d/%d %d:%d:%d", tmYearToCalendar(tm.Year), tm.Month, tm.Day, tm.Hour, tm.Minute, tm.Second);
  Serial.println(s);


// LCD表示
  display.clear();
  display.setFont(ArialMT_Plain_10);            //  10フォント
  display.drawString(0,0,"= 8025NB Setting board =");    //  TITLE
  display.setFont(ArialMT_Plain_16);            //  16フォント


//  Get Week ID
  tm.Wday = calc_dayweek(tmYearToCalendar(tm.Year), tm.Month, tm.Day); 

// 
  sprintf(rdate, " %04d/%02d/%02d [%s]",
        tmYearToCalendar(tm.Year), tm.Month, tm.Day,  weekStr[tm.Wday+0]); 
  
  sprintf(rtime, " %02d:%02d:%02d", 
        tm.Hour, tm.Minute, tm.Second);

  display.drawString(0, 32,rdate);
  display.drawString(18, 48,rtime);
  display.display();

}

まとめ

”RTC簡易テスト時計”として、現状のRTC保存データから時を表示。
NTPサーバーから時刻情報を取得し再設定しました。

比較的に入手が容易な電子部品を採用し、2組としてテスト実施。

RTCを利用する目的としたテスト機に伴い、秒処理は簡素的にdelay loopで組合せ、
シンプルな簡易時計して表示し作成しました。

ABOUT ME
ぽちお
ぽちお
シニアエンジニア
ものづくりが大好です。
記事URLをコピーしました