前回、ArduinoをWebサーバーとして動作させました。それを踏まえ、今後数回に分けてそのWebサーバーをさらに拡張して簡易百葉箱の作成を目指してみます。百葉箱では気温計や湿度計が入っていますが、今回は屋内での利用を前提として温度・湿度の計測の他に前回利用した光センサーや超音波センサー等を利用して屋内の環境をセンシングする屋内用百葉箱を作ってみたいと思います。
最終的には百葉箱で収集したデータの内容をSDカードに保存してみたり、Webサーバーを通じてサーバーサイドのプログラムと連携してみたいと思います。
今回は、まず温度センサーをArduinoで動かしてみたいと思います。その上で、前回のWebサーバー版光センサーと組み合わせます。
今回の電子工作レシピ
完成までの時間目安:45分
必要なパーツ
- Arduino本体(Arduino Uno R3)http://www.switch-science.com/catalog/789/
- ブレッドボード http://www.switch-science.com/catalog/313/
- 温度センサー(LM35DZ)
- 7セグメントLED(超高輝度赤色7セグメントLED表示器(アノードコモン)NAR161-B)
- 抵抗器(220Ω)
温度センサーの使い方
温度センサーはいくつか種類がありますが今回はLM35DZという一般的なパーツを利用します。
温度センサー LM35DZ
温度センサーは他のセンサーに比べて比較的どのパーツも扱いやすくできていて、LM35DZは摂氏0℃から100℃まで測定可能で、温度センサーの温度が0℃の時は0Vの出力、1℃の時は10mVの出力、10℃の時は100mVの出力を得ることができます。
アナログ入力は0〜1023の値でArduinoで取得することができますので、下記の計算式で、Arduino側で気温を計測することが可能です。
では、さっそくArduinoとつなげてみましょう。
温度センサーの接続方法は下記の図の通りとなります。
平らな面を正面に左から+Vs Vout GNDとなります
// // 温度センサーの値をシリアルモニタに表示するプログラム // int sensorPin = A0; //アナログ0番ピンを指定 int sensorValue = 0; void setup() { Serial.begin(9600); //シリアルモニタに表示する為の設定 } void loop() { sensorValue = analogRead(sensorPin); //アナログ0番ピンからの入力値を取得 float temp = modTemp(sensorValue); //温度センサーからの入力値を変換 Serial.println(temp); //結果をシリアルモニタに表示 delay(500); //0.5秒ウェイト } //アナログ入力値を摂氏度℃に変換 float modTemp(int analog_val){ float v = 5; // 基準電圧値( V ) float tempC = ((v * analog_val) / 1024) * 100; // 摂氏に換算 return tempC;
シリアルモニタ上の表示
第5回でも利用したシリアルモニタ([ツール]-[シリアルモニタ])を使って、画面上に現在の気温が表示されました!
今回、プログラムを見ていきますと、setup()とloop()関数以外にmodTemp()という関数がプログラムの中に出現しています。これは、自分である程度まとまった処理を関数としてまとめることができます。
関数の構造
[呼ばれ元に返却するデータ形式] [関数名]([引数]){
〜ここに処理を記述〜
return [返却する値];
}
例)
loop(){ int result01 = testFunc(1,2); int result02 = testFunc(3,4); } int testFunc(int A, int B){ int C = A + B; return C; }
処理の流れと結果:loop内でtestFunc関数が呼ばれ、それぞれtestFuncに渡した引数を計算して結果をresult01・result02に返します。それぞれの結果はresult01には3、result02には7の値が入ります。
プログラムの規模が大きくなってくるとそれぞれの処理を関数としてまとめておくことで、同じ処理がプログラムの中で必要になった場合でも2重に同じコードを各必要がなく、また何かしら変更があった場合も関数内の該当部分だけ修正すれば良いですので、同じ処理がある場合は関数にまとめましょう。
温度センサーの使い方はこれだけです、簡単でしょう?
Webサーバーに搭載する
前回作成したWebサーバーに今回の温度センサーも実装してみます。
// // 温度センサー、光センサーをWebサーバーを通して表示させるプログラム // #include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //イーサネットシールドに記載されているMACアドレスを指定する IPAddress ip(192,168,0,177); //Arduinoサーバーに割り当てるIPアドレスを指定する EthernetServer server(80); //サーバーが利用するポートを指定(HTTPで利用するので基本このままの80番ポートで問題ないです) void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Ethernet.begin(mac, ip); //ここからイーサネットシールドで接続の確立を試みます server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { EthernetClient client = server.available(); //サーバーに対して外部から接続があるかどうかを監視 if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Refresh: 3"); // refresh the page automatically every 5 sec client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); //A)各センサーの入力 //光センサーの入力 int sensorReading = analogRead(0); //アナログ0番ピン client.print("Light:"); client.print(sensorReading); client.println("<br />"); delay(50); //温度センサーの入力 sensorReading = analogRead(1); //アナログ1番ピン client.print("Temp:"); client.print(modTemp(sensorReading)); client.println("<br />"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disonnected"); } } //B)アナログ入力値を摂氏度℃に変換 float modTemp(int analog_val){ float v = 5; // 基準電圧値( V ) float tempC = ((v * analog_val) / 1024) * 100; // 摂氏に換算 return tempC; }
プログラムでは、前回Webサーバーとして利用したプログラムから赤色の部分を変更しています。A)の実際にアナログ入力値を取得する部分(前回はfor文だった部分)とB)の温度を変換する為の関数を記述することで替えるだけで2つのセンサーからの値を表示することができます。
プログラムの準備ができたら、さっそくブラウザで表示してみてください。
ブラウザ上にそれぞれの値が表示されました
これで百葉箱に一歩近づきましたね!
Arduinoのデータの表示について
これまでArduinoを使ってデータの表示には色々な方法があることはわかりました。Arduinoを通してLEDなどのパーツに出力する、シリアルモニタを利用してPCで閲覧する、イーサネットシールドを通してネットワーク越しにデータを表示するetc…様々な表示の方法がありますが、今回制作を進めていく百葉箱、どんな形で取得したデータを表示したら面白いでしょうか?せっかくイーサネットシールドを使ってWebサーバーを立てたので、例えばスマフォとかで見れたら面白いですよね。表示に関しては表現方法がアイデア次第で面白くもつまらなくもなりますが、今回7セグメントLEDという電子部品を利用して入力値をそのまま表示してみます。
※7セグメントLEDの詳しい使い方は次回解説をします。
温度センサーの値を7セグメントLEDに表示してみる
Arduinoをアダプタ電源等で起動している場合は、シリアルモニタなどが見れません。そういう時に、センサーの値をすぐ見たい、と思う方は7セグメントLEDにチャレンジしてみてください。アナログ入力の値を数値で表現することが可能です。
7セグメントLED
試しにカウントアッププログラムで7セグメントの動作確認
7セグメントLEDを使うとこんな感じに。
7セグメントLEDを利用して、温度計の値をそのまま表示してみます。7セグメントLEDはそのまま利用しようとすると配線の数が一気にふくれあがるので、Arduinoが爆弾みたいな様相になっています(笑
温度センサーの数値を7セグメントLEDで表示
最終的に温度センサーと光センサーを実装
温度センサーと光センサーが搭載されて少しずつ充実してきましたね。次回以降、あともう一つくらいセンサーを搭載したらArduinoを入れるケースなどにこだわってみたいと思います。
■関連リンク
この記事の応用編として、見ル野栄司先生が世紀の大発明しちゃいました!
【第34話】みなぎるドクターミルノマスク