MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Arduinoの基礎 - Ethernetのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Arduinoの基礎 - Ethernet
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == <br><br> == EthernetシールドとDHCPの利用 == ArduinoでEthernetシールド等を使用する場合、プログラムで明示的にIPアドレスを指定するのではなく、<br> DHCPで自動的にIPアドレスの割り当てを行う方法を記載する。<br> <br> Arduinoの標準のEthernetライブラリを使用することで、簡単に実現できる。<br> これは、<code>Ethernet.begin()</code>を呼び出す時、MACアドレスのみを指定することで(IPアドレスは指定しない)、DHCPからIPアドレスを自動で取得できる。<br> <br> ここでは、Arduino UnoにEthernetシールドを接続している。<br> 以下の例では、シリアルポートに結果を出力するために、<code>Serial.begin()</code>や<code>println()</code>を呼び出している。<br> <syntaxhighlight lang="c++"> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D }; void setup() { Serial.begin(9600); Ethernet.begin(mac); Serial.println(Ethernet.localIP()); } void loop() { } </syntaxhighlight> <br><br> == EthernetシールドとWebサーバの実装 == このセクションでは、Arduinoの標準のEthernetライブラリを使用して、単純なWebサーバを実装する。<br> 簡単なWebサーバの実装例はExampleに含まれている。<br> <br> 以下の例では、URIを確認して、<code>HTTPステータスコード 200 OK</code>および<code>404 File Not Found</code>を返している。<br> Webサーバが必要な評価試験において、以下のようなサンプルコードを動作させるとよい。<br> <br> IPアドレスはDHCPから自動で取得しており、手動で設定する場合は、<code>Ethernet.begin()</code>で指定する。<br> また、IPアドレスはシリアルポートに出力しており、<br> WebブラウザからこのWebサーバに接続する時は、シリアルモニタに表示されたIPアドレスへリクエストを送る。<br> <br> リクエストラインのみを確認するので、その行だけ特別にバッファ(変数<code>reqLine</code>)にコピーしている。<br> クライアントからのリクエストを読み込みんだ後、バッファを確認してメソッドとURIを取得する。<br> もし、長いリクエストが来た場合、途中まで読み込む。<br> <br> Content-Lenghをセットしない代わりに、データ区切りとしてConnection closeする。<br> 効率は悪いが、単一クライアントのみ接続が可能なので、1つずつのリクエスト処理は短くする必要がある。<br> <syntaxhighlight lang="c++"> #include <Ethernet.h> byte mac[] = { 0xDE,0xAD,0xBE,0xEF,0xF0,0x0D }; EthernetServer server(80); void setup() { Serial.begin(9600); Ethernet.begin(mac); Serial.println(Ethernet.localIP()); server.begin(); } void loop() { EthernetClient client = server.available(); if(client) { Serial.println("*** New Client ***"); boolean currentLineIsBlank = true; boolean requestLineRead = false; char reqLine[64] = {0}; char *p = reqLine; char *method = NULL; char *uri = NULL; const char delims[2] = " "; while(client.connected()) { char c = client.read(); // Serial.write( c ); // Query if(!requestLineRead && (p - reqLine ) < (sizeof(reqLine) - 1) && c != '\r' && c != '\n' ) { *p = c; p++; } if(c == '\n' && currentLineIsBlank) { // Parse Query p = strtok(reqLine, delims); while( p ) { if(!method) { method = p; } else if(!uri) { uri = p; } p = strtok(NULL, delims); } // Send Response if(!strcmp(method, "GET") && !strcmp(uri, "/pic")) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/plain"); client.println("Connection: close"); client.println(); client.println("OK!"); } else { client.println("HTTP/1.1 404 Not Found"); client.println("Content-Type: text/plain"); client.println("Connection: close"); client.println(); client.println("File Not Found"); } break; } if(c == '\n') { currentLineIsBlank = true; if(!requestLineRead) { requestLineRead = true; } } else if(c != '\r') { currentLineIsBlank = false; } } delay( 10 ); client.stop(); Serial.println("Client disconnected"); } } </syntaxhighlight> <br><br> == EthernetシールドとArduinoの遠隔操作 == Arduinoのメリットの1つに、各種シールドと開発環境における各種ライブラリの存在が挙げられる。<br> <br> 例えば、Arduino UnoをLANに接続するには、Ethernetシールドのみ準備することで、Arduino Unoにネットワーク機能を追加することができる。<br> そして、そのネットワーク機能はハードウェアの違いを意識せずに、Ethernetライブラリを使用することで実現できる。<br> さらに、プログラミングインターフェイスとして、ソケットよりも抽象化されたサーバオブジェクトとクライアントオブジェクトが用意されている。<br> <br> このセクションでは、ArduinoとEthernetシールドを使用したLED遠隔操作ソフトウェアを作成する。<br> ホストPC上のソフトウェアONボタンまたはOFFボタンを押下することで、Arduinoに接続されたLEDを制御する。<br> また、ArduinoとホストPCは、有線LANケーブルを使用してルータまたはハブに接続する。<br> <br> Arduinoのソースコードでは、TCP 50000番をリスニングしており、データ<code>S:1</code>を受信するとLEDを点灯、データ<code>S:0</code>を受信するとLEDを消す。<br> ホストPCのソフトウェアでは、ONボタンを押下した時はArduinoにデータ<code>S:1</code>を送信、OFFボタンを押下した時はデータ<code>S:0</code>を送信する。<br> このようなクライアントとサーバ間のデータ通信の取り決めのことを、プロトコルという。<br> [[ファイル:Arduino Ethernet 1.jpg|フレームなし|中央]] <br> 次に、ArduinoにEthernetシールドを接続する。<br> 下図に、Ethernetシールドの表面と裏面、接続図を示す。<br> [[ファイル:Arduino Ethernet 2.jpg|フレームなし|中央]] <br> 下図に、ArduinoとLEDの接続を示す。<br> 8番ピンのデジタル出力を使用している。<br> ここでは、抵抗は470[Ω]を使用しており、流れる電流は<math>I = \frac{5 \mbox{[V]} - 2.1 \mbox{[V]}}{470 [\Omega]} = 6 \mbox{[mA]}</math>である。<br> [[ファイル:Arduino Ethernet 3.jpg|フレームなし|中央]] <br> 以下に、Arduino Unoのソースコードを記述する。<br> データ<code>S:1</code>でLEDを点灯、データ<code>S:0</code>でLEDを消す。その他のデータを受信した場合、クライアントがそのデータを捨てる。<br> 1バイトずつにデータを取得するため、下図のような状態遷移となる。<br> [[ファイル:Arduino Ethernet 4.jpg|フレームなし|中央]] <br> MACアドレスは、一意性のある6バイトを設定する。(ここでは、0xDE 0xAD 0xBE 0xEF 0xF0 0x0Dとしている)<br> ネットワークアドレスは192.168.1.0/24、ArduinoのIPアドレスは192.168.1.10(固定)、ポート番号は、TCP 50000番とする。<br> <syntaxhighlight lang="c++"> #include <EthernetServer.h> #include <Ethernet.h> #include <EthernetClient.h> #include <Dhcp.h> #include <Dns.h> #include <EthernetUdp.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D }; byte ip[] = { 192, 168, 1, 10 }; EthernetServer server(50000); const int STATE_INIT = 0; const int STATE_1 = 1; const int STATE_2 = 2; const int STATE_3 = 3; const int PIN_LED = 8; void setup() { Ethernet.begin( mac, ip ); server.begin(); pinMode( PIN_LED, OUTPUT ); digitalWrite( PIN_LED, LOW ); } void loop() { EthernetClient client = server.available(); int state = STATE_INIT; int i; if(client) { while(client.connected()) { while( ( i = client.read() ) != -1 ) { if( state == STATE_INIT ) { if( i == 'S' ) { state = STATE_1; } else { client.stop(); break; } } else if( state == STATE_1 ) { if( i == ':' ) { state = STATE_2; } else { state = STATE_INIT; client.stop(); break; } } else if( state == STATE_2 ) { if( i == '1' ) { switch_led(1); client.print("OK"); } else if( i == '0' ) { switch_led(0); client.print("OK"); } state = STATE_INIT; client.stop(); break; } } } } } void switch_led(int on) { digitalWrite( PIN_LED, on ? HIGH : LOW ); } </syntaxhighlight> <br> 最後に、ホストOSのソフトウェア(.NET Frameworkの<code>TcpClient</code>クラスを使用)のソースコードを記述する。<br> ここでは、Windowsで利用可能なC#と.NET Frameworkを利用して、上述のプロトコルをサポートするTCPクライアントを作成する。<br> 下図に示すソフトウェアのUIでは、ArduinoのIPアドレスとポート番号を指定できるようにしている。<br> [[ファイル:Arduino Ethernet 5.jpg|フレームなし|中央]] <syntaxhighlight lang="c#"> using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Windows.Forms; namespace LightApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click( object sender, EventArgs e ) { SendCommand( true ); } private void button2_Click( object sender, EventArgs e ) { SendCommand( false ); } void SendCommand( bool on ) { try { var port = int.Parse(textBox2.Text); using(var client = new TcpClient(textBox1.Text, port)) { using(NetworkStream stream = client.GetStream()) { // データの送信 "S:0" または "S:1" Byte[] TxData = System.Text.Encoding.ASCII.GetBytes(string.Format("S:{0}", on ? "1" : "0")); stream.Write(TxData, 0, TxData.Length); // データの受信 var RxData = new Byte[256]; Int32 bytes = stream.Read(RxData, 0, RxData.Length); String responseData = System.Text.Encoding.ASCII.GetString(RxData, 0, bytes); } } } catch(Exception ex) { MessageBox.Show(ex.Message, "Switch", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Arduino]]
Arduinoの基礎 - Ethernet
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse