Arduino気象ステーション(AからZ)パート5

終了 前の部分







目次:









船外センサー。 ソフトウェア



海外センサー用のソフトウェアについて話してください。 その後、あなたはすでに実験できる完全なシステムを手に入れるでしょう。







サーバーはWiFi経由でインターネットと通信できる中央のホームユニットであり、 クライアントはデータを無線でサーバーに送信する、すぐに使用できるリモートセンサーであることを思い出してください。







サーバーとクライアントの両方のソースコードはこちらです。

ソーステキストには詳細なコメントが付いています。







クライアントでほとんど何も設定する必要はありません。







nRF24L01 +無線送信機、より正確にはRadioHeadライブラリでは、サーバーとクライアントのアドレスを指定する必要があります。 複数のサーバーとクライアントがある場合に備えて、アドレスが提供されます。 アドレスは単なる整数です。 クライアントがサーバーにデータパケットを送信するとき、このパケットがどのサーバー向けであるかを示します。 サーバーは、独自のアドレスを知っているため、このパケットがそのアドレス宛かどうかを判断します。







したがって、サーバーとクライアントのSERVER_ADDRESS



は同じである必要がありますが、異なるクライアントのCLIENT_ADDRESS



は異なる必要があります。 つまり、将来別の新しいセンサーをシステムに接続する場合、 CLIENT_ADDRESS



を変更する必要があります。







 //     #define SERVER_ADDRESS 10 #define CLIENT_ADDRESS 20 //     !!!
      
      





RF_CHANNEL



無線チャネルRF_CHANNEL



は、すべての人で同じでなければなりません。 デフォルトでは、2です。デフォルトの番号を変更しましたが、他のものを選択できます。







 //  .       #define RF_CHANNEL 73
      
      





バッテリーの供給電圧を測定するための電圧計の設定を変更する必要があります。







 //   ,   const float r1 = 100400; // 100K const float r2 = 9960; // 10K //      //    http://localhost/arduino-secret-true-voltmeter/ const float typVbg = 1.082; //    1.0 -- 1.2 
      
      





エネルギーを節約するために、Arduino用の軽量の低電力ライブラリが使用されます。







以下は、このライブラリを使用したArduino Pro Miniの実際の消費量の測定値です。









クライアントは、温度、湿度、および供給電圧の測定値を取得し、これらすべてをデータ構造にパックし、サーバーにデータを送信して「スリープ状態になります」。 転送中にエラーが発生した場合、転送はすぐに繰り返されます。







サーバー(中央、ホームユニット)は、データを受信し、受信を確認して処理します。







データベース、MySQL、PHP、WWWサーバー



作業が完了すると、気象ステーションの完全に機能する設計ができました。 しかし、今では数十のそのような気象観測所があり、地元の工芸品はもはや流行ではありません。 結局のところ、モノのインターネットがあります。







したがって、これらのインターネットへのアクセスがどのように実行されるかについて話し、データベースとWebフェイスをウェザーステーションに添付します。







「ウェブカメラ」の問題ステートメント:









この場合、mysqliモジュールでApache、PHP、MySQLをサポートするホスティングが必要です。 そして、これらの条件は、地球上のほとんどすべてのホストによって満たされます。 または、ホストする代わりに、ホームネットワークルーターに接続され、インターネットにアクセスできるサーバーの役割を果たすコンピューターがあります。







データベース作成



データベースの設計と作成から始めましょう。







データベースはあなたの世界であり、長期間学習することができるので、直接必要なものだけを簡単に説明します。







すべてのSQLスクリプトは、 weather-station/server/php-sql/



ディレクトリにあります







データベース設計はどこから始まりますか? 論理的および物理的表現。







論理ビューまたはデータベーススキーマ:









物理スキームは、特定のDBMSとデータ型に依存しています。 特定の例で分解する方が簡単です。 make_tables.sql



SQLスクリプトmake_tables.sql



、論理スキーマと物理スキーマをmake_tables.sql



します。







各テーブルにはタイプフィールドが必要です







 id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT
      
      





フィールド名はデータベースごとに異なる場合がありますが、唯一の意味があります-これは一意の識別子、レコードキーです。 将来、このようなカウンタを持たないテーブルにデータベースが表示された場合、このデータベースはプログラミングからはほど遠い人、おそらく人文科学によって設計されたものであることを知っておく必要があります。







