tinkering好きの素人

ものづくりの記録

rtcのアラーム機能を使う

ArduinoでHiletgoのRTCモジュールを使って、アラーム機能で1分に1回LEDを点ける。使ったのはこちら


配線は皆さん書かれているように、Arduino->rtcで
A4->SDA,A5->SCL,5V->VCC,GND->GND

ライブラリは以下を使えばI2Cしなくていい
zipダウンロードしてArduinoのスケッチ>ライブラリをインクルードからzipを指定を選択してインクルード。参照できないライブラリはコード横にURLがあるので適宜追加。

github.com


上記のgitにあるalarm_ex1をほんのすこしだけいじった。毎分05秒でArduinoのビルトインLEDが1秒光る。
このコードなら、一旦電源をとってしまってもCR2032をつけておけばもう一度つけたとき時計がずれることはなかった。念の為アマゾンのレビューにもあるように201の抵抗をはずした。

// Arduino DS3232RTC Library
// https://github.com/JChristensen/DS3232RTC
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// DS3231/DS3232 Alarm Example Sketch #1
//
// Set Alarm 1 to occur once a minute at 5 seconds after the minute.
// Detect the alarm by polling the RTC alarm flag.
//
// Hardware:
// Arduino Uno, DS3231 RTC.
// Connect RTC SDA to Arduino pin A4.
// Connect RTC SCL to Arduino pin A5.
//
// Jack Christensen 16Sep2017

#include <DS3232RTC.h>      // https://github.com/JChristensen/DS3232RTC
#include <Streaming.h>      // http://arduiniana.org/libraries/streaming/

void setup()
{
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags
  RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1);
  RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1);
  RTC.alarm(ALARM_1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_1, false);
  RTC.alarmInterrupt(ALARM_2, false);
  RTC.squareWave(SQWAVE_NONE);

  // set the RTC time and date to the compile time
  //    RTC.set(compileTime());

  // set Alarm 1 to occur at 5 seconds after every minute
  RTC.setAlarm(ALM1_MATCH_SECONDS, 5, 0, 0, 1);
  // clear the alarm flag
  RTC.alarm(ALARM_1);

  Serial << millis() << " Start ";
  printDateTime(RTC.get());
  Serial << endl;
}

void loop()
{
  if ( RTC.alarm(ALARM_1) )    // check alarm flag, clear it if set
  {
    Serial << millis() << " ALARM_1 ";
    printDateTime(RTC.get());
    Serial << endl;
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);

  }
  if ( RTC.alarm(ALARM_2) )    // check alarm flag, clear it if set
  {
    Serial << millis() << " ALARM_2 ";
    printDateTime(RTC.get());
    Serial << endl;
  }
  delay(100);                  // no need to bombard the RTC continuously
}

void printDateTime(time_t t)
{
  Serial << ((day(t) < 10) ? "0" : "") << _DEC(day(t));
  Serial << monthShortStr(month(t)) << _DEC(year(t)) << ' ';
  Serial << ((hour(t) < 10) ? "0" : "") << _DEC(hour(t)) << ':';
  Serial << ((minute(t) < 10) ? "0" : "") << _DEC(minute(t)) << ':';
  Serial << ((second(t) < 10) ? "0" : "") << _DEC(second(t));
}

// function to return the compile date and time as a time_t value
time_t compileTime()
{
  const time_t FUDGE(10);    //fudge factor to allow for upload time, etc. (seconds, YMMV)
  const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
  char compMon[3], *m;

  strncpy(compMon, compDate, 3);
  compMon[3] = '\0';
  m = strstr(months, compMon);

  tmElements_t tm;
  tm.Month = ((m - months) / 3 + 1);
  tm.Day = atoi(compDate + 4);
  tm.Year = atoi(compDate + 7) - 1970;
  tm.Hour = atoi(compTime);
  tm.Minute = atoi(compTime + 3);
  tm.Second = atoi(compTime + 6);

  time_t t = makeTime(tm);
  return t + FUDGE;        //add fudge factor to allow for compile time
}