【パワーメーター2019】RTC_DS3231Mをmbed接続<ライブラリー無し>

SDカードでログデータを保存できるようになったが、左右クランクと母艦の3か所で増殖するログファイルの管理をするには、同時スタートした年月日時刻タイムスタンプ付きのファイル名が必要なので、RTCモジュールをamazonで3個セット仕入れました。

※2019年11月追記、このHILETGOの3個セットは、DS3231MというICが乗ってますが、これは、DS3231SNの下位版で、精度が相当低下している物であることが実験でわかりました。I2C接続はほとんど同じですが、一部レジスタで仕様削除されてます。購入される場合はICの拡大写真をよくみて、DS3231SNと書いてあるICがのっているボードを選択しないと損します。

最近は、アマゾンで格安で販売していて助かりますが、難ありで、電池をCR2032をしらずにいれると事故が発生するらしくユーザーブログで注意喚起されてます。
https://ht-deko.com/arduino/rtc_ds3231.html

●mbedでライブラリー付プログラムで動作しない
何個がライブラリー付きのサンプルプログラムがあるのですが
 NUCLEOで動作するものがありませんでした。 

しょうがないので、ライブラリー無でi2cを直接たたいて、動作させているプログラムを見つけて、それの動作を学習してなんとか所望のプログラムに改造しました。作者の方に感謝です。
https://os.mbed.com/users/zhouer/code/NUCLEO-DS3231/

●DS3231Mの仕様判りにくい
MAXIM DS3231のHP
英文マニュアル
https://datasheets.maximintegrated.com/en/ds/DS3231.pdf

I2Cの接続方法の解説が書き足りてなくて、ちんぷんかんでした。
 通常は、レジスタアドレスを指定して、値を書き入れて動作させるのですが
 どうも違っていて、0~0x07番レジスタの年月日時間分秒のデータレジスタの間をアドレスポインタがリングバッファ的にぐるぐる回るみたいです。ですので、秒から始まって年までが1セットになっていて、
 書き込みは、年を変更する場合でも全データを書き換えないといけないみたいです。

●改造プログラム
NUCLEO l432KCのSDA:PA_9,SCL:PA_10を使ってます。3.3V入力です
 時刻合わせ部分を追加してありますが、単に、whileループの前に現在の年月日時刻から数分先の時刻を書き込んで、コンパイルして、マイコンにコピペして走らせながら、時刻がきたらリセットさせれば、時刻は合いますが数秒ずれるかもしれません。今回は、タイムスタンプの目的なので数秒程度は問題になりません。

ライブラリ無しのプログラムのほうが、DS3231の基本が見えて便利です。

#include “mbed.h”

// 9600 bauds, 8-bit data, no parity
Serial pc(SERIAL_TX, SERIAL_RX);

//I2C i2c(I2C_SDA, I2C_SCL);
I2C i2c(PA_10, PA_9);//NUCLEO L432KC SDA,SCL
const int DS3231_ADDR = 0xd0;

DigitalOut myled(LED1);

int main()
{ int i;
int ret;
int sec, min, hour, day, date, month, year;
char data_write[8];
char data_read[8];
data_write[0] = 0;//time read start address
i2c.write(DS3231_ADDR, data_write, 1, 0);
data_write[0]=0x0;//na
data_write[1]=0x0;//sec
data_write[2]=0x47;//min
data_write[3]=0x3;//hour
data_write[4]=0x0;//day
data_write[5]=0x4;//date
data_write[6]=0x7;//month
data_write[7]=0x19;//year
data_write[0] = 0;//time read start address
i2c.write(DS3231_ADDR, data_write, 1, 0);
i2c.write(DS3231_ADDR, data_write, 8, 0);

while (1) {

data_write[0] = 0;//time read start address
i2c.write(DS3231_ADDR, data_write, 1, 0);
ret = i2c.read(DS3231_ADDR, data_read, 7, 0);
for(i=0;i<7;i++){
pc.printf(“data_read[%d]=0x%x\n\r”,i,data_read[i]);
}
sec = (data_read[0] >> 4) * 10 + (data_read[0] & 0x0f);
min = (data_read[1] >> 4) * 10 + (data_read[1] & 0x0f);
hour = (data_read[2] >> 5 & 0x01) * 20 + (data_read[2] >> 4 & 0x01) * 10 + (data_read[2] & 0x0f);

day = data_read[3] & 0x07;

date = (data_read[4] >> 4) * 10 + (data_read[4] & 0x0f);
month = (data_read[5] >> 4 & 0x01) * 10 + (data_read[5] & 0x0f);

year = 2000 + (data_read[6] >> 4) * 10 + (data_read[6] & 0x0f);

pc.printf(“ret = %d, %d-%02d-%02d %d %02d:%02d:%02d\n\r”, ret, year, month, date, day, hour, min, sec);
myled = !myled;
wait(1.0);
}
}

●以後
母艦NUCLEOF446REにDS3231を取りつけてプログラムも追加します。
24時間回してみて時間の精度みてみます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です