Arduinoを使って時間データをSDカードに記録する方法

どんな電子工作をするの?

  • ArduinoボードにRTC(実時間)モジュールとSDモジュールを接続し、時間データをSDカードに保存します。

必要な部品は?

RTC(実時間)モジュール(DS1307)1個
SDモジュール (microSDカードスロット)1個
Arduino UNO R31個

どのように動作するの?

  • RTC(実時間)モジュール(DS1307)に設定した時間を、1秒間隔でSDカードに記録します。
  • Arduino IDEのシリアルモニタ画面に日時・時刻が表示されます。
  • SDカードには[DATA_LOG.CSV]が作られています

スケッチのコードは?

  1. RTC(実時間)モジュール(DS1307)とSDモジュールを操作するためにライブラリが必要です。以下の投稿を参照ください。
//www.arduinomakesiteasy.com
//2022.5.3
//
// 1) Elegoo 実時間モジュール DS1307
// 2) 秋田通商 SDモジュール
//

//ライブラリインクルード
#include <Wire.h>
#include <DS3231.h>
#include "SPI.h" 
#include "SD.h"

//SDカード設定
File myFile;                //クラス指定
const int chipSelect = 10;  //チップセレクトピン指定

//実時間モジュール設定
DS3231 clock;
RTCDateTime dt;

//一般変数
int i;

void setup()
{
  Serial.begin(9600);

  //SDカードの初期化
  Serial.println("Initializing SD card...");
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Initialization failed or does not exist");
    while (1);
  }
  Serial.println("Initialization done.");
  Serial.println();

  //実時間モジュールの初期化
  Serial.println("Initialize RTC module");
  // Initialize DS3231
  clock.begin();

  // スケッチのコンパイル時の時刻をRTCモジュールに書き込む
  //このコードは、1回のみ実行し、2回はコメントアウトして再度コンパイルする
  //clock.setDateTime(__DATE__, __TIME__);    

  //一般変数の初期化
  i=0;
  
  delay(1000);  
  
  //シリアルログの最初の行に表示項目を表示する
  Serial.print("Year,");
  Serial.print("Month,");
  Serial.print("Day,");
  Serial.print("Hour,");
  Serial.print("Minuts,");
  Serial.print("Second,");
  Serial.println("Count)");  

  //ログデータの最初の行に記録項目を記入する
  myFile = SD.open("DATA_LOG.csv", FILE_WRITE); //SDカードをオープンする 
  myFile.print("Year,");
  myFile.print("Month,");
  myFile.print("Day,");
  myFile.print("Hour,");
  myFile.print("Minuts,");
  myFile.print("Second,");
  myFile.println("Count");  
  myFile.close(); 	//SDカードをクローズする   
}

void loop()
{
  //シリアルログの表示
  dt = clock.getDateTime();
  Serial.print(dt.year);   Serial.print(",");
  Serial.print(dt.month);  Serial.print(",");
  Serial.print(dt.day);    Serial.print(",");
  Serial.print(dt.hour);   Serial.print(",");
  Serial.print(dt.minute); Serial.print(",");
  Serial.print(dt.second); Serial.print(",");
  Serial.println(i);
   
  //SDカードへの書き込み
  myFile = SD.open("DATA_LOG.csv", FILE_WRITE); 

  myFile.print(dt.year);   myFile.print(",");
  myFile.print(dt.month);  myFile.print(",");
  myFile.print(dt.day);    myFile.print(",");
  myFile.print(dt.hour);   myFile.print(",");
  myFile.print(dt.minute); myFile.print(",");
  myFile.print(dt.second); myFile.print(",");
  myFile.println(i);

  myFile.close();

  i+=1; //iに1を加える
  
  delay(1000);   // 1秒の待ち時間
}
  • SDモジュールの使い方を[SDカードにデータを記録する方法]で学習しています。この時はArduinoにRTCモジュールを組み込んでいなかったので、ファイル作成時の時間の情報が無く、2001/01/01 1:00と表示されていました。
  • ArduinoのホームページにRTCモジュールを使用している時にファイル作成時間をファイルに入力する方法「file creation date and time in sd card ? 」がありましたので参考にしてスケッチを変更しました。
//http://forum.arduino.cc/index.php?topic=348562.msg3298426;topicseen#msg3298426

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>

File file;  // test file
const uint8_t SD_CS = 10; // SD chip select
RTC_DS1307 RTC;  // define the Real Time Clock object

 char timestamp[30];

//------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
 DateTime now = RTC.now();
 sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n", now.hour(),now.minute(),now.second(),now.month(),now.day(),now.year()-2000);
 Serial.println("yy");
 Serial.println(timestamp);
 // return date using FAT_DATE macro to format fields
 *date = FAT_DATE(now.year(), now.month(), now.day());

 // return time using FAT_TIME macro to format fields
 *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
