Webサーバー-初めてのArduinoネットワークソフトウェア

はじめに


私の出版物[1,2,3]では、センサーチェーンの詳細が説明されています-Python Arduinoインターフェイス。 工業生産の実際の条件では、センサーは、互いからだけでなく、測定情報の集中処理が実行される場所からもかなりの距離に配置されます。 十分に開発されたネットワーク技術を使用して、コンピューターLANを介してセンサーから情報を送信することは論理的です。 この出版物は、自宅でArduinoを使用してネットワークアプリケーションを構築および構成するための演習のスタイルで書かれています。

問題の声明


  1. Arduino Ethernet Shield拡張機能を備えたArduino Ethernetライブラリを使用して、Webサーバーを作成します。
  2. 自宅のコンピューターネットワークを使用してArduinoへのリモートアクセスを作成します。
  3. 標準のArduinoの例を使用して、Webサーバーを使用して湿度およびモーションセンサーを提供します。
  4. Pythonを使用してWebアプリケーションを開発します。

タスクを解決する段階


  1. Arduinoとイーサネットシールドを使用するためのハードウェアを設計および構築します。
  2. サーバーを作成するための開始点として、Arduino開発環境からデフォルトの例を実行します。
  3. ハードウェアをホストし、コードを再展開するように例を変更しました。
  4. Pythonを使用したWebアプリケーション開発。

Arduino Uno上のイーサネットシールド接続


Arduino Ethernet Shieldは、Arduino Unoと連携するように設計された、公式にサポートされているオープンソースネットワーク拡張機能です。 イーサネットシールドには、イーサネットネットワークに接続するためのRJ45コネクタが装備されています。 イーサネットシールドはArduino Unoにインストールするように設計されており、ボード上部のArduino Unoのピンを拡張します。 イーサネットシールドには、ネットワーク経由で重要なファイルを保存するためのmicroSDカードスロットもあります。 ほとんどの拡張機能と同様に、イーサネットシールドは、接続されているArduinoボードによって駆動されます。



各イーサネットシールドには、固有のハードウェア(MAC)アドレスが装備されています。 ボードの裏で見ることができます。 このハードウェアアドレスは、今後の演習で必要になることが多いため、書き留めておくことができます。 また、以下の演習用のArduino Ethernet Shieldのインストールに精通していることを確認してください。

以下は、この演習に必要なフリッツティングスキームの図です。 最初に行う必要があるのは、Arduino Unoの上にイーサネットシールドを接続することです。

Arduino uno





USBを使用しないリモート接続用にArduinoハードウェアを展開する場合、ボードに電力を供給するためのUSB接続がないため、ボードに外部電源を供給する必要があります。

USBケーブルを使用してArduino Unoをコンピューターに接続します。 また、イーサネットケーブルを使用して、Arduinoをローカルホームネットワークに接続する必要があります。 これを行うには、ストレートCAT5またはCAT6ケーブルを使用し、ケーブルの一方の端をホームルーターに接続します。

このルーターは、使用しているコンピューターへのネットワークアクセスを提供するデバイスと同じである必要があります。 イーサネットケーブルのもう一方の端をArduinoイーサネットシールドのイーサネットポートに接続します。 物理層の接続が正しく確立されると、ポートに緑色のライトが表示されます。



ここで、最初のイーサネットの例のコーディングを開始しますこのコードでは、構成に合わせてMACアドレスとIPアドレスを変更する必要があります。 ボードの背面からイーサネットシールドMACアドレスを取得できますが、ホームネットワークの構成に従ってIPアドレスを選択する必要があります。

作業しているコンピューターのIPアドレスを既に受け取っている場合は、範囲内の別のアドレスを選択します。 他のネットワークノードがこのIPアドレスを使用していないことを確認してください。 これらのMACアドレスとIPアドレスを使用して、コード内の次の値を更新します。