同じタイプのセンサーからのデータを1つのテーブルに保存し、別のタイプのセンサーについては別のテーブルを作成します。 これにより、データベースとそれにバインドされるPHPが若干複雑になりますが、将来のシステム全体の拡張または変更が簡単になります。







プロジェクトには2つのテーブルがあります。 arduino_dht



テーブルはDHTタイプセンサー(s)(温度、湿度)からのデータを格納し、 arduino_bmp



テーブルはBMPタイプセンサー(s)(温度、圧力)からのデータを格納します。 将来、たとえば、ガスセンサーまたはモーション検出器を使用する場合は、追加のテーブルを作成してください。 DHT11またはDHT22タイプの別のセンサーを接続する場合、追加のテーブルを作成する必要はありませんarduino_dht



テーブルを使用します。 原則が明確であることを願っています。別の物理エンティティは別のテーブルです。







同じタイプの複数のセンサーからのデータがテーブルに保存される場合、どのようにそれらを区別できますか? これを行うには、各テーブルにフィールドを入力します







 idSensor INTEGER
      
      





実際、これはリモートクライアント-クライアントの各インスタンスのclient/client.ino



と、 server/server.ino



直接接続されているセンサーの中央サーバーであるserver/server.ino



したserver/server.ino



です。







産業システムでは、別のテーブルが必要ですidSensor



とその口頭で人間が読める記述の対応。 たとえば、 idSensor



= 2のセンサーは「温度、アパート内の湿度」などです。 しかし、このプロジェクトでは複雑化せず、次のことを覚えておいてください。









次。 テーブルには次のデータが保存されます。









ご覧のarduino_dht



arduino_bmp



arduino_bmp



非常に似ており、違いは圧力と湿度のフィールドのみであり、すべてを1つのヒープ(テーブル)にダンプしたいという要望があります。 しかし、 最初の標準形式はこれを行うように指示していません。多くの初心者プログラマーがそれを回避しようとしましたが、どれも成功しませんでした。 これは、当分の間、万有引力の法則に気付かない方法です。







arduino_error_log



テーブルarduino_error_log



デバッグに役立ちます—エラーやその他のシステムメッセージのログです。







権限を持つデータベースとそのユーザーの作成については、 make_db.sql



で説明していmake_db.sql









 -- .  config.php --   CREATE DATABASE IF NOT EXISTS db_weather; --   CREATE USER 'u_weather'@'localhost' IDENTIFIED BY '***PASSWORD***'; GRANT ALL ON db_weather.* TO 'u_weather'@'localhost';
      
      





これは一度行われ、データベース名とユーザー名は独自のものになります。 そして、正確に行う必要があるのは、パスワードを設定することです。







PHPおよびWebサーバー



すべてのWebインターフェイス設定はconfig.php



保存されます。 データベース設定に従って変更します。







タイムゾーンをPHP形式で設定します







 date_default_timezone_set('Europe/Prague');
      
      





利用可能なすべてのタイムゾーンについては、ここで説明します







スケッチserver.ino



からの定数SOURCE_KEY



一致する必要があるアクセス用の秘密鍵を(数字として)設定します







 $access_key = '***KEY***';
      
      





Webサーバーには認証もパスワードのログインもありません。これは設計全体を複雑にします。 プロトタイプの場合、これは必要ありません。 したがって、すべての保護はrobots.txt



ファイル、 index.php



およびアクセス用のこの秘密キーの不在に基づいて構築されます。







メインのPHPスクリプトweather.php



は、データを含む単純なHTTP GETリクエストを受け入れ、対応するデータベーステーブルに保存します。 キー$access_key



が一致しない場合、リクエストは拒否されます。







weather-view.php



データテーブルの表示に使用され、他のWebインターフェイススクリプトへのハイパーリンクが含まれています。 そんな彼に電話して







 http:// / /weather-view.php?k= access_key
      
      





例えば







 http://yourhost/iot/weather-view.php?k=12345
      
      





weather-view.php



は、次のことを覚えておく必要のある簡単なラベルを表示します。









function.php



スクリプトには、すべてのPHPスクリプトに共通のfunction.php



が含まれています。







chart-dht.php



