最終更新日:2020年1月26日
気象観測出来るだけのセンサを、この評価ボードに接続してブラウザでモニタ出来るように出来ないかという点を検討します。
最初に判っている事は、結構制限があるという事です。
気象業務法第6条により、ホームページでの公開は、成果の発表にあたりますので、届出が必要となります。
何を意味しているかというと、ホームページで不特定多数の人が閲覧できる気象データを公表するためには、資格を持った人が認可された計測機器で取得した情報を表示しなくてはいけないようです。この点を十分理解した上で、法に触れない範囲で扱う必要があります。
気象情報の要素を検討します。
- 気温
- 湿度
- 照度
- 風向風速
- 雨量
それに付随する機能として、
- 自己電力確保 太陽光発電 充電装置
が考えられます。また、農業等に絡めると、
- CO2濃度
も必要となるようです。
市販の観測ユニットを調査してみました。
昔は『百葉箱』をイメージしたと思います。しかし、現状『百葉箱』は殆ど残っていないようです。認可装置も『百葉箱』とは似ても似つかない形態です。
『POTEKA』と云う装置は認可装置のようです。価格は確認出来ていません。守谷市が8台設置したニュースがあり、公開された情報が見つかれば明らかになります。
『Vantage Vue』というウェザーステーションは\59800と可成り安価な気象観測機器です。
『プロフェッショナルワイヤレス ウェザーステーション』は $89.99USと更に安価です。
気になった点としてワイヤレスだと技適が適用されていないと思われるので、日本では使いづらいです。
この商品はMISOLIE Technology社という会社が扱っていますが、OfficialSiteを見てみると気象観測商品がたくさん掲載されています。こういう会社もあるんだと感心しました。改造して使うような物を確認したところ、『4M 気象観測ステーション』なるものを見つけました。香港の4Mと云うメーカの商品で型番:FM03279 です。どの程度電子化できるか判りませんが、ベースが\1500でペットボトルの口ネジに固定出来るものです。置き換えるセンサが見つかれば面白いです。紹介記事がないか気になるところです。
MISOLIEの雨量計についてもう少し調べました。型番は WH-SP-RG で 12$US 程度の価格のようです。
仕様詳細が提供されていませんが、FAQによると、0.3mmの雨量で1カウントになるような仕組みとのことです。
面積は雨受けは 21 × 11cm で深さが2cmのようです。日本だとφ20cmを要求していることから、一寸面積は異なります。
コネクタはRJ11かと思いますが判りません。
CO2濃度用のセンサモジュールを調べて見ました。
- Arduino用にはHANWEI ELECTRONICS社のMG-811を使用したモジュールが多いようです。このセンサはDC6Vを供給する必要があり、またアナログ出力なのでBluePillでは扱いづらいです。
- MH-Z14というモジュールがありました。5V供給でデジタル出力(シリアル、PWM)が可能です。$20程度で販売されていることからリーズナブルではあります。
- AMS社が提供するCCS811というchipがCO2検知に使えるとあります。3.3V供給でI2Cで扱えます。$10程度で提供されています。興味深いです。
大気中のCO2濃度は400ppm(0.04%)と云われています。厚生労働省 建築物環境衛生管理基準では室内において1000ppm以下が望ましいとあり、40,000ppm以上で人体にダメージが出ると有ります。
大気中でどの程度の変化が有るのか判りませんが、室内においてCO2濃度は結構変化が有るとのことです。満員電車内では空調がなければ すぐに5,000ppm以上となり人は異常を感じるレベルになるようです。
とりあえず、以下のような構成でExampleを検討してみました。
基本はブラウザ表示ですが、LocalでもLCDに表示するようにします。情報としては6点。
- 気圧 Pa値 最大6桁
- 気温 ℃値 最大3桁 2.1
- 湿度 %RH 最大3桁 2.1
- 風速 m/sec 最大3桁 2.1
- 風向 16方位
- 雨量 mm/h 最大4桁 3.1
MISOLIE Technologyの『プロフェッショナルワイヤレス ウェザーステーション』のパーツを調査しました。すると、温度湿度はSHTxx(正確なところは判っていない)、気圧はBMP280、風速はパルス出力とあり、多分エンコーダ出力と思われる。風向は抵抗値とあり、多分ポテンショメータを使っていると考える。雨量はリードスイッチと思われる。
これらを考慮して、気圧・温度湿度はBME280(I2C) 風速はPB10へカウンタ入力、風向はPB0へアナログ電圧入力、雨量はPB11へ接点入力と検討しました。iPhoneから無線ルータ経由で制御出来ることも確認しています。当然ですが、、、
やはり確認は必要で、同じHTMLコードでBOXサイズ5としてもWindowsOS・Chromeだと余裕で収まるのに、iPhone・Chromeだと6桁表示が出来ないことが判りました。修正が必要です。https://ipアドレス/setup でアクセスすると MACアドレス等の情報を確認/変更出来ます。これによって、一つのバイナリーコードがあればMACアドレスの異なるモジュールをいくつも構築可能となります。また、IPアドレスも自由に設定出来ることになります。
ソースコードはこんな感じになります。
このコードを実行するに当たり追加が必要なライブラリは、
/* * 20200126 T.Wanibe STM32MINIShieldEvaluationプロジェクト用にレタッチ * STM32MINIShield基板に基づいてPinアサインを決めています。 * 初期のMACアドレスはWiznetが提供しているモノを使用しています。 * ブラウザを介して後から実際のデバイスに提供されているMACアドレスに変更する必要があります。 * IPアドレスに関しても192.168.0.xのZoneにて192.168.0.200を初期値にしています。 * W5500はDHCPも可能ですが、アドレス変更等に問題が出ますのでFIXアドレスを推奨します。 * 気象データを表示するようなモノを作成しました。 * 気圧・気温・湿度はBME280 I2Cモジュール ※BMP280では無いです。 * 風速はカウンタ入力 PB10 最大999m/s で 1秒毎に入力カウントを表示します。変換係数を与えることで風速となります。 * 風向はアナログ入力 PB0 16方針 入力電圧値により16方位を表示します。 * 雨量は接点入力 PB1 雨量は1カウント0.3mmのカップを使用します。カウントアップ時に前回のカウントアップ時の時間差を求め1時間当たりの雨量を計算します。 * デバッグ用にLEDは2つ。PB8,PB9 STM32MINIShield基板に有るLEDをデバッグ用に使用します。 * iPhoneの場合6桁表示のためにはBOXSIZE=6が必要です。 * 最大131072バイトのフラッシュメモリのうち、スケッチが64072バイト(48%)を使っています。 * 最大20480バイトのRAMのうち、グローバル変数が4848バイト(23%)を使っていて、ローカル変数で15632バイト使うことができます。 */ #include <SPI.h> // for Ethernet.h #include <Ethernet3.h> // for Ethernet #include <EEPROM.h> #include <avr/pgmspace.h> #include <Wire.h> #include <BME280I2C.h> #include <ST7032.h> #define HttpPort 80 #define LED PC13 //BluePill基板に付いているLED //I2C接続のアドレスを記載しておきます。バッティングを防ぐため //PINアサインを記載します。 #define W550io_Rst PA8 //NIC_Reset #define SPI1_NSS_PIN PA4 //NIC_ChipSelect #define LED1 PB8 //LED出力1 #define LED2 PB9 //LED出力2 #define HOUI PB0 //アナログ入力 #define FUSOKU PB10 //カウンタ入力 #define URYO PB11 //デジタル入力 #define SerialValid false //----------------------- VARIABLES LED ------------------------// byte mac[] = {0x00,0x08,0xDC,0x54,0x4D,0xD0}; //Wiznet byte ip[] = {192, 168, 0, 200}; byte dns_server[] = {192, 168, 0, 1}; byte gateway[] = {0, 0, 0, 0}; byte subnet[] = {255, 255, 255, 0}; String HTTP_req; // stores the HTTP request int dout[3] = {0,0,0}; // 1 で消灯 0で点灯 const char titleStr[] = "STM32MINIShield"; byte ErrorTMP = false; byte ErrorHUM = false; byte ErrorPRS = false; const byte EID = 0x92; //ボード内パラメータ保存の為のKEYID uint8_t cols = 16; uint8_t rows = 2; uint8_t charsize = LCD_5x8DOTS; uint8_t Contrast = 40; char printBuf[20]; char *printBuf2; char *printBuf3; volatile bool CntValid = false; volatile long gHOUI = 0; volatile long gFUSOKU = 0; volatile double gURYO = 0.0; volatile long offset = 0; volatile long gViewValue = 0; double URYOunit = 0.3; //1カウントの雨量 unsigned int nowtime,gPretime; EthernetServer server(HttpPort); EthernetClient client; ST7032 lcd; //ST7032 lcd(int i2c_addr); BME280I2C bme; // Default : forced mode, standby time = 1000 ms // Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off, //------------------信号変化割込でカウンタ値をインクリメントする。 void FUSOKUCountUp(void) { if(SerialValid) Serial.print(F("*")); gFUSOKU++; } //---------------雨量の計測方法は要検討 単に1時間のカウント値ではダメ。 void RainFallCountUp(void) { if(SerialValid) Serial.print(F("!")); nowtime = millis(); gURYO = URYOunit * 1000.0 * 3600.0 / double(nowtime - gPretime); gPretime = nowtime; } //--------------- void ResetCount(void){ if(SerialValid) Serial.print(F("R")); gFUSOKU = 0; } //--------------- void ViewValue(void){ gViewValue = gFUSOKU; CntValid = true; ResetCount(); } //---------------------------------- void LANSetup(){ int idcheck = EEPROM.read(0); //KEYID読込 if (idcheck != EID){ //idがIDの値ではない場合、 //このスケッチがシールドを設定する前に使用されていなかったことを意味します //スケッチの始めに書かれた値を使用するだけです } if (idcheck == EID){ //idがIDと同じ値の場合、 //これは、このスケッチがシールドを設定するために使用されたことを意味します。 //EERPOMの値を読み取ってシールドを設定します。 for (int i = 0; i < 6; i++){ mac[i] = EEPROM.read(i+1); } for (int i = 0; i < 4; i++){ ip[i] = EEPROM.read(i+7); } for (int i = 0; i < 4; i++){ subnet[i] = EEPROM.read(i+11); } for (int i = 0; i < 4; i++){ gateway[i] = EEPROM.read(i+15); } } Ethernet.begin(mac, ip); //推奨 // Ethernet.begin(mac); //DHCPの場合 // Ethernet.begin(mac, ip, subnet); //SubnetMaskを意識した場合。 // Ethernet.begin(mac, ip, subnet, gateway); //gatewayを意識した場合。 } //--------------------------HTML出力 // HTMLのコードを作成する場合は、HTMLエディタで構築した後、行毎にclient.println(F(""))に割り当てます。 void PrintNormalPage( EthernetClient client,String parm){ PrintResponse200(client); client.println(F("<!doctype html>")); client.print(F("<html lang='ja'>\n\t<head>\n\t\t<title>")); client.print(titleStr); client.println(F("</title>\n")); client.println(F("\t\t<meta charset='UTF-8' name='viewport' content='width=240px' />\n")); client.println(F("\t\t<script type='text/javascript'>\n")); client.println(F("\t\tfunction createXMLHttpRequest(cbFunc){\n")); client.println(F("\t\t\tvar XObj = new XMLHttpRequest();\n")); client.println(F("\t\t\tif(XObj) XObj.onreadystatechange = cbFunc;return XObj;\n\t\t}\n")); client.println(F("\t\tfunction setData(val){\n\t\t\thtObj = createXMLHttpRequest(displayData);\n")); client.println(F("\t\t\tif(htObj){\n\t\t\t\thtObj.open('GET','/?btn='+val,true);htObj.send(null);\n\t\t\t}\n\t\t}\n")); client.println(F("\t\tfunction getData(){\n\t\t\thtObj = createXMLHttpRequest(displayData);\n")); client.println(F("\t\t\tif(htObj){\n\t\t\t\thtObj.open('GET','/?=',true);htObj.send(null);\n\t\t\t}\n\t\t}\n")); client.println(F("\t\tfunction displayData(){\n\t\t\tif((htObj.readyState == 4) && (htObj.status == 200)){\n")); client.println(F("\t\t\tdocument.getElementById('result').innerHTML = htObj.responseText;\n\t\t\t}\n\t\t}\n")); client.println(F("\t\tfunction strT(){\n\t\t\tgetData(); timerID=setTimeout('strT()',document.getElementById('tf1').value);\n")); client.println(F("\t\t\tdocument.getElementById('btn100').value = 'STARTING';\n\t\t}\n")); client.println(F("\t\tfunction clrT(){\n\t\t\tclearTimeout(timerID);\n")); client.println(F("\t\t\tdocument.getElementById('btn100').value = 'START';\n\t\t}\n")); client.println(F("\t\twindow.onload = function() {")); client.println(F("\t\t\tif (navigator.onLine === true) {")); client.println(F("\t\t\t\talert('current network status is online');")); client.println(F("\t\t\t} else if (navigator.onLine === false) {")); client.println(F("\t\t\t\talert('current network status is offline');")); client.println(F("\t\t\t} else {")); client.println(F("\t\t\t\talert('current network status is unknown');")); client.println(F("\t\t\t}")); client.println(F("\t\t}")); client.println(F("\t\tfunction setInputBackGroundColor(idname,flg){")); client.println(F("\t\t\tvar obj = document.getElementByName(idname);")); //フォームの色を初期値の 白 に戻す client.println(F("\t\t\tif(flg){\n\t\t\t\tobj[0].stle.backgroundColor='#ff0000';\n")); //値のチェック client.println(F("\t\t\t}else{\n\t\t\t\tobj[0].stle.backgroundColor='#ffffff';\n")); //半角英数以外の場合は背景色を 薄赤 へ変更 client.println(F("\t\t\t}\n\t\t}\n")); client.println(F("\t\t</script>\n\t</head>\n\t<body onLoad='getData()'>\n")); client.println(F("\t<form action='/' method='GET'>\n")); client.print(F("\t<h2 class='text-center'><P><CENTER>")); client.print(titleStr); client.println(F("</CENTER></h2>\n")); client.println(F("\t<BLOCKQUOTE>\n\t\t<CENTER><BR / CLEAR='ALL'><TABLE WIDTH='280' BORDER='0' CELLSPACING='0' CELLPADDING='0'>\n")); client.println(F("\t\t\t<TR>\n\t\t\t\t<TD WIDTH='100%'>\n")); client.println(F("\t\t\t\t<input id='btn0' type='button' value=' LED1 ' onClick='setData(1)'>\n")); client.println(F("\t\t\t\t<input id='btn1' type='button' value=' LED2 ' onClick='setData(2)'><br / CLEAR='ALL'>\n")); client.println(F("\t\t\t\t<input id='btn100' type='button' value=' START ' onClick='strT()'>\n")); client.println(F("\t\t\t\t<input id='btn200' type='button' value=' STOP ' onClick='clrT()'>\n")); client.println(F("\t\t\t\t<input id='tf1' type='text' size='5' value='1000'>[msec]\n")); client.println(F("\t\t\t\t<br / CLEAR='ALL'></TD>\n\t\t\t</TR>\n\t\t</TABLE></CENTER>\n\t\t<P><HR></P>")); client.println(F("\t\t\t\t<P><CENTER><TABLE WIDTH='280' BORDER='0' CELLSPACING='0' CELLPADDING='0'><TR>\n<TD WIDTH='100%'>")); client.println(F("\n\t\t<div id='result'></div></TD></TR></TABLE></CENTER></P><br />\n")); client.println(F("\t</BLOCKQUOTE>\n\t</form>\n\t</body>\n</html>")); HTTP_req = ""; } //--------------------------HTML出力(SetUpページ) void PrintSetUpPage( EthernetClient client,String parm) { PrintResponse200(client); client.println(F("<!DOCTYPE HTML PUBLIC \"\"><html><HEAD>")); client.println(F("<META http-equiv=\"Content-Type\" charset=UTF-8\">")); client.println(F("<META http-equiv=\"Content-Style-Type\">")); client.print(F("<TITLE>")); client.print(titleStr); client.println(F(" Setup Page</TITLE></HEAD>")); client.println(F("<BODY marginwidth=\"0\" marginheight=\"0\" ")); client.println(F("leftmargin=\"0\" style=\"margin: 0; padding: 0;\">")); client.println(F("<BLOCKQUOTE><BLOCKQUOTE><table bgcolor=\"#17A1A5\" ")); client.println(F("border=\"0\" width=\"100%\" cellpadding=\"1\" ")); client.println(F("style=\"font-family:Verdana;color:#ffffff;font-size:12px;\">")); client.println(F("<tr><td> ")); client.print(titleStr); client.println(F(" Setup Page</td></tr></table><br>")); // client.println(F("<script>function hex2num (s_hex) {eval(\"var n_num=0X\" + ")); client.println(F("s_hex);return n_num;}</script><FORM><input type=\"hidden\" ")); client.println(F("name=\"SBM\" value=\"1\"><table><tr><td>MAC:</td><td>")); client.println(F("<input id=\"T1\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT1\" value=\"")); client.print(mac[0],HEX); client.println(F("\">.<input id=\"T3\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT2\" value=\"")); client.print(mac[1],HEX); client.println(F("\">.<input id=\"T5\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT3\" value=\"")); client.print(mac[2],HEX); client.println(F("\">.<input id=\"T7\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT4\" value=\"")); client.print(mac[3],HEX); client.println(F("\">.<input id=\"T9\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT5\" value=\"")); client.print(mac[4],HEX); client.println(F("\">.<input id=\"T11\" type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"2\" name=\"DT6\" value=\"")); client.print(mac[5],HEX); // client.println(F("\"><input id=\"T2\" type=\"hidden\" name=\"DT1\">")); client.println(F("<input id=\"T4\" type=\"hidden\" name=\"DT2\">")); client.println(F("<input id=\"T6\" type=\"hidden\" name=\"DT3\">")); client.println(F("<input id=\"T8\" type=\"hidden\" name=\"DT4\">")); client.println(F("<input id=\"T10\" type=\"hidden\" name=\"DT5\">")); client.println(F("<input id=\"T12\" type=\"hidden\" name=\"DT6\">")); client.println(F("</td></tr><tr><td>IP:</td><td><input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT7\" value=\"")); client.print(ip[0],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT8\" value=\"")); client.print(ip[1],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT9\" value=\"")); client.print(ip[2],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT10\" value=\"")); client.print(ip[3],DEC); // client.println(F("\"></td></tr><tr><td>MASK:</td><td><input type=")); client.println(F("\"text\" size=\"3\" maxlength=\"3\" name=\"DT11\" value=\"")); client.print(subnet[0],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT12\" value=\"")); client.print(subnet[1],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT13\" value=\"")); client.print(subnet[2],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT14\" value=\"")); client.print(subnet[3],DEC); // client.println(F("\"></td></tr><tr><td>GW:</td><td><input type=\"text\" ")); client.println(F("size=\"3\" maxlength=\"3\" name=\"DT15\" value=\"")); client.print(gateway[0],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT16\" value=\"")); client.print(gateway[1],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT17\" value=\"")); client.print(gateway[2],DEC); client.println(F("\">.<input type=\"text\" size=\"3\" ")); client.println(F("maxlength=\"3\" name=\"DT18\" value=\"")); client.print(gateway[3],DEC); client.println(F("\"></td></tr><tr><td><br></td></tr><tr><td>")); client.println(F("<input id=\"button1\"type=\"submit\" value=\"SUBMIT\" ")); client.println(F("Onclick =\"document.getElementById('T2').value ")); client.println(F("= hex2num(document.getElementById('T1').value);")); client.println(F("document.getElementById('T4').value ")); client.println(F("= hex2num(document.getElementById('T3').value);")); client.println(F("document.getElementById('T6').value ")); client.println(F("= hex2num(document.getElementById('T5').value);")); client.println(F("document.getElementById('T8').value ")); client.println(F("= hex2num(document.getElementById('T7').value);")); client.println(F("document.getElementById('T10').value ")); client.println(F("= hex2num(document.getElementById('T9').value);")); client.println(F("document.getElementById('T12').value ")); client.println(F("= hex2num(document.getElementById('T11').value);\"")); client.println(F("></td><td></td></tr></form></table>")); client.println(F("</BLOCKQUOTE></BLOCKQUOTE></BODY></html>")); HTTP_req = ""; } //-------------------------- void PrintResponse200( EthernetClient client) { client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(F("Connnection: close")); client.println(); } //-------------------------- void PrintResponse404( EthernetClient client ) { client.println(F("HTTP/1.1 404 Not Found")); client.println(F("Content-Type: text/html")); client.println(F("Connnection: close")); client.println(); } //-------------------------- void XMLhttpObjectAccess(EthernetClient client,String parm) { int check = parm.indexOf('='); if(check != -1){ //Set Digital Port int check2 = parm.indexOf('btn'); if(check2 != -1){ int port = (parm.substring(check+1)).toInt(); dout[port] = !dout[port]; switch(port){ case 0: //digitalWrite(LED, dout[port]); break; case 1: digitalWrite(LED1, dout[port]); break; case 2: digitalWrite(LED2, dout[port]); break; default: break; } } //風速・風向・雨量 int ws,wd; //BME280計測 double rf; float temp(NAN), hum(NAN), pres(NAN); BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); BME280::PresUnit presUnit(BME280::PresUnit_Pa); bme.read(pres, temp, hum, tempUnit, presUnit); if(!ErrorTMP){ Serial.print(F("Temp: ")); Serial.print(temp); Serial.print(F(" ℃\t")); sprintf(printBuf,"T%3.1f ",temp); lcd.setCursor(0,0);lcd.println(printBuf); client.print (F("\n\t\t<input id='tf2' type='text' size='6' value='"));client.print(temp);client.print(F("'>[deg]<BR>\n")); } if(!ErrorHUM){ Serial.print(F("Humidity: ")); Serial.print(hum); Serial.println(F(" %")); sprintf(printBuf,"H%3.1f ",hum); lcd.setCursor(5,0);lcd.println(printBuf); client.print (F("\n\t\t<input id='tf3' type='text' size='6' value='"));client.print(hum);client.print(F("'>[%RH]\t\t<BR>\n")); } // rf = gURYO; Serial.print(F("rainfall: ")); Serial.print(rf); Serial.print(F(" mmph\t")); sprintf(printBuf,"R%4.1f",rf); lcd.setCursor(10,0);lcd.println(printBuf); // Serial.print(F("wind speed: ")); Serial.print(gViewValue); Serial.print(F(" mps\t")); sprintf(printBuf,"V%3.1f ",gViewValue); lcd.setCursor(0,1);lcd.println(gViewValue); client.print (F("\n\t\t<input id='tf5' type='text' size='6' value='"));client.print(gViewValue);client.print(F("'>[mps]\t\t<BR>\n")); wd = analogRead(HOUI)>>8; switch(wd){ case 0: printBuf3 = "N ";printBuf2 = "北"; break; case 1: printBuf3 = "NNE";printBuf2 = "北北東"; break; case 2: printBuf3 = "NE ";printBuf2 = "北東"; break; case 3: printBuf3 = "ENE";printBuf2 = "東北東"; break; case 4: printBuf3 = "E ";printBuf2 = "東"; break; case 5: printBuf3 = "ESE";printBuf2 = "東南東"; break; case 6: printBuf3 = "SE ";printBuf2 = "南東"; break; case 7: printBuf3 = "SSE";printBuf2 = "南南東"; break; case 8: printBuf3 = "S ";printBuf2 = "南"; break; case 9: printBuf3 = "SSW";printBuf2 = "南南西"; break; case 10: printBuf3 = "SW ";printBuf2 = "南西"; break; case 11: printBuf3 = "WSW";printBuf2 = "西南西"; break; case 12: printBuf3 = "W ";printBuf2 = "西"; break; case 13: printBuf3 = "WNW";printBuf2 = "西北西"; break; case 14: printBuf3 = "NW";printBuf2 = "西北"; break; case 15: printBuf3 = "NNW";printBuf2 = "北北西"; break; default: break; } Serial.print(F("wind direction: "));Serial.print(printBuf3); lcd.setCursor(6,1);lcd.println(printBuf3); client.print (F("\n\t\t<input id='tf6' type='text' size='6' value='"));client.print(printBuf2);client.print(F("'><BR>\n")); // if(!ErrorPRS){ Serial.print(F("Pres: ")); Serial.print(pres); Serial.print(F(" Pa\t")); sprintf(printBuf,"P%6.0fPa ",pres); lcd.setCursor(9,1);lcd.println(printBuf); client.print (F("\n\t\t<input id='tf4' type='text' size='6' value='"));client.print(int(pres));client.print(F("'>[Pa]\t\t<BR>\n")); } // client.print (F("\n\t\t<input id='tf7' type='text' size='6' value='"));client.print(rf);client.print(F("'>[mmph]\t\t<BR>\n")); } HTTP_req = ""; } //-------------------------- void printError(byte error){ // If there's an I2C error, this function will // print out an explanation. Serial.print(F("I2C error: ")); Serial.print(error,DEC); Serial.print(F(", ")); switch(error){ case 0: Serial.println(F("success")); break; case 1: Serial.println(F("data too long for transmit buffer")); break; case 2: Serial.println(F("received NACK on address (disconnected?)")); break; case 3: Serial.println(F("received NACK on data")); break; case 4: Serial.println(F("other error")); break; default: Serial.println(F("unknown error")); } } //-------------------------- int LoopCount = 0; void setup() { Serial.begin(115200); // for diagnostics delay(1000); //待ち時間を入れないとStart文字列が表示されない。 Serial.print(F("Start ")); Serial.println(titleStr); SPI.begin(); //Initialize the SPI_1 port. SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order SPI.setClockDivider(SPI_CLOCK_DIV4); //SPI_CLOCK_DIV16 (72 / 16 = 4.5 MHz SPI_1 speed) //SPI_CLOCK_DIV4 (72 / 4 = 18 MHz SPI_1 speed) Serial.print(F("SPI_Start\n")); pinMode(SPI1_NSS_PIN, OUTPUT); //Ethernet3で使用可能なAPI Ethernet.setCsPin(SPI1_NSS_PIN); Ethernet.setRstPin(W550io_Rst); //リセット処理 pinMode(W550io_Rst, OUTPUT); digitalWrite(W550io_Rst, LOW); delay(10); digitalWrite(W550io_Rst, HIGH); Serial.print(F("NIC_Reset\n")); LANSetup(); Serial.print(F("LAN_setuped\n")); server.begin(); Serial.print(F("WebServer_Start\n")); //I2CのSlaveデバイスが存在するかチェックする。 Wire.begin(); Serial.print(F("I2C_Start\n")); while(!bme.begin()) { Serial.println(F("Could not find BME280 sensor!")); delay(1000); } // bme.chipID(); // Deprecated. See chipModel(). switch(bme.chipModel()){ case BME280::ChipModel_BME280: Serial.println(F("Found BME280 sensor! Success.")); break; case BME280::ChipModel_BMP280: Serial.println(F("Found BMP280 sensor! No Humidity available.")); ErrorHUM = true; break; default: Serial.println(F("Found UNKNOWN sensor! Error!")); ErrorTMP = true; ErrorHUM = true; ErrorPRS = true; } delay(100); pinMode(LED1, OUTPUT); digitalWrite(LED1,dout[1]); pinMode(LED2, OUTPUT); digitalWrite(LED2,dout[2]); pinMode(FUSOKU, INPUT_PULLUP); pinMode(URYO, INPUT_PULLUP); gHOUI = (analogRead(HOUI) - offset) >> 8; //タイマ割込の設定 Timer1.pause(); //念のためタイマ停止 Timer1.setPrescaleFactor(7200); //システムクロック 72MHzを分周して400uSECにセット Timer1.setOverflow(10000); //オーバーフローを1SECに設定 U16 Timer1.attachInterrupt(TIMER_UPDATE_INTERRUPT,ViewValue); attachInterrupt(FUSOKU,FUSOKUCountUp,RISING); //RISING,FALLING,CHANGE attachInterrupt(URYO,RainFallCountUp,FALLING); Timer1.setCount(0); //カウンタを0に設定 Timer1.refresh(); Timer1.resume(); gPretime = millis(); //初期値設定 lcd.begin(cols, rows); //begin(cols,rows,charsize); lcd.setContrast(Contrast); Serial.print(F("server is at "));Serial.println(Ethernet.localIP()); } //-------------------------- void loop() { if(!(LoopCount++ % 1000)){ } client = server.available(); if( !client ){ delay(1); return; } // HTTPリクエスト空行(\r\n\r\n)で終わる。ので、空行を探す。 boolean currentLineIsBlank = true; while( client.connected() ) { if( !client.available() ){ Serial.print(F(".")); continue; } char c = client.read(); HTTP_req += c; //Serial.print(c); if( c == '\n' && currentLineIsBlank ){ // 空行発見。HTTPリクエスト終了。レスポンスを返す。 //Serial.print("RecieveLength=");Serial.println(HTTP_req.length()); //PrintResponse200(client); if (HTTP_req.indexOf("/?")>0) { //setup?と/?を区別する必要がある //Serial.print(F("CASE1:"));Serial.print(LoopCount); if(LoopCount++ % 2){ digitalWrite(PC13,HIGH); //Serial.println(F(" H")); }else{ digitalWrite(PC13,LOW); //Serial.println(F(" L")); } delay(100); XMLhttpObjectAccess(client,HTTP_req); break; }else if(HTTP_req.indexOf("setup")>0){ //setup頁の場合 SBMが含まれていればEEPROMに書込、そうで無ければ表示のみ //setup?SBM=1&DT1=0&DT2=8&DT3=DC&DT4=54&DT5=4D&DT6=D0&DT1=0&DT2=8&DT3=220&DT4=84&DT5=77&DT6=208&DT7=192&DT8=168&DT9=0&DT10=200&DT11=255&DT12=255&DT13=255&DT14=0&DT15=192&DT16=168&DT17=0&DT18=1 //TextFinderを使うとHTMLの切り出しは比較的容易これをSTRING型のままどう扱うか? if (HTTP_req.indexOf("SBM")>0){ //Serial.println(F("Found_SBM")); int Code; //byte SET = finder.getValue();Serial.print(F("SET="));Serial.println(SET); int len = HTTP_req.length(); char* HTTP_c = (char*)malloc(len+1); HTTP_req.toCharArray(HTTP_c, len); char bufff[10]; //DT1 mac[0] HEX int indexS = HTTP_req.indexOf("DT1="); int indexE = HTTP_req.indexOf("&",indexS); int k = 0; char c; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); mac[0]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[0]); break; }else{ bufff[k++] = c; } } break; } } //DT2 mac[1] HEX indexS = HTTP_req.indexOf("DT2="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); mac[1]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[1]); break; }else{ bufff[k++] = c; } } break; } } //DT3 mac[2] HEX indexS = HTTP_req.indexOf("DT3="); //Serial.print("Pos=");Serial.println(indexS); indexE = HTTP_req.indexOf("&",indexS); //Serial.print("Pos=");Serial.println(indexE); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j);//Serial.println(c); if (c == '='){ int m = indexE - indexS; //Serial.print("m=");Serial.println(m); for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); mac[2]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[2]); break; }else{ bufff[k++] = c; } } break; } } //DT4 mac[3] HEX indexS = HTTP_req.indexOf("DT4="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); mac[3]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[3]); break; }else{ bufff[k++] = c; } } break; } } //DT5 mac[4] HEX indexS = HTTP_req.indexOf("DT5="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); mac[4]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[4]); break; }else{ bufff[k++] = c; } } break; } } //DT6 mac[5] HEX indexS = HTTP_req.indexOf("DT6="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); mac[5]=int(strtol(bufff, NULL, 16));//Serial.print(bufff);Serial.println(mac[5]); break; }else{ bufff[k++] = c; } } break; } } //DT7 ip[0] DEC indexS = HTTP_req.indexOf("DT7="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); ip[0]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(ip[0]); break; }else{ bufff[k++] = c; } } break; } } //DT8 ip[1] DEC indexS = HTTP_req.indexOf("DT8="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); ip[1]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(ip[1]); break; }else{ bufff[k++] = c; } } break; } } //DT9 ip[2] DEC indexS = HTTP_req.indexOf("DT9="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); ip[2]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(ip[2]); break; }else{ bufff[k++] = c; } } break; } } //DT10 ip[3] DEC indexS = HTTP_req.indexOf("DT10="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); ip[3]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(ip[3]); break; }else{ bufff[k++] = c; } } break; } } //DT11 subnet[0] DEC indexS = HTTP_req.indexOf("DT11="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); subnet[0]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(subnet[0]); break; }else{ bufff[k++] = c; } } break; } } //DT12 subnet[1] DEC indexS = HTTP_req.indexOf("DT12="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); subnet[1]=int(strtol(bufff, NULL, 10)); //Serial.print(bufff);Serial.println(subnet[1]); break; }else{ bufff[k++] = c; } } break; } } //DT13 subnet[2] DEC indexS = HTTP_req.indexOf("DT13="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); //Serial.println(bufff); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); subnet[2]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(subnet[2]); break; }else{ bufff[k++] = c; } } break; } } //DT14 subnet[3] DEC indexS = HTTP_req.indexOf("DT14="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0'; //Serial.println(bufff); subnet[3]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(subnet[3]); break; }else{ bufff[k++] = c; } } break; } } //DT15 gateway[0] DEC indexS = HTTP_req.indexOf("DT15="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); gateway[0]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(gateway[0]); break; }else{ bufff[k++] = c; } } break; } } //DT16 gateway[1] DEC indexS = HTTP_req.indexOf("DT16="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); gateway[1]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(gateway[1]); break; }else{ bufff[k++] = c; } } break; } } //DT17 gateway[2] DEC indexS = HTTP_req.indexOf("DT17="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); gateway[2]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(gateway[2]); break; }else{ bufff[k++] = c; } } break; } } //DT18 gateway[3] DEC indexS = HTTP_req.indexOf("DT18="); indexE = HTTP_req.indexOf("&",indexS); k = 0; for(int j = indexS;j<=indexE;j++){ c = HTTP_req.charAt(j); if (c == '='){ int m = indexE - indexS; for (int l = 1; l < m;l++){ c = HTTP_req.charAt(j+l); if(c == '&'){ bufff[k]='\0';//Serial.println(bufff); gateway[3]=int(strtol(bufff, NULL, 10));//Serial.print(bufff);Serial.println(gateway[3]); break; }else{ bufff[k++] = c; } } break; } } // すべてのデータを取得したので、EEPROMに保存します。 for (int i = 0 ; i < 6; i++){ EEPROM.write(i + 1,mac[i]); } for (int i = 0 ; i < 4; i++){ EEPROM.write(i + 7, ip[i]); } for (int i = 0 ; i < 4; i++){ EEPROM.write(i + 11, subnet[i]); } for (int i = 0 ; i < 4; i++){ EEPROM.write(i + 15, gateway[i]); } // 既知のビットにIDを設定すると、ArduinoをリセットするとEEPROMの値が使用されます EEPROM.write(0, EID); //データがEEPROMに書き込まれている場合は、arduinoをリセットする必要があります。 //読込直す int idcheck = EEPROM.read(0); if (idcheck == EID){ //idがIDと同じ値の場合、 //これは、このスケッチがシールドを設定するために使用されたことを意味します。 //EERPOMの値を読み取ってシールドを設定します。 for (int i = 0; i < 6; i++){ mac[i] = EEPROM.read(i+1); } for (int i = 0; i < 4; i++){ ip[i] = EEPROM.read(i+7); } for (int i = 0; i < 4; i++){ subnet[i] = EEPROM.read(i+11); } for (int i = 0; i < 4; i++){ gateway[i] = EEPROM.read(i+15); } } //ハードウェアリセットボタンを使用する必要があります HTTP_req = ""; }else{ Serial.println(F("SBMnotFound")); } //データがEEPROMに書き込まれている場合は、arduinoをリセットする必要があります。 //ハードウェアリセットボタンを使用する必要があります PrintSetUpPage(client,HTTP_req); break; }else{ Serial.println(F("CASE4")); PrintNormalPage(client,HTTP_req); break; } break; // ループを抜ける } if(c == '\n'){ // 新しい行の始まり。 currentLineIsBlank = true; } else if(c != '\r' ){ // この行は空行ではなかった。 currentLineIsBlank = false; } } // Webブラウザに対して、データを取得するための時間を与える。 delay(1); // コネクションを閉じる。 client.stop(); } //--------------------------EOF
オブジェクト自体はベクター殿のストレージをお借りしています。
https://www.vector.co.jp/vpack/browse/person/an051501.html 免責事項
本ソフトウエアは、あなたに対して何も保証しません。本ソフトウエアの関係者(他の利用者も含む)は、あなたに対して一切責任を負いません。
あなたが、本ソフトウエアを利用(コンパイル後の再利用など全てを含む)する場合は、自己責任で行う必要があります。本ソフトウエアの著作権はToolsBoxに帰属します。
本ソフトウエアをご利用の結果生じた損害について、ToolsBoxは一切責任を負いません。
ToolsBoxはコンテンツとして提供する全ての文章、画像等について、内容の合法性・正確性・安全性等、において最善の注意をし、作成していますが、保証するものではありません。
ToolsBoxはリンクをしている外部サイトについては、何ら保証しません。
ToolsBoxは事前の予告無く、本ソフトウエアの開発・提供を中止する可能性があります。
商標・登録商標
Microsoft、Windows、WindowsNTは米国Microsoft Corporationの米国およびその他の国における登録商標です。
Windows Vista、Windows XPは、米国Microsoft Corporation.の商品名称です。
LabVIEW、National Instruments、NI、ni.comはNational Instrumentsの登録商標です。
I2Cは、NXP Semiconductors社の登録商標です。
その他の企業名ならびに製品名は、それぞれの会社の商標もしくは登録商標です。
すべての商標および登録商標は、それぞれの所有者に帰属します。