byte mac [] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02}; IPAddress ip (192, 168, 0, 102); //        File --> Examples --> Ethernet --> DhcpAddressPrinter 

IPネットワークでは、ネットワークのIPアドレスの可視範囲は、サブネットワークまたはサブネットと呼ばれる別のアドレスの関数です。 LAN IPネットワークのサブネットは、コンピューターのIPアドレスの範囲でイーサネットシールドに適切なIPアドレスを選択するのに役立ちます。 [4]でサブネットの基本について学ぶことができます。

コードを掘り下げる前に、これらの変更を使用してコードをコンパイルし、Arduinoにアップロードします。 ダウンロードプロセスが正常に完了したら、Webブラウザーを開き、Arduinoスケッチで指定されたIPアドレスを入力します。 すべてうまくいけば、アナログ接点の値を示すテキストが表示されます。

ここで何が起こったのかをよりよく理解するために、コードに戻りましょう。 ご覧のとおり、コードの冒頭で、イーサネットライブラリのEthernetServerメソッドを使用して、ポート80でイーサネットサーバーライブラリを初期化します。

 EthernetServer server(80); 

セットアップ()に、プログラムは、前に定義したmacおよびip変数を使用してEthernet.being()メソッドを使用して、イーサネットシールドを介したイーサネット接続を初期化します。 server.begin()メソッド 、ここからサーバー起動します。 サーバーコードにイーサネットライブラリを使用する場合、サーバーを起動するにはこれらの手順の両方が必要です。

 Ethernet.begin (mac, ip); server.begin (); 

loop()関数では、 EthernetClientメソッドを使用して、 クライアントオブジェクトを初期化し、着信クライアント要求をリッスンします。 このオブジェクトは、ポート80を介してイーサネットサーバーにアクセスしようとしている接続済みクライアントからの要求に応答します。

 EthernetClient client = server.available (); 

リクエストを受け取った後、プログラムはリクエストがロードを完了するのを待ちます。 次に、メソッドを使用して、フォーマットされたHTMLデータでクライアントに応答します。

 client.print (): while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); # Response code } 

ブラウザーからArduinoサーバーにアクセスしようとすると、Webサーバーがアナログ連絡先のデータを使用してクライアントに応答していることがわかります。 ここで、ハードウェア設計で接続した湿度およびPIRセンサーの正しい値を取得するには、次のコード変更を実行する必要があります。

ここでは、すべてのアナログ出力からの生の読み取り値の代わりに、計算された相対湿度値で顧客に応答することに気づくでしょう。 また、正しいセンサー名に一致するようにWebブラウザーで印刷されるテキストを変更しました。

 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"); client.println("Refresh: 5"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); float sensorReading = getHumidity(analogChannel, temperature); client.print("Relative Humidity from HIH4030 is "); client.print(sensorReading); client.println(" % <br />"); client.println("</html>"); break; } 

このプロセスでは、Arduino関数getHumidity()も追加しました。この関数は、アナログピンから観測された値から相対湿度を計算します。

 float getHumidity(int analogChannel, float temperature){ float supplyVolt = 5.0; int HIH4030_Value = analogRead(analogChannel); float analogReading = HIH4030_Value/1023.0 * supplyVolt; float sensorReading = 161.0 * analogReading / supplyVolt - 25.8; float humidityReading = sensorReading / (1.0546 - 0.0026 * temperature); return humidityReading; } 

これらの変更は、たとえば、テスト段階でWebServer Arduinoに適用したり、コードディレクトリの演習1-WebサーバーフォルダからスケッチWebServer_Custom.inoを開いたりするだけです。 開いているスケッチファイルを見るとわかるように、変更を反映するためにコードを既に変更していますが、MACアドレスとIPアドレスを対応するアドレスに変更する必要があります。

これらの小さな変更が完了したら、スケッチをコンパイルしてArduinoにアップロードします。 すべてが計画どおりに進んでいる場合、Webブラウザを使用してWebサーバーにアクセスできる必要があります。 最近準備したArduinoのIPアドレスをWebブラウザーで開きます。