は、 Google Chartを使用したチャート作成を担当します 。 これは、たとえば、無線センサーの供給電圧のグラフです。 晴れた日に太陽電池により電圧が上昇し、その後、電池の電源が徐々に放電します。







グラフ







export-dht.php



は、MySQLデータベーステーブルからCSVファイルにデータをexport-dht.php



ます。 スプレッドシートでさらにインポートおよび分析するため。







export-voltage.php



は、ウィンドウセンサーの供給電圧に関するデータをMySQLデータベースからCSVファイルにエクスポートします。 デバッグに役立ちます。







truncate.php



すべてのテーブルをクリアします。 すべてのデータを削除します。 デバッグに役立ちます。 weather-view.php



からこのスクリプトへのリンクはないため、ブラウザのアドレスバーにある$access_key



直接リンクを介して呼び出す必要があります。







データを受信するとき、 mysqli_real_escape_string()



関数は、一般的に誤った値がデータベースに入るのを防ぐために使用されます。







robots.txt



をサイトのルートに配置して、検索エンジンへの侵入を防ぐことを忘れないでください。







ESP8266、WiFiおよびデータ転送



server.ino



server.ino



スケッチに戻り、WiFiアクセスポイントに接続してデータをWebサーバーに送信する部分に戻ります。







既に書いたように、ArduinoがATコマンドを使用してESP8266モジュールを制御するための通常のライブラリを見つけることができなかったため、自分で「集団農場」をしなければなりませんでした。 また、ESP8266-01のファームウェアの特定のバージョンをフラッシュする必要があることを思い出させてください。 そして、すべての準備が整ったら、どのように機能するかを見てみましょう。







server.ino



スケッチでWebサーバーにアクセスするには、これらの定数を変更server.ino



必要がありserver.ino









 const String DEST_HOST = " "; //  habr.com const String DEST_PORT = " "; //  80 const String DEST_URL = "/ /weather.php"; const String SOURCE_KEY= "  "; //    $access_key  config.php
      
      





server.ino



void setup()



関数で、ESP8266は最初にステーションモードに切り替えられます。 Wi-Fiクライアントとして機能し始めます







 espSendCmd(«AT+CWMODE_CUR=1», «OK», 3000);
      
      





そして、アクセスポイントへの接続に従います







 espState = espConnectToWiFi();
      
      





接続が発生しない場合、試行が繰り返されます(1回)







 if ( espState != ESP_SUCCESS ) { delay(5000); Serial.println("WiFi not connected! Try again ..."); espConnectToWiFi(); }
      
      





次に、TCP / IPシングル接続モードを選択します







 espSendCmd("AT+CIPMUX=0", "OK", 2000);
      
      





DHTセンサーからWebサーバーにデータを送信する場合、 type=dht



として示されるデータ型で関数が使用されます







 espSendData( "type=dht&t=" + String(dhtData.temperature) + "&h=" + String(dhtData.humidity) + "&v=" + String(dhtData.voltage) + "&s=" + String(CLIENT_ADDRESS) );
      
      





BMPセンサーからWebサーバーにデータを送信するとき、同じ関数がtype=bmp



として示されるデータ型で使用されます







 espSendData( "type=bmp&t=" + String(temperature_bmp) + "&p=" + String(pressure_bmp) + "&s=" + String(CLIENT_ADDRESS) );
      
      





espSendData()



関数は、HTTP GET要求文字列を受け入れ、意図したとおりにWebサーバーに送信します。







内部では、 espSendData()



は「AT」コマンドを送信してESPモジュールの可用性を確認し、必要に応じてWiFi接続を確認して再接続します。 その後、データが送信され、TCP接続が閉じられます。







Androidアプリ



最近では、誰もがLEDを点滅させることができれば、気象観測所を持っている人を驚かせることはありません。 しかし、クラフトがWiFi経由でサーバーと通信でき、Webフェイスとモバイルアプリケーションを持っている場合、これは何かです! ここでのサーバーとは、もちろんアプリケーションサーバー、つまり 私たちの場合、これはPHPバインディングおよびMySQL DBMSです。 ケーキには十分なチェリーがありません。つまり、Androidアプリケーションです。これについては、これから作成します。







建築



気象観測所ソフトウェアプラットフォーム全体のアーキテクチャは単純です。