//------------------------------------------------------------------------------
void setup() {
 
 Serial.begin(9600);
 Wire.begin();
 if (!RTC.begin()) {
   Serial.println("RTC failed");
   while(1);
 };
 // set date time callback function
 SdFile::dateTimeCallback(dateTime);
 
  DateTime now = RTC.now();
  sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n", now.hour(),now.minute(),now.second(),now.month(),now.day(),now.year()-2000);
  Serial.println("xx");
  Serial.println(timestamp);
 
 
 if (!SD.begin(SD_CS)) {
   Serial.println("SD.begin failed");
   while(1);
 }
 file = SD.open("TEST_SD.TXT", FILE_WRITE);
 file.println("Testing 1,2,3...");
 
 delay(5000);
 file.close();
 Serial.println("Done");
}
//------------------------------------------------------------------------------
void loop() {}
//www.arduinomakesiteasy.com
//2022.5.3
//
// 1) Elegoo 実時間モジュール DS1307
// 2) 秋田通商 SDモジュール
//

//ライブラリインクルード
#include <Wire.h>
#include <DS3231.h>
#include "SPI.h" 
#include "SD.h"

//SDカード設定
File myFile;                //クラス指定
const int chipSelect = 10;  //チップセレクトピン指定

//実時間モジュール設定
DS3231 clock;
RTCDateTime dt;

//一般変数
int i;

//ファイル作成・更新時のタイムスタンプを記録するスケッチ------------------------------
char timestamp[30];

// call back for file timestamps
void dateTime(uint16_t *date, uint16_t *time) {
 sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n",dt.hour,dt.minute,dt.second,dt.month,dt.day,dt.year-2000);
 // return date using FAT_DATE macro to format fields
 *date = FAT_DATE(dt.year,dt.month,dt.day);
 // return time using FAT_TIME macro to format fields
 *time = FAT_TIME(dt.hour,dt.minute,dt.second);
}
//------------------------------------------------------------------------------

void setup()
{
  Serial.begin(9600);

  //実時間モジュールの初期化
  Serial.println("Initialize RTC module");
  // Initialize DS3231
  clock.begin();

  // スケッチのコンパイル時の時刻をRTCモジュールに書き込む
  //このコードは、1回のみ実行し、2回はコメントアウトして再度コンパイルする
  //clock.setDateTime(__DATE__, __TIME__);    

  //SDカードの初期化
  Serial.println("Initializing SD card...");
  
  if (!SD.begin(chipSelect)) {
    Serial.println("Initialization failed or does not exist");
    while (1);
  }
  Serial.println("Initialization done.");
  Serial.println();

  dt = clock.getDateTime();

  //ファイル作成・更新時のタイムスタンプを記録するスケッチ------------------------------
  SdFile::dateTimeCallback(dateTime);
  sprintf(timestamp, "%02d:%02d:%02d %2d/%2d/%2d \n",dt.hour,dt.minute,dt.second,dt.month,dt.day,dt.year-2000);
  //------------------------------------------------------------------------------

  //一般変数の初期化
  i=0;
  
  delay(1000);  
  
  //シリアルログの最初の行に表示項目を表示する
  Serial.print("Year,");
  Serial.print("Month,");
  Serial.print("Day,");
  Serial.print("Hour,");
  Serial.print("Minuts,");
  Serial.print("Second,");
  Serial.println("Count)");  

  //ログデータの最初の行に記録項目を記入する
  myFile = SD.open("DATA_LOG.csv", FILE_WRITE); //SDカードをオープンする 
  myFile.print("Year,");
  myFile.print("Month,");
  myFile.print("Day,");
  myFile.print("Hour,");
  myFile.print("Minuts,");
  myFile.print("Second,");
  myFile.println("Count");  
  myFile.close();   //SDカードをクローズする   
}

void loop()
{
  //シリアルログの表示
  dt = clock.getDateTime();
  Serial.print(dt.year);   Serial.print(",");
  Serial.print(dt.month);  Serial.print(",");
  Serial.print(dt.day);    Serial.print(",");
  Serial.print(dt.hour);   Serial.print(",");
  Serial.print(dt.minute); Serial.print(",");
  Serial.print(dt.second); Serial.print(",");
  Serial.println(i);
   
  //SDカードへの書き込み
  myFile = SD.open("DATA_LOG.csv", FILE_WRITE); 

  myFile.print(dt.year);   myFile.print(",");
  myFile.print(dt.month);  myFile.print(",");
  myFile.print(dt.day);    myFile.print(",");
  myFile.print(dt.hour);   myFile.print(",");
  myFile.print(dt.minute); myFile.print(",");
  myFile.print(dt.second); myFile.print(",");
  myFile.println(i);

  myFile.close();

  i+=1; //iに1を加える
  
  delay(1000);   // 1秒の待ち時間
}
  • ファイル作成・更新時の日時が表示されるようになりました。

回路図(配線図)は?

  • Fritzingで描いた回路図(配線図)と実際の配線です。

RTCモジュールとSDモジュールを含んだシールドは?

  • Arduino UNO R3には、ハードウェアの機能を簡単に拡張するためのシールドと呼ばれる拡張ハードウェアを簡単に接続できます。
  • RTCモジュールとSDモジュールが一体となったデータロガーモジュールがあり、時間データを扱う機能とデータを保存する機能を容易に使用できます。

ご質問、誤植の指摘などありましたら。「問い合わせ のページからお願いします。