次のスクリーンショットに示されているのと同じ答えが得られるはずです。 このスケッチでは湿度値のみを表示していますが、追加のclient.print()メソッドを使用してモーションセンサー値を簡単に添付できます。



この演習で実装したメカニズムと同様に、WebサーバーはWebブラウザーからの要求に応答し、探しているWebページを提供します。 この方法はWebページを配信するために非常に一般的で汎用性がありますが、ペイロードにはセンサー情報の実際のサイズと比較して多くの追加のメタデータ(データに関するデータ)が含まれています。

さらに、Ethernetサーバーライブラリを使用してサーバーを実装すると、Arduinoリソースが大量に消費されます。 リソースが限られたデバイスであるArduinoは、サーバーアプリケーションの起動には適していません。Arduinoリソースは、通信ではなくセンサーの処理の優先順位である必要があるためです。

イーサネットライブラリを使用して作成されたWebサーバーは、非常に限られた数の接続をサポートするため、大規模なアプリケーションやマルチユーザーシステムには適していません。

この問題を解決する最善の方法は、クライアントデバイスとしてArduinoを使用するか、リソースが限られているハードウェアデバイスで動作するように設計された軽量の通信プロトコルを使用することです。 次のいくつかのセクションでは、イーサネット経由でArduinoを通信するためのこれらのアプローチを学び、実装します。

Pythonを使用したWebアプリケーション開発


前のプログラムを実装することにより、Arduinoでネットワーキングを有効にしました。 前の例では、イーサネットライブラリから利用可能なメソッドを使用してHTTP Webサーバーを作成しました。 Arduino Webサーバーを作成したら、ネットワーク上でArduinoリソースを利用できるようにしました。 同様に、Pythonは、Webサーバーインターフェイスを作成するためのさまざまなライブラリを通じて拡張性も提供します。

コンピューターまたはRaspberry Piなどの他のデバイスでPythonベースのWebサーバーを実行することで、Arduinoを使用してWebサーバーをホストすることを回避できます。 Pythonなどの高水準言語を使用して構築されたWebアプリケーションも、Arduinoと比較して追加の機能と拡張性を提供できます。

Pythonライブラリweb.pyを使用して、Python Webサーバーを作成します。 また、このライブラリを使用して、ArduinoクライアントとWebブラウザー間でデータを転送するインタラクティブなWebアプリケーションを作成します。

web.pyの基本を学んだ後、シリアルポートを使用してweb.pyでArduinoとやり取りし、Python WebサーバーでArduinoを使用できるようにします。 次に、Arduinoの通信方法をシリアルインターフェイスからHTTPベースのメッセージングにアップグレードします。

Python Webフレームワーク-web.py


Webサーバーは、 Django、bottle、Pylonweb.pyなどのさまざまなWebフレームワークを使用してPythonで開発できます。 シンプルでありながら強力な機能を備えているため、 web.pyを優先Web構造として選択しました。

web.pyライブラリはもともと、Pythonを使用してWebアプリケーションを構築するための簡単なアプローチを開発することを目的として、故アーロン・スワルツによって開発されました。 このライブラリは、 HTTP Representation State Transfer(REST)アーキテクチャをサポートするために、 GETPOSTの 2つの主要なメソッドを提供します。

このアーキテクチャは、クライアントとサーバー間でデータを送受信することにより、HTTPプロトコルをサポートするように設計されています。 現在、RESTアーキテクチャは、HTTPを介してデータを送信するための膨大な数のWebサイトによって実装されています。

web.pyをインストールする


web.pyを使い始めるには、Setuptoolsを使用してweb.pyライブラリをインストールする必要があります。 LinuxおよびMac OS Xでは、ターミナルで次のコマンドのいずれかを実行してweb.pyをインストールします。

 $ sudo easy_install web.py $ sudo pip install web.py 

