終了 前の部分 。
目次:
- パート1.要件。 鉄の選択。 一般的なスキーム
- パート2.ソフトウェア。 中央ユニット、鉄
- パート3.セントラルユニット、ソフトウェア
- パート4.ウィンドウセンサー
- パート5. MySQL、PHP、WWW、Android
船外センサー。 ソフトウェア
海外センサー用のソフトウェアについて話してください。 その後、あなたはすでに実験できる完全なシステムを手に入れるでしょう。
サーバーは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の実際の消費量の測定値です。
- 通常25mA
- DHTで作業するときも同じ
- 無線伝送38 mA
- LowPower.idle 15 mAで
- LowPower.powerdown 7.5 mAで
クライアントは、温度、湿度、および供給電圧の測定値を取得し、これらすべてをデータ構造にパックし、サーバーにデータを送信して「スリープ状態になります」。 転送中にエラーが発生した場合、転送はすぐに繰り返されます。
サーバー(中央、ホームユニット)は、データを受信し、受信を確認して処理します。
データベース、MySQL、PHP、WWWサーバー
作業が完了すると、気象ステーションの完全に機能する設計ができました。 しかし、今では数十のそのような気象観測所があり、地元の工芸品はもはや流行ではありません。 結局のところ、モノのインターネットがあります。
したがって、これらのインターネットへのアクセスがどのように実行されるかについて話し、データベースとWebフェイスをウェザーステーションに添付します。
「ウェブカメラ」の問題ステートメント:
- 気象ステーションデータの受信と保存:温度、湿度、気圧、供給電圧
- このデータを表示する
- チャートを作成します。
この場合、mysqliモジュールでApache、PHP、MySQLをサポートするホスティングが必要です。 そして、これらの条件は、地球上のほとんどすべてのホストによって満たされます。 または、ホストする代わりに、ホームネットワークルーターに接続され、インターネットにアクセスできるサーバーの役割を果たすコンピューターがあります。
データベース作成
データベースの設計と作成から始めましょう。
データベースはあなたの世界であり、長期間学習することができるので、直接必要なものだけを簡単に説明します。
すべてのSQLスクリプトは、 weather-station/server/php-sql/
ディレクトリにあります
データベース設計はどこから始まりますか? 論理的および物理的表現。
論理ビューまたはデータベーススキーマ:
- DHT温湿度表
- 圧力および温度センサーデータテーブルBMP
- これらのテーブルには相互のリンクがないため、リンクは不要です。
物理スキームは、特定の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のセンサーは「温度、アパート内の湿度」などです。 しかし、このプロジェクトでは複雑化せず、次のことを覚えておいてください。
-
idSensor
持つセンサー、CLIENT_ADDRESS
、11に等しい-これはサーバー上のホームセンサー-中央ユニット、 -
idSensor
備えたセンサーは、CLIENT_ADDRESS
、20に等しい-これは、最初の(プロジェクトで唯一の)ウィンドウベースのセンサークライアントです。
次。 テーブルには次のデータが保存されます。
- ipRemote-データの送信元の気象観測所(サーバー)のIPアドレス。デバッグと監視に役立ちます。
- dateCreate-レコードが作成された日付、
- millis-デバッグに役立ちます。これは、Arduinoでスケッチを開始してからのミリ秒単位の時間です。
- 温度-温度
- 湿度-湿度
- 電圧-供給電圧、
- 圧力-圧力
- errors-エラーの数(使用されません)。 システム全体の状態をリモートで評価できるように、伝送エラーの数などを保存することを目的としていました。
ご覧の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
は、次のことを覚えておく必要のある簡単なラベルを表示します。
- ID 11のセンサーはサーバー上のホームセンサーです。
- ID 20のセンサーはウィンドウセンサーです。
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アプリケーションです。これについては、これから作成します。
建築
気象観測所ソフトウェアプラットフォーム全体のアーキテクチャは単純です。
- 気象ステーションのサーバー部分(中央ユニット)は、リモートセンサークライアントからデータを収集します
- 次に、データをアプリケーションのWebサーバーに転送し、このデータをデータベースに保存します
- Androidアプリケーション(または他のリモートアプリケーション:iOS、ブラウザー)は、Webサーバーにデータを要求し、画面に表示します。
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アプリケーションは可能な限りシンプルで、テクノロジーの本質だけです。 さらにこの「スケルトン」の周りに、さまざまな「美」を巻き上げることがすでに可能になります。
結果のスクリーンショットを次に示します
ご覧のとおり、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アプリケーションを最初に起動したときにデフォルトで使用されます。
エピローグ
まあ、何かがすでに機能しています。 さらに、何かを最適化、置き換え、すべてを捨てることができますが、何かを借りることもできます。
別の大きな問題はエネルギー消費です。 実用的なヒントが多い投稿のコメントを読むことをお勧めします。
無限に...そしてその先へ。