以前の投稿「arduinoを使った温度測定webサーバ」とか「arduinoの気温測定で問題発生」でArduinoを使って,室温を図るwebサーバの作成について書いてきましたが,一冬過ぎて,そろそろオフィスの室温が上がり始めたこと,湿度に関する意見も部署内であることから,湿度センサを増設し,ケースに入れたバージョンを作成しました.
各種参考URL
まずは,参考URLの類.わからないことがあった場合,他の記事と比較したい場合のスタートポイントにしてください.httpサーバおよび,温度センサ関連
- http://openhardware.gridshield.net/home/arduino-snmp-temperature-sensor
- http://d.hatena.ne.jp/a10i/20110607/1307453448
- http://homepage3.nifty.com/sudamiyako/zk/AVR_ADC/AVR_ADC.html
- http://makining.com/okuzawats/dht11-temperature-humidity-20150218
- https://learn.adafruit.com/dht/connecting-to-a-dhtxx-sensor
- http://mpu.seesaa.net/category/22909809-2.html
- http://blog.livedoor.jp/hardyboy/tag/LM35DZ
- http://makining.com/okuzawats/dht11-temperature-humidity-20150218
- http://qiita.com/masato/items/99e5dac91d13650e90a2
pingのライブラリ
- http://playground.arduino.cc/Code/ICMPPing
DHTセンサのライブラリ
- https://github.com/adafruit/DHT-sensor-library
使った部品
リンクは製品販売元じゃなくて,私が買った店や有名代理店の場合もあります.
抵抗は,買った時の情報が無いので,ワット数は違っているかも.コンデンサは転がっていたやつを使ったので,同一容量の製品のwebページです.
ハードウェア
一応,Fritzingの図面も添付しますが,ユニバーサル基板の配線は,Fritzingの練習不足のため,ご勘弁ください.
回路図
現物写真
手元に適当なサイズのユニバーサル基板がなかったので,微妙に大きい.
- 表側
- 裏側
ソフトウェア
とりあえず,ソースもここに置いときます.
実装上の工夫
LM35DZの温度を読むと,非常にふらつく上に,時々とんでもない値が出てくるため以下の工夫を入れた.- 100回読む
- ソートする
- 統計的な中央値を選んでそれを結果とする
現在の問題
わかっている問題は以下の2点- 精度
温度や湿度の校正はしていない(そんな設備がない)ので精度は不明. - DHT11とLM35の出力の違い
DHT11の測定値とLM35の測定値が約2度程度異なり,DHTが常に高い温度を返す.
ソースコード
/* LM35DZを用いた温度測定(0℃~100℃) シリアルモニターに摂氏で表示させるのと,httpでのアクセスで答える 参考URL httpサーバおよび,温度センサ関連 http://openhardware.gridshield.net/home/arduino-snmp-temperature-sensor http://d.hatena.ne.jp/a10i/20110607/1307453448 http://homepage3.nifty.com/sudamiyako/zk/AVR_ADC/AVR_ADC.html http://makining.com/okuzawats/dht11-temperature-humidity-20150218 https://learn.adafruit.com/dht/connecting-to-a-dhtxx-sensor http://mpu.seesaa.net/category/22909809-2.html http://blog.livedoor.jp/hardyboy/tag/LM35DZ http://makining.com/okuzawats/dht11-temperature-humidity-20150218 http://qiita.com/masato/items/99e5dac91d13650e90a2 pingのライブラリ http://playground.arduino.cc/Code/ICMPPing DHTセンサのライブラリ https://github.com/adafruit/DHT-sensor-library */ /* 固定IP設定の時に,pingで設定を確認する機能を有効にする場合に定義する */ #define USE_PING /* ネットワーク関係のインクルード */ #include//#include //#include #include //#include //#include //#include #ifdef USE_PING #include #endif /* USE_PING */ /* DHTセンサ関係のインクルード */ #include "DHT.h" /* * DHT11関係の定義 */ #define DHTPIN 2 // what pin we're connected to // Uncomment whatever type you're using! #define DHTTYPE DHT11 // DHT 11 //#define DHTTYPE DHT22 // DHT 22 (AM2302) //#define DHTTYPE DHT21 // DHT 21 (AM2301) // Connect pin 1 (on the left) of the sensor to +5V // NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1 // to 3.3V instead of 5V! // Connect pin 2 of the sensor to whatever your DHTPIN is // Connect pin 4 (on the right) of the sensor to GROUND // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); // NOTE: For working with a faster chip, like an Arduino Due or Teensy, you // might need to increase the threshold for cycle counts considered a 1 or 0. // You can do this by passing a 3rd parameter for this threshold. It's a bit // of fiddling to find the right value, but in general the faster the CPU the // higher the value. The default for a 16mhz AVR is a value of 6. For an // Arduino Due that runs at 84mhz a value of 30 works. // Example to initialize DHT sensor for Arduino Due: //DHT dht(DHTPIN, DHTTYPE, 30); /* * LM35(温度センサ)関連の定数の定義 */ float v=5.0; // MEGA2560やEthernet R3は5.0V駆動 float tempC = 0; // 摂氏値( ℃ ) float Threshold=28.0; // 警告LEDをつける閾値(気温) float offset = 0; // センサの温度ズレを修正する変数 #define LOOPNUMBER 100 #define MEDIAN 50 /* * 配線関連の定数 */ int TempSensorPin = 0; // センサ用のアナログI/Fは0番を利用 /* * ネットワーク関係の定数 */ byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x92, 0x1A }; //アドレスは手持ちのarduinoのものに変更すること boolean useDhcp = false; // DHCPで運用する場合は true に変更 // DHCPでのアドレス取得失敗時の対策や,長時間経過後のアドレス再割当て等は対応していない /* 以下は固定IP運用の場合の変数なので適宜変更して使用すること */ IPAddress ip(192,168,0,201); IPAddress dnsServer(192,168,0,1); IPAddress gatewayAddress(192,168,0,1); IPAddress netMask(255,255,255,0); #ifdef USE_PING SOCKET pingSocket = 0; char buffer [256]; #endif /* USE_PING */ /* * デバッグ関連 */ boolean debugFlag=false; // デバッグ目的で,各種情報をシリアルに出力する場合は true /* * プログラム本体 */ #ifdef USE_PING ICMPPing ping(pingSocket, (uint16_t)random(0, 255)); #endif /* USE_PING */ EthernetServer server(80); // サーバオブジェクトの定義. 引数はポート番号 void setup() { if (debugFlag) { // シリアル通信速度 Serial.begin(9600); } // DHT11センサの初期化 dht.begin(); // MACアドレスとIPアドレスの設定 // 参考URL http://arduino.cc/en/Reference/EthernetBegin if (useDhcp) { Serial.println("configure Ethernet using DHCP"); if ((Ethernet.begin(mac)==0) && (debugFlag)) { Serial.println("Failed."); } else { Serial.println("Success."); } } else { Serial.println("Manual ip confuguration of ethernet"); Ethernet.begin(mac, ip, dnsServer, gatewayAddress, netMask); Serial.println("done."); #ifdef USE_PING // ルータのアドレスにping // 参考URL http://playground.arduino.cc/Code/ICMPPing ICMPEchoReply echoReply = ping(gatewayAddress, 4); if (debugFlag) { if (echoReply.status == SUCCESS) { Serial.println("Ping to Gateway address : success"); } else { Serial.println("Ping to Gateway address : fail"); } } #endif /* USE_PING */ } if (debugFlag) { // IPアドレスのシリアルへの出力 Serial.println("IP address of Ethernet Interface"); Serial.println(Ethernet.localIP()); // float temperature = getLMTemperature(TempSensorPin); float h = getDHTHumidity(); float t = getDHTCTemperature(); float f = getDHTFTemperature(); } // サーバの実行 server.begin(); } void loop() { // 接続してきたクライアントを示すオブジェクトを生成 EthernetClient client = server.available(); if (client) { if (debugFlag) { Serial.println("Connection established by a client"); } // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); //一文字読み取り // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply 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: 5"); // refresh the page automatically every 5 sec client.println(); client.println(""); client.println(""); // LM35温度読み取り float temperature = getLMTemperature(TempSensorPin); client.println("LM35 output"); client.println(" "); client.print("Temperature: "); //client.print(temperature); //client.println(" degrees Celsius"); //client.println(" "); float temperatureEX = getLMTemperatureEX(TempSensorPin); //client.print("Fixed Temperature: "); client.print(temperatureEX); client.println(" degrees Celsius"); client.println(" "); client.println(" "); // // DHT11の温度湿度 float h = getDHTHumidity(); // Read temperature as Celsius float t = getDHTCTemperature(); // Read temperature as Fahrenheit float f = getDHTFTemperature(); float hi = dht.computeHeatIndex(f, h); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t) || isnan(f)) { if (debugFlag) { Serial.println("Failed to read from DHT sensor!"); } client.println("Failed to read from DHT sensor!"); client.println(" "); } else { client.println("DHT11 output"); client.println(" "); client.print("Temperature: "); client.print(t); client.println(" degree Celsius"); client.println(" "); /* client.print(f); client.println(" degree Fahrenheit"); client.println(" "); */ client.print("Humidity: "); client.print(h); client.println(" \%"); client.println(" "); /* client.print("Heat index: "); client.print(hi); client.println(" degree Fahrenheit"); client.println(" "); */ if (debugFlag) { Serial.println("Heat index: "); Serial.println(hi); } } // // client.println(""); 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(); if (debugFlag) { Serial.println("client disconnected"); } } } // // DHT11の温度と湿度読み取り関数 float getDHTCTemperature(){ float t = dht.readTemperature(); if (debugFlag) { // 温度のシリアルへの出力 Serial.println("DHT11 celcious temperature is"); Serial.println(t); } return t; } float getDHTFTemperature(){ float t = dht.readTemperature(true); if (debugFlag) { // 温度のシリアルへの出力 Serial.println("DHT11 Faren temperature is"); Serial.println(t); } return t; } float getDHTHumidity(){ float h = dht.readHumidity(); if (debugFlag) { // 湿度のシリアルへの出力 Serial.println("DHT11 Humidity is"); Serial.println(h); } return h; } // // LM35の温度読み取り関数 // float getLMTemperature(int pin){ float t; t = analogRead( pin ); t = ((v * t) / 1024) * 100; t = t + offset; if (debugFlag) { // 温度のシリアルへの出力 Serial.println("temperature is"); Serial.println(t); } return t; } float getLMTemperatureEX(int pin){ int buff[LOOPNUMBER]; float tmp; if (debugFlag){ Serial.print("Data = "); } for (int i=0 ; i < LOOPNUMBER ; i++){ buff[i] = analogRead( pin ); if (debugFlag) { Serial.print(buff[i]); Serial.print(" , "); } } if (debugFlag) { Serial.println(""); } sort(buff,LOOPNUMBER); if (debugFlag){ Serial.print("SortData = "); for (int i=0 ; i < LOOPNUMBER ; i++){ if (debugFlag) { Serial.print(buff[i]); Serial.print(" , "); } } } tmp = ((v * buff[MEDIAN]) / 1023) * 100; tmp = tmp + offset; if (debugFlag) { // 温度のシリアルへの出力 Serial.println("temperature is"); Serial.println(tmp); Serial.println("Pin number = "); Serial.println(pin); } return tmp; } void sort(int a[], int size) { for(int i=0; i<(size-1); i++) { for(int o=0; o<(size-(i+1)); o++) { if(a[o] > a[o+1]) { int t = a[o]; a[o] = a[o+1]; a[o+1] = t; } } } }
0 件のコメント:
コメントを投稿