Windowsでは、コマンドプロンプトを開き、次のコマンドを実行します。

 > easy_install.exe web.py 

pythn 3.61の場合、コマンドラインに次のように入力します。

 > easy_install-3.61.exe web.py 

Setuptoolsが正しく構成されていれば、ライブラリを問題なくインストールできます。 ライブラリのインストールを確認するには、Pythonオンラインヘルプを開き、次のコマンドを実行して、エラーなしでライブラリをインポートしたことを確認します。

 >>> import web 

最初のPython Webアプリケーション


web.pyを使用してWebサーバーを実装することは、非常に単純で簡単なプロセスです。 web.pyライブラリでは、Webサーバーを正常に起動するために必要なGETメソッドの宣言が必要です。

クライアントがWebブラウザーまたは別のクライアントを使用してサーバーにアクセスしようとすると、 web.pyGETリクエストを受信し、このメソッドで指定されたデータを返します。 web.pyライブラリを使用して簡単なWebアプリケーションを作成するには、次のコード行を使用してPythonファイルを作成し、Pythonを使用してファイルを実行します。

 import web urls = ( '/', 'index') class index: def GET(self): return "Hello, world!" if __name__ == "__main__": app = web.application(urls, globals()) app.run() 

実行すると、サーバーが実行中であり、アドレス0.0.0.0:8080からアクセスできることがわかります。 サーバープログラムはIPアドレス0.0.0.0で実行されているため、同じコンピューター、ローカルホスト、または同じネットワークから他のコンピューターを使用してアクセスできます。

サーバーを確認するには、Webブラウザーを開いて0.0.0.0:8080に進みます。 同じコンピューターからサーバーにアクセスしようとすると、 127.0.0.1 :8080またはlocalhost :8080も使用できます。 127.0.0.1 IPアドレスは、実際にはローカルホスト、つまりプログラムが実行されている同じコンピューターのネットワークアドレスを意味します。 次のスクリーンショットに示すように、ブラウザーにサーバーの応答が表示されます。



この単純なコードの仕組みを理解するには、前のコードスニペットのGETメソッドを確認してください。 ご覧のとおり、WebブラウザーがURLを要求すると、 GETメソッドはHello、world!を返します ブラウザに。

それまでの間、コードでさらに2つの必要なweb.pyコンポーネントを確認することもできます: urlsおよびweb.application()メソッド。 web.pyライブラリでは、urls変数宣言で応答場所の初期化が必要です。

すべてのweb.pyベースのWebアプリケーションに対して、 application(urls、global())メソッドが呼び出され、Webサーバーが初期化されます。 デフォルトでは、 web.pyアプリケーションはポート8080で実行されますが、実行時に指定することで別のポート番号に変更できます。 たとえば、ポート8888web.pyアプリケーションを実行する場合は、次のコマンドを実行します。
 $ python webPyBasicExample.py 8888 

これはプレーンテキストのみを返しますが、Pythonを使用して最初のWebアプリケーションを正常に作成しました。 ここから移動し、 web.pyライブラリを使用して、次の章でより複雑なWebアプリケーションを作成します。

これらの複雑なアプリケーションを開発するには、 GETメソッド以上のものが必要です。 web.pyライブラリの理解をさらに深めるために、予備的な概念の調査を始めましょう。

複雑なWebアプリケーションを開発するためのWeb.pyのコアコンセプト


web.pyライブラリは、Pythonを使用して動的なWebサイトおよびWebアプリケーションを開発するための便利でシンプルな方法を提供するように設計されました。 web.pyを使用すると、追加のPythonコンセプトをいくつか使用するだけで、複雑なWebサイトを非常に簡単に作成できます。

この限られたトレーニングコースと使いやすい方法により、 web.pyはプログラミング言語からWebアプリケーションを作成する最速の方法の1つです。 これらのweb.pyの概念を詳細に理解することから始めましょう。

