温湿度データのような長期間の測定値など、さらに広範囲のデータを保存したい場合は、SDカードを使用します。PCでよくデータ移動に使われるSDカードは、通常数ギガバイトのさまざまなストレージボリュームがあります。この巨大な保存領域は、Arduinoを使用する上で十分な容量です。
接続には、専用アダプタモジュールとシールド(プラグインボード)の両方を用意しています。
別々のモジュールやシールドを使用するかどうかにかかわらず、接続は通常SPIを介して行われます。シールドの場合、自由に選択できるチップセレクトラインは通常4ピンに接続されています。 15秒ごとに温度と湿度を測定し、その情報を現在のタイムスタンプと一緒にSDカードのテキストファイルに書き込むデータロガーを作りたいと思います。タイムモジュールとしては、DS3231のリアルタイムクロックを使用し、DHT22が温湿度センサとして機能します。
RTCモジュールはI²C経由で、SDカードアダプタはSPI経由で、温度センサは通常のデジタルピンで接続します。SDカードシールドを代わりに使用した場合は、SDカードアダプタへの線材での接続は不要です。
SDカードは市販されている機種であれば何でもいいのですが、ファイルシステムがFAT16かFAT32である必要があります。他のファイルシステムには対応していません。疑わしい場合は、コンピュータ(Windows)上でカードを右クリックして「フォーマット」オプションを選択することで、カードをフォーマットすることができます。この作業を行うとカード内のデータがすべて削除されます。また、Arduinoアダプタを直接パソコンのSDカードリーダーとして使えません。SDカードのデータを見るには、SDカードリーダーがパソコンに内蔵されていない場合は、パソコン用のカードリーダーが必要になる場合があります。
フォーマットの設定で重要なのはファイルシステムが「FAT」または「FAT32」で、その他の値はSDカードのサイズによって異なる場合があります。
SDモジュールを制御するために必要なライブラリはArduino IDEにプリインストールされているので、プログラミングに専念することができます。センサデータを15秒間隔で取得し、タイムスタンプと一緒にデータセットを作成し、SDカード内のファイル「temp_log.txt」に書き込み、さらにシリアルモニタに出力します。
ソース
#define SPI_CS 4 //SPI接続のチップセレクト端子 #define SENSORPIN 2 #include "SPI.h" #include "SD.h" #include "DHT.h" #include "DS3231.h" DHT dht(SENSORPIN, DHT22); DS3231 ds3231; float Temp; float Humidity; boolean Dummy = false; void setup() { dht.begin(); Wire.begin(); Serial.begin(9600); Serial.println("SD-Card initialize..."); if(!SD.begin(SPI_CS)) //(1) { Serial.println("Card not readable!"); while (1); //無限ループでプログラムを停止 } Serial.println("successful."); } void loop() { float Temp = dht.readTemperature(); float Humidity = dht.readHumidity(); String DataRecord = "# " + String(ds3231.getDate(),2) + "." + String(ds3231.getMonth(Dummy)) + "." + ds3231.getYear() + ", " + ds3231.getHour(Dummy, Dummy) + ":"; //(2) if(ds3231.getMinute() < 10) DataRecord = DataRecord + "0"; DataRecord = DataRecord + ds3231.getMinute() + ":"; if(ds3231.getSecond() < 10) DataRecord = DataRecord + "0"; DataRecord = DataRecord + ds3231.getSecond() + " # Temperatur: " + String(Temp) + " # Humidity: " + String(Humidity) + " #"; Serial.println(DataRecord); //(3) File File1 = SD.open("temp_log.txt", FILE_WRITE); //(4) if(File1) //(5) { File1.println(DataRecord); //(6) File1.close(); //(7) } else { Serial.println("DataRecord could not be written!"); } delay(15000); }
(1) SD.hライブラリは、関数begin()で接続を確立するオブジェクトSDを提供しています。引数としてSDカードアダプタのチップセレクト端子が渡されているので、この引数を変更すれば複数のカードリーダーを同じSPIバスで動作させられます。この関数は、SD カードがあるかどうかをテストします。読み込めない場合、または別のエラーが発生した場合は、falseが返されます。
(2) 次の数行にわたって、String型文字列変数DataRecordを宣言し、値初期化します。
(3) 文字列変数DataRecordに各種測定データの追記が完了したので、ここで文字列変数DataRecordがデータセットとしてシリアルモニタに表示されます。
(4) Fileオブジェクト型のFile1は、データを書き込みたいテキストファイルを表します。open()で開きます。ここでのファイル名の長さは8文字(名前の拡張子は3文字)までです。
(5) ファイルのオープンに失敗した場合、FileオブジェクトFile1は空なのでif文はfalseとなり、そうでなければif文はtrueです。
(6) ファイルへの書き込みは、シリアルモニタの場合と同様です。
(7) ただし、すぐにさらにデータを書き込む場合を除いて、もう一度ファイルを閉じることが重要です。これを行わないと、電源が切断されたり、close()エラーの前にリセットが実行されたりすると、データが失われる可能性があります。
temp_log.txtというファイルでは、ファイルの最後に常に新しいデータが追加されています。内容は最初の2行のステータスメッセージを除いて、シリアルモニタの出力と全く同じです。
もちろん、カンマやセミコロンでデータを区切って、CSV(Comma-Separated Values)としてマイクロソフト社のエクセルなどのデータ処理ソフトに取り込んで表示することも可能です。このような作業を経ればグラフィカルな評価や分析も可能です。
コメントを残す