Arduino UNO R4 MINIMAでRTCを使ってみる

Arduino RTC-1

Arduino UNO R4 MINIMAを買ってから久しいですが、今一つ使い道に困っていて、とりあえずRTCを試してみることにしました。

Arduino UNO R4 MINIMAにはRTCが搭載されています。これにより、単独で時計機能を維持できます。しかしながら、MINIMAにはWi-Fiがありませんので、最初の時刻設定をどうするかが問題です。それについては、サンプルプログラムに解決方法がありました。

要は、ビルドした時の時間を取得して、その後はUSBケーブルを外して単独運転するという方法ができることが分かりました。それでは、デジタル時計を作ってみます。

#include <Wire.h>
#include<Adafruit_GFX.h>
#include<Adafruit_SSD1306.h>
#include <RTC.h>

Adafruit_SSD1306 display(-1);

DayOfWeek convertDayOfWeek(String s)
{
  if (s == String("Mon"))
  {
    return DayOfWeek::MONDAY;
  }
  if (s == String("Tue"))
  {
    return DayOfWeek::TUESDAY;
  }
  if (s == String("Wed"))
  {
    return DayOfWeek::WEDNESDAY;
  }  
  if (s == String("Thu"))
  {
    return DayOfWeek::THURSDAY;
  }  
  if (s == String("Fri"))
  {
    return DayOfWeek::FRIDAY;
  }  
  if (s == String("Sat"))
  {
    return DayOfWeek::SATURDAY;
  }  
  if (s == String("Sun"))
  {
    return DayOfWeek::SUNDAY;
  }  
}

Month convertMonth(String s)
{
  if (s == String("Jan"))
  {
    return Month::JANUARY;
  }
  if (s == String("Feb"))
  {
    return Month::FEBRUARY;
  }
  if (s == String("Mar"))
  {
    return Month::MARCH;
  }
  if (s == String("Apr"))
  {
    return Month::APRIL;
  }
  if (s == String("May"))
  {
    return Month::MAY;
  }
  if (s == String("Jun"))
  {
    return Month::JUNE;
  }
  if (s == String("Jul"))
  {
    return Month::JULY;
  }
  if (s == String("Aug"))
  {
    return Month::AUGUST;
  }
  if (s == String("Sep"))
  {
    return Month::SEPTEMBER;
  }
  if (s == String("Oct"))
  {
    return Month::OCTOBER;
  }  
  if (s == String("Nov"))
  {
    return Month::NOVEMBER;
  }
  if (s == String("Dec"))
  {
    return Month::DECEMBER;
  }  
}

RTCTime currentRTCTime()
{
  // Get a compilation timestamp of the format: Wed May 10 08:54:31 2023
  // __TIMESTAMP__ is a GNU C extension macro
  // We can't use the standard macros __DATE__ and __TIME__ because they don't provide the day of the week
  String timeStamp = __TIMESTAMP__;
  // Extract the day of the week
  int pos1 = timeStamp.indexOf(" ");
  DayOfWeek dayOfWeek = convertDayOfWeek(timeStamp.substring(0, pos1));
  // Extract the month
  ++pos1;
  int pos2 = timeStamp.indexOf(" ", pos1);
  Month month = convertMonth(timeStamp.substring(pos1, pos2));
  // Extract the day
  pos1 = ++pos2;
  pos2 = timeStamp.indexOf(" ", pos1);
  int day = timeStamp.substring(pos1, pos2).toInt();
  // Extract the hour
  pos1 = ++pos2;
  pos2 = timeStamp.indexOf(":", pos1);
  int hour = timeStamp.substring(pos1, pos2).toInt();
  // Extract the minute
  pos1 = ++pos2;
  pos2 = timeStamp.indexOf(":", pos1);
  int minute = timeStamp.substring(pos1, pos2).toInt();
  // Extract the second
  pos1 = ++pos2;
  pos2 = timeStamp.indexOf(" ", pos1);
  int second = timeStamp.substring(pos1, pos2).toInt();
  // Extract the year
  pos1 = ++pos2;
  pos2 = timeStamp.indexOf(" ", pos1);
  int year = timeStamp.substring(pos1, pos2).toInt();

  return RTCTime(day, month, year, hour, minute, second, dayOfWeek, SaveLight::SAVING_TIME_INACTIVE);
}

void setup() {

  Serial.begin(115200) ;

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  RTC.begin(); 

  RTCTime timeToSet = currentRTCTime();
  RTC.setTime(timeToSet);

  delay(1000);

}

void loop() {
  // put your main code here, to run repeatedly:
  char buff[256] ;

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);

  delay(100); 

  RTCTime currentTime;
  RTC.getTime(currentTime);

  // 現在の時刻を取得
  int hours = currentTime.getHour() ;
  int minutes = currentTime.getMinutes() ;
  int seconds = currentTime.getSeconds() ;
  int years = currentTime.getYear() ;
  int months = Month2int(currentTime.getMonth()) ;
  int days = currentTime.getDayOfMonth() ;
  
  display.setCursor(0, 0);
  sprintf(buff, "%02d:%02d:%02d", hours, minutes, seconds);

  display.print(buff);

  display.setCursor(0, 16);
  sprintf(buff, "%04d/%02d/%02d", years, months, days);

  display.print(buff);

  display.display();

  delay(250);  // 0.25秒ごとに更新

}

時間の取得部分は、サンプルを使わさせて頂いています。表示はSSD1306を使うOLEDディスプレイです。

Arduino RTC-2

まずは、USBケーブルを接続して、プログラムをArduino UNO R4 MINIMAにロードします。

Arduino RTC-3

バッテリーからArduino UNO R4 MINIMAへ電力を供給します。5VINGNDジャンパーケーブルで接続します。

そして、USBケーブルを外して、パソコンからの電力を遮断します。これで、Arduino UNO R4 MINIMA単独で時計が動作します。

Arduino RTC-4

13時間ほど動作させました。テスト開始時、電波時計との時間差は25秒でしたが、8分以上ずれています。なんと1時間あたり40秒前後もずれてしまっています。ちょっと精度が悪すぎですが、やり方が悪いのでしょうか。

どちらかというと、タイマーなどで使う方が良いのかもしれません。何か分かったら追記します。

created by Rinker
Arduino (アルドゥイーノ)
¥3,020 (2024/11/06 09:43:44時点 Amazon調べ-詳細)