2016年6月21日火曜日

450円でESPでもArduinoでも使える高精度RTC

電子工作でRTCっていうとDS1307 / 1302あたりが定番だと思うんですが、秋月で売ってるRX-8025NBって、なかなか良いと思うんです。TXCO使ったものだともっと精度の高いものもあるんですが(NXPのPCF2129など)、450円で月差13秒程度ってのはなかなかのバランスだと思います。

秋月電子のサイトから

ずっと以前に買ってあったものの使う機会がなくて部品沼に沈んでましたが、在庫リストを見ていたら出てきたので使ってみました。

配線は、SDA - SDA, SCL - SCL, Vcc - Vcc, Gnd - Gndで何のひねりもありません。動作電圧範囲が広いのでmbedでもArduino / ESP8266/ ESP-WROOM-02どれでもそのまま使えます。

欠点としては、バッテリバックアップのラインが別になっていないので、電池やスーパーキャパシタをつなぐときにはSBRダイオードなどで一手間かかってしまいます。

この点、VddとVbatが分かれているDS1307+とかPCF2129は便利なんですよね。

余談ですが、こないだPCF2129で基板を作ったんですが動作しなくて泣いています。その辺の顛末はまたいつかブログに書きます。

■ソース■

こちらの記事を参考にさせていただきました。ありがとうございます。

RTCに多いんですが、年月日時分秒すべて60進数のBCDです。通常の10進をそのままセットするとまともな値が返ってこないので、セット前 / 読み出し後に変換してやる必要があります。fromClockFormatはBCD(60進)から10進、toClockFormatは10進からBCDへの変換を行ってます。

time_t(unix時間:1970年1月1日 00:00:00.000からの経過ミリ秒)とグレゴリアン歴との変換は標準関数で済ませてしまいました。テヘペロ。

起動するとWiFiに接続してsntpから時間を取得してRTCにセットし、あとはRTCから読み込んでは時間を表示しているだけです。

このRTCにはアラームをセットして割り込みを掛けたりする機能もあるのですが、使っていません。ESP-WROOM-02でRSTにつないでやると、deep sleepの後に指定した時刻に立ち上がる、なんてこともできると思います。

// Both_RX-8025NB by kkurahashi 2016-06-21
//
// thanks:
// 秋月のリアルタイムクロック(RTC)モジュール
// http://s2jp.com/2015/03/rtc-module/
//
//
#include <Wire.h>
#include <Time.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
extern "C" {
#include "user_interface.h"
#include "sntp.h"
}
#define LCD_ADRS 0x3E
#define RTC_ADRS 0x32
void setupRTC() {
Wire.beginTransmission(RTC_ADRS);
Wire.write(0xE0);
Wire.write(0x20); // 24 hour mode
Wire.write(0x00); // PON Clear
Wire.endTransmission();
delay(1);
}
void writeRTC(time_t *inTime) {
int yy, mm, dd, HH, MM, SS;
setTime(*inTime);
Serial.print("year = ");
Serial.println(year());
yy = year() % 100;
mm = month();
dd = day();
HH = hour();
MM = minute();
SS = second();
Wire.beginTransmission(RTC_ADRS);
Wire.write(0x00);
Wire.write(toClockFormat(SS));
Wire.write(toClockFormat(MM));
Wire.write(toClockFormat(HH));
Wire.write(0x00);
Wire.write(toClockFormat(dd));
Wire.write(toClockFormat(mm));
Wire.write(toClockFormat(yy));
Wire.endTransmission();
}
void readRTC(time_t *outTime) {
int yyyy, mm, dd, HH, MM, SS;
Wire.requestFrom(RTC_ADRS, 8);
Wire.read();
SS = fromClockFormat(Wire.read());
MM = fromClockFormat(Wire.read());
HH = fromClockFormat(Wire.read());
Wire.read(); // dummy read
dd = fromClockFormat(Wire.read());
mm = fromClockFormat(Wire.read());
yyyy = 2000 + fromClockFormat(Wire.read());
setTime(HH, MM, SS, dd, mm, yyyy);
*outTime = now();
}
byte fromClockFormat(int inClock) {
return ((inClock & 0xf0) >> 4) * 10 + (inClock & 0x0f);
}
byte toClockFormat(int inValue) {
return abs(inValue / 10) * 16 + (inValue % 10);
}
//
// Wifi
//
#include "../../private_ssid.h"
//const char *ssid = "*************";
//const char *password = "*************";
WiFiClient client;
void setup()
{
Serial.begin(115200);
startWifi();
pinMode(13, OUTPUT);
Wire.begin();
setupRTC();
time_t tt = getTimestamp();
Serial.print("get sntp = ");
Serial.println(tt);
writeRTC(&tt);
}
void loop()
{
digitalWrite(13, HIGH);
time_t tt;
readRTC(&tt);
Serial.print(tt);
Serial.print(" ");
Serial.print(year());
Serial.print("-");
Serial.print(month());
Serial.print("-");
Serial.print(day());
Serial.print(" ");
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(":");
Serial.println(second());
digitalWrite(13, LOW);
delay(1000);
}
//
// WiFi
//
bool startWifi() {
WiFi.begin ( ssid, password );
Serial.println("Started");
// Wait for connection
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
Serial.println("Wifi Connected");
return true;
}
//
// sntp
//
uint32_t getTimestamp() {
configTime(9 * 3600, 0, "ntp.nict.jp", NULL, NULL);
uint32_t result = 0;
int cnt = 0;
while (result == 0) {
result = sntp_get_current_timestamp();
delay(100);
if (++cnt > 10) {
break;
}
}
return result;
}


いい感じで動いているからあと何個か買っておこう。

…秋月にアフィリエイトがないのが残念です(笑)。

2 件のコメント:

  1. エプソンのRTCは使い易いと思います。
    DS1307だと発振子が邪魔だし、そもそもちゃんと発振してくれるのかという疑問が付きまといますから。
    あとエプソンは極端に消費電流が少ないのでRTCだけ保持してシステムはスリープするとき有利です。

    最近のRX8900SA辺りだとVbat端子がありますし、チップ単価も安いです。

    返信削除
  2. コメントありがとうございます!

    ほんとに使いやすいし消費電力も小さいし、データロガーなどを作るには打って付けですよね。

    RX8900SAは存じませんでした(私の部品調達は秋月が中心なので)。今度digikeyに注文してみます。

    返信削除

注: コメントを投稿できるのは、このブログのメンバーだけです。