Androidデバイスの画面には、現在の最新のセンサー測定値が表示されます。







HTTP GETおよびJSON



そもそも解決する必要がある質問は、データがWebサーバーからAndroidアプリケーションにどのように転送されるかです。







ここでは何も発明する必要はありません。すべてがすでに発明されています-これらはHTTP GETとJSONです。







この例では、Androidアプリケーションの準備がまだできていない間に、Webサーバーへの単純なGETリクエストを手動でコンパイルおよびデバッグできます。







JavaおよびAndroidには、JSON形式のデータを処理するための既製のライブラリがあります。 JSONは、人間が読める形式のテキスト形式であり、デバッグに役立ちます。







気象ステーションのセンサーから現在のデータを生成するために、Webサーバー上に新しいPHPスクリプトlast-data-to-json.phpを作成します。







スクリプト呼び出し:







 http://<>/last-data-to-json.php?k=<access_key>
      
      





ここで、 <access_key>



は、思い出すように、シークレットデータベースアクセスキーです。







JSON形式の応答例:







 { "DHT 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:03", "temperature":"19", "humidity":"26", "voltage":"5.01" }, "DHT 20":{ "idSensor":"20", "dateCreate":"2016-04-18 07:36:26", "temperature":"10", "humidity":"26", "voltage":"3.7" }, "BMP 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:22", "temperature":"19", "pressure":"987.97" } }
      
      





3つのセンサーがあることを思い出してください。 それらのIDとタイプ(DHTまたはBMP)は、気象観測所コード全体にハードコーディングされています。 このハードコアコーディングの方法はイデオロギー的には正しくありませんが、膝で描かれたプロトタイプ(迅速で簡単な解決策が必要な場合)の場合、これは妥当な妥協案です。







 $idSensor = 11; //  DHT  $idSensor = 11; //  BMP  $idSensor = 20; //  DHT 
      
      





last-data-to-json.php



は、これらの異種センサーの最新データをデータベースから取得し、JSON形式でパックします。 「最後から」データベースからのデータの選択は、次のように進みます。







 SELECT <> FROM <> ORDER BY id DESC LIMIT 1;
      
      





Android



次に、JSONデータを要求、受信、デコードし、画面に情報を表示するシンプルなAndroidアプリケーションを作成します。







私たちのAndroidアプリケーションは可能な限りシンプルで、テクノロジーの本質だけです。 さらにこの「スケルトン」の周りに、さまざまな「美」を巻き上げることがすでに可能になります。







結果のスクリーンショットを次に示します







Android







ご覧のとおり、UIはLinearLayoutに基づく単なるSpartanであり、それ以上のものはありません。







TextViewの上部には、センサーのIDと気象データが表示されます。 [更新]ボタンは、Webサーバーへの2番目の要求を開始します。 EditTextのNextは唯一のプログラム設定です-これはフォーム内のリクエストURLです







 http://< >/last-data-to-json.php?k=<access_key>
      
      





何に注意する必要がありますか?







マニフェストで、インターネットを許可し、ネットワーク接続のステータスを確認する行を追加します。







 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
      
      





ネットワークでの作業とWebサイトからのデータの受信は次のとおりです。







AsyncTaskを使用して、メインUIスレッドとは別のバックグラウンドタスクを作成します。 このバックグラウンドタスクはリクエストURLをHttpURLConnection



し、それを使用してHttpURLConnection



を作成します。







接続が確立された後、AsyncTaskはWebページ(JSON)のコンテンツをInputStreamとしてロードします。 次に、InputStreamは文字列に変換され、JSONObjectを使用してデコードされ、 onPostExecute()



メソッドを使用してユーザーインターフェイスに表示されます。







MainActivity.javaで、URLを次のように変更します。







 private static final String defUrl = "http://host/dir/last-data-to-json.php?k=< >";
      
      





Androidアプリケーションを最初に起動したときにデフォルトで使用されます。







エピローグ



まあ、何かがすでに機能しています。 さらに、何かを最適化、置き換え、すべてを捨てることができますが、何かを借りることもできます。







別の大きな問題はエネルギー消費です。 実用的なヒントが多い投稿のコメントを読むことをお勧めします。







無限に...そしてその先へ。








All Articles