URL処理


最初のweb.pyプログラムで、Indexクラスのルートフォルダー(/)を指すurls変数を定義していることに気付くかもしれません。

 urls = ( '/', 'index' ) 

前の宣言では、最初の部分「/」は、実際のURL要求と一致するために使用される正規表現です。 このような式を使用して、 web.pyサーバーに到着する複雑なリクエストを処理し、それらを適切なクラスにポイントできます。

web.pyでは 、ランディングページのさまざまな場所を対応するクラスにリンクできます。 たとえば、データ/データの場所をIndexクラスに加えてデータクラスにリダイレクトする場合、次のようにurls変数を変更できます。

 urls = ( '/', 'index', '/data', 'data', ) 

この条件下で、クライアントがアドレスhttp:// <ip-address>:8080 / dataへのアクセス要求を送信すると、要求はデータクラスに送信され、次にこのクラスのGETまたはPOSTメソッドに送信されます。

GETおよびPOSTメソッド


ポート80で実行されるArduinoベースのWebサーバーを作成し、Webブラウザーを使用してWebサーバーにアクセスしました。 Webブラウザは、Webサーバーへのアクセスに使用される最も一般的なタイプのWebクライアントの1つです。 他のタイプは、URL、Wget、およびWebクローラーです。

WebブラウザーはHTTPを使用して、使用したArduino Webサーバーを含むすべてのWebサーバーと通信します。 GETとPOSTは、Webブラウザーからのサーバー要求に対処するためにHTTPプロトコルでサポートされる2つの主要な方法です。

ブラウザーまたは他のHTTPクライアントでWebサイトを開こうとするたびに、実際にはWebサーバーからGET機能を要求しています。 たとえば、WebサイトのURL [5]を開くと、このWebサイトをホストしているWebサーバーがロケーション '/'に対するGET要求を行うように要求します。

URL処理セクションでは、 web.pyクラスをURLプレースメントに関連付ける方法を学びました。 web.pyライブラリが提供するGETメソッドを使用して、GETリクエストを個々のクラスに関連付けることができます。 GETリクエストを受け取った後、クライアントへの応答として適切な値を返す必要があります。 次のコードスニペットは、誰かが「/」の場所にGETリクエストを行うと、GET()関数がどのように呼び出されるかを示しています。

 def GET(self): f = self.submit_form() f.validates() t = 75 return render.test(f,t); 

HTTP POST関数は、主にフォームまたはその他のデータをWebサーバーに送信するために使用されます。 ほとんどの場合、POSTはWebページに埋め込まれ、ユーザーがPOST機能を実行するコンポーネントを送信すると、サーバーリクエストが生成されます。 web.pyライブラリはPOST()関数も提供します。これは、WebクライアントがPOSTメソッドを使用してweb.pyサーバーに接続しようとしたときに呼び出されます。 POST()関数のほとんどの実装では、リクエストにはフォームを介して送信されたデータが含まれます。 値f ['Celsius' ...]を使用して個々のフォーム要素を抽出できます。これにより、摂氏フォーム要素に関連付けられた値が得られます。 POST()関数が提供されたアクションを完了すると、POST要求への応答として関連情報をクライアントに返すことができます。

  def POST(self): f = self.submit_form() f.validates() c = f['Celsius'].value t = c*(9.0/5.0) + 32 return render.test(f,t) 

パターン


これで、HTTPリクエストを対応するURLにリダイレクトする方法と、これらのHTTPリクエストに応答するメソッド(GETおよびPOST)を実装する方法がわかりました。 しかし、リクエストを受信した後に表示されるWebページはどうでしょうか? レンダリングプロセスを理解するために、web.pyプログラムが配置されるのと同じディレクトリにtemplatesというフォルダを作成することから始めましょう。 このフォルダーには、オンデマンドでWebページをレンダリングするために使用されるテンプレートが保存されます。 次のコード行に示すように、 template.render()関数を使用して、プログラム内でこのテンプレートフォルダーの場所を指定する必要があります。

 render = web.template.render ('templates') 

