Arduinoを始めて簡単なプログラムを書くことができるようになったので、かねてからやりたかった自分の部屋の温湿度を出先からモニタすることに挑戦します。
システムの設計
温湿度を外出先からモニタするために、どのようなシステムにするかをまず考えました。まず、温湿度を測定する方法ですが、これはArduinoと温度センサー、湿度センサーを使います。こちらは、Arduinoの勉強用に買った本、”ボクのArduino工作ノート 改訂版”(鈴木哲哉 著)に記載されている温湿度モニタシールドを使います。また、測定したデータはLCDシールドに表示して、ちゃんと温湿度が測定できていることを確認します。
次に、測定したデータをどうやってWebにアップロードするかを考えます。いろいろと調べていると、東芝が販売しているFlashairにいきつきました。これは、SDカードにWi-Fiを内蔵しており、簡単にwebにファイルをアップロードすることができます。しかも、Flashair Iot Hubというサービスが提供されており、そこにcsvファイルをアップロードすれば、計測値のグラフを簡単に作ることができます。
以上をまとめると、次のようなシステムの設計になります。
準備するもの
このシステムを作るにあたって準備したものを紹介します。
・Arduino:私が用意したのは、Arduino Unoです。その他のシリーズ、互換機でも問題ありません。
・Flashair:現在、第4世代のFlashairが発売されています。世代はどれでも良いですが、新しいもののほうがベターでしょう。
・SDカードシールド:Flashairの開発支援サイト、Flashairディベロッパーズで推奨されている、Seeed StudioのSDカードシールドを使います。
・液晶:私は、Arduinoの勉強用に購入した本に記載されている液晶ディスプレイシールドを作成し、使用しました。LCDシールドは完成済みのものが売られていますので、そちらを使用しても良いと思います。
・温湿度センサー:こちらも本を参考に作成しました。作成したのは、第2章で紹介されている温湿度計です。書籍では、基板を自作していましたが、私はユニバーサル基板を使って作りました。
Arduinoプログラム
必要なものがそろったら、Arduinoのプログラムを書いていきます。
SDカードへの書き込み
まず、SDカードへのデータ書き込み部分を記述します。
#include <SPI.h> #include <SD.h> File myFile; void setup() { // put your setup code here, to run once: // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } Serial.print("Initializing SD card..."); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); SD.remove("sensor.csv"); myFile = SD.open("sensor.csv", FILE_WRITE); myFile.println("time, temp, humid, internal"); myFile.close(); }
Arduinoには、SDカードを使うための標準ライブラリが用意されています。ますは、それをインクルードします。続いて、シリアル通信でSDカードにアクセスします。そのために、SPI通信のライブラリ、SPI.hもインクルードします。
11行目から21行目がSDカードとの通信を確認している部分になります。
23行目からがSDカード内のファイルを操作している部分になります。
まず、remove(“sensor.csv”)で指定したファイルを削除します。ここで、sensor.csvというのは、計測結果を記述するためのファイルで、名前は任意です。(あくまで私がつけたファイル名)
次に、open(“sensor.csv”, FILE_WRITE)でsensor.csvを開きます。該当するファイルがなければ、新規に作成されます。FILE_WRITEは指定したファイルを読み書きモードで開くために記述します。ファイルを読むだけであれば、FILE_READと記述します。
そして、開いたファイルに書き込みます。println()は指定の文字列や数字を改行を伴ってファイルに書き込む関数です。ファイルへの書き込みが終わったら、開いていたファイルをclose()で閉じます。
以上がSDカードにファイルを書き込む手順になります。温湿度の数値を取得⇒文字列に変換⇒sensor.csvを開く⇒文字列を書き込む⇒ファイルを閉じる⇒温湿度の数値を取得⇒・・・を繰り返します。
液晶への表示
液晶への表示を行う部分について紹介します。今回使用している液晶ディスプレイはSD1602Hです。
#include <LiquidCrystal.h> //Create an instance LiquidCrystal lcd(10, 9, 8, 3, 2, 4, 7); void setup() { // put your setup code here, to run once: //LCD Setup lcd.begin(2, 16); lcd.setCursor(0, 0); lcd.print("Temperature:"); lcd.setCursor(0, 1); lcd.print("Humidity:");
まずは、液晶ディスプレイを使うための標準ライブラリをインクルードし、液晶ディスプレイ型の変数を作成します。
lcd()の中の引数は、左からrs, rw, enable, d4, d5, d6, d7で、それぞれ
rs:液晶ディスプレイのRSピンを接続したArduinoピン番号
rw:液晶ディスプレイのRWピンを接続したArduinoピン番号
enable:液晶ディスプレイのENABLEピンを接続したArduinoピン番号
d4~d7:液晶ディスプレイのd4~d7ピンを接続したArduinoピン番号
を与えます。液晶ディスプレイには、d0~d7まで8つのデータラインがありますが、d0~d3までは省略可能で、省略する場合はd4~d7を用います。
lcd.begin(2,16)は液晶に表示する文字列の行数、文字数を指定しています。今回使用する液晶は2行16文字のLCDなので、2, 16を引数にしています。
lcd.setCursor(x, y)は液晶ディスプレイのx文字目、y行目から文字を表示し始めるかを指定します。文字、行数ともに0から数え始めることに注意しましょう。
lcd.print(string)で指定した場所から引数の文字列を表示させます。かな・漢字は使わず英数字で入力します。
温湿度の測定
温湿度の測定はそれぞれ、温度と湿度のセンサを使って測定します。
温度センサはLM35DZを用いています。これは、IC温度センサで、温度が上がると電流が増える性質を利用して温度を測定しています。データシートに書かれている応用回路例と温度vs電圧特性をもとに、電圧から温度を計算します。
湿度センサはHS15Pを用いています。これは高分子感湿膜で空気中の水分を吸収し、湿度に応じた抵抗値を示します。高分子感湿膜は一方向に電流を流していると分極してしまうため、交流で抵抗値を調べる必要があります。回路の詳細は本に譲りますが、湿度vs抵抗値特性をもとに、抵抗値から湿度を計算しています。
関数は本に書かれているものを使用し、プログラムは以下の通りになります。
String t = ""; String h = ""; t = Weather.thermoString(); h = Weather.hygroString();
それぞれ、温度と湿度を小数点以下第一位まで計算し、文字列で返しています。
全体のソースコード
最後にArduino側に書き込む全体のソースコードを示します。プログラムの流れとしては、
1.液晶ディスプレイの初期化
2.シリアルポートを開く
3.Flashairの無線LANが安定するまで10秒待つ
4.計測値を書き込むcsvファイルを初期化
5.1秒ごとに温度と湿度を計算
Arduino内部のIC温度センサの値を読み込む関数も使用しています。温度の補正に使えるかと思いましたが、今のところは使っていません。
6.1秒ごとに液晶ディスプレイに表示
7.60秒ごとにcsvファイルにその時の値を書き込む
csvファイルには測定した時間、温度、湿度、内部温度を書き込みます。測定した時間はloop開始からのカウント数で代用しています。1秒ごとのループで1増えるので、大体の時間管理には使えると判断しています。次回説明するflashair IoT hubのluaスクリプトの都合で、このようなデータを作成しています。
8.4時間経ったら、csvファイルを初期化
9.5~8を繰り返す
#include <SPI.h> #include <SD.h> #include <Weather.h> #include <LiquidCrystal.h> //Create an instance LiquidCrystal lcd(10, 9, 8, 3, 2, 4, 7); File myFile; void setup() { // put your setup code here, to run once: //LCD Setup lcd.begin(2, 16); lcd.setCursor(0, 0); lcd.print("Temperature:"); lcd.setCursor(0, 1); lcd.print("Humidity:"); // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } delay(10000); Serial.print("Initializing SD card..."); if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); SD.remove("sensor2.csv"); myFile = SD.open("sensor2.csv", FILE_WRITE); myFile.println("time, temp, humid, internal"); myFile.close(); } void loop() { // put your main code here, to run repeatedly: //counter uint16_t i; String sensor_data = ""; String t = ""; String h = ""; for(i = 0; i < 14400; i++){ //read sensor t = Weather.thermoString(); h = Weather.hygroString(); //print LCD lcd.setCursor(12, 0); lcd.print(t); lcd.setCursor(12, 1); lcd.print(h); //make csv file if(i%60 == 0){ sensor_data = String(i) + "," + t + "," + h + "," + String(Weather.thermoInternal(335)); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile = SD.open("sensor2.csv", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.print("Writing to sensor.csv..."); myFile.println(sensor_data); // close the file: myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening sensor.csv"); } } //wait 1sec delay(1000); } SD.remove("sensor2.csv"); Serial.println("remove sensor2.csv"); myFile = SD.open("sensor2.csv", FILE_WRITE); myFile.println("time, temp, humid, internal"); myFile.close(); }
まとめ
FlashairとArduinoを使って、部屋の温湿度をモニタするシステムの構築に向けた取り組みの紹介をしました。
この記事ではシステムの概要とArduinoのソースコードの紹介をしました。次回の記事では、Flashairで実行するluaスクリプトについて紹介します。このluaスクリプトが動くようになるまで、苦労したのでそこにも触れたいと思います。
最後までお読みいただきありがとうございます。それではまた次の記事でお会いしましょう。