Arduinoの基礎 - Ethernet
概要
Ethernetシールド
DHCPの利用
ArduinoでEthernetシールド等を使用する場合、プログラムで明示的にIPアドレスを指定するのではなく、
DHCPで自動的にIPアドレスの割り当てを行う方法を記載する。
Arduinoの標準のEthernetライブラリを使用することで、簡単に実現できる。
これは、Ethernet.begin()
を呼び出す時、MACアドレスのみを指定することで(IPアドレスは指定しない)、DHCPからIPアドレスを自動で取得できる。
ここでは、Arduino UnoにEthernetシールドを接続している。
以下の例では、シリアルポートに結果を出力するために、Serial.begin()
やprintln()
を呼び出している。
#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()
{
}
Webサーバの実装
このセクションでは、Arduinoの標準のEthernetライブラリを使用して、単純なWebサーバを実装する。
簡単なWebサーバの実装例はExampleに含まれている。
以下の例では、URIを確認して、HTTPステータスコード 200 OK
および404 File Not Found
を返している。
Webサーバが必要な評価試験において、以下のようなサンプルコードを動作させるとよい。
IPアドレスはDHCPから自動で取得しており、手動で設定する場合は、Ethernet.begin()
で指定する。
また、IPアドレスはシリアルポートに出力しており、
WebブラウザからこのWebサーバに接続する時は、シリアルモニタに表示されたIPアドレスへリクエストを送る。
リクエストラインのみを確認するので、その行だけ特別にバッファ(変数reqLine
)にコピーしている。
クライアントからのリクエストを読み込みんだ後、バッファを確認してメソッドとURIを取得する。
もし、長いリクエストが来た場合、途中まで読み込む。
Content-Lenghをセットしない代わりに、データ区切りとしてConnection closeする。
効率は悪いが、単一クライアントのみ接続が可能なので、1つずつのリクエスト処理は短くする必要がある。
#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");
}
}