レンダリングフォルダーのインスタンスを作成したら、プログラムのテンプレートファイルを作成します。 プログラムの要件に応じて、必要な数のテンプレートファイルを作成できます。 Web.pyは、Templetorという言語を使用してこれらのテンプレートファイルを作成します。 詳細については、[5]をご覧ください。 Templetorを使用して作成された各テンプレートファイルは、拡張子が.htmlのHTML形式で保存する必要があります。

テキストエディターを使用してテンプレートフォルダーにtest.htmlファイルを作成し、次のコードをファイルに貼り付けます。

 $def with(form, i) <form method="POST"> $:form.render() </form> <p>Value is: $:i </p> 

前のコードスニペットで見ることができるように、テンプレートファイルは、式$ def with()で始まります。ここで、入力引数を角括弧内の変数として指定する必要があります。

テンプレートをレンダリングした後、これらはWebページで使用できる唯一の変数になります。 たとえば、前のコードフラグメントでは、2つの変数( formi )を入力変数として渡しました。 $:form.render()を使用してフォームオブジェクトを使用し、Webページ内に表示しました。 フォームオブジェクトを表示する必要がある場合、単に宣言するだけで別の変数を直接渡すことができます(つまり、$:i)。 Templetorは、変数を使用するときにテンプレートファイルのHTMLをそのまま表示します。

これで、web.pyプログラムで使用できるtest.htmlテンプレートファイルが準備できました。 GET()またはPOST()関数が実行されるたびに、要求元のクライアントに値を返す必要があります。 Noneなど、これらのリクエストに対して任意の変数を返すことができますが、答えがWebページの読み込みに関連するテンプレートファイルを表示する必要があります。 render()関数を使用してテンプレートファイルを返し、その後にテンプレートファイルの名前と入力引数を続けます。

 return render.test (f, i); 

前のコード行からわかるように、 render.test()関数を指定して、レンダリングされたtest.htmlページを返します。ここで、 test()は.html拡張子のないファイルの名前です。 この関数には、入力引数として渡されるフォームオブジェクトfと変数iも含まれています。

フォーム


web.pyライブラリは、Formモジュールを使用してフォーム要素を作成する簡単な方法を提供します。 このモジュールには、HTMLフォーム要素を作成し、ユーザーから入力を受け取り、これらの入力をPythonプログラムで使用する前に検証する機能が含まれています。 次のコードフラグメントでは、 フォームライブラリを使用して、 TextboxButtonの 2つのフォーム要素を作成します。

 submit_form = form.Form( form.Textbox('Celsius', description = 'Celsius'), form.Button('submit', type="submit", description='submit')) 

Textbox (ユーザーからテキスト入力を受け取る)およびButton(フォームを送信する)に加えて、Formモジュールは、非表示のテキスト入力を受け取るためのパスワード 、相互排他的なドロップダウンリストを受け取るためのDropboxRadiotoがいくつかのオプションから相互に排他的な入力を受け取るなど、いくつかの他のフォーム要素も提供します、およびチェックボックス -指定されたオプションからのバイナリ入力の選択。 これらの要素はすべて非常に簡単に実装できますが、フォーム要素はプログラム要件に従ってのみ選択する必要があります。

web.pyを使用してフォームを実装する場合、Webページはフォームが送信されるたびにPOSTメソッドを実行する必要があります。 次のテンプレートファイルのフォームの実装でわかるように、フォーム送信メソッドを明示的にPOSTとして宣言しています。

 $def with(form, i) <form method="POST"> $:form.render() </form> 

おわりに


.

参照資料


  1. Python-Arduino.
  2. , Arduino.
  3. Python , Arduino.
  4. Subnetwork.
  5. web.py templating system.

Source: https://habr.com/ru/post/J338844/


All Articles