できること

第6回 Arduinoを使ってWebサーバをつくろう!

DSC_1057

前回は、光センサから明るさの情報をアナログ入力でArduino上に表示しました。これで、Arduinoでの入力・出力どちらも扱えるようになりましたね!今回はもう一歩進んでArduinoをネットワークに繋いでみたいと思います。 Arduino単体で通信ができるようになるとぐっと制作の幅も広がりますよ。こんなに小さいのに、なんとWebサーバにもなるんです!

今回はArduinoをLANケーブルで接続して、通信を可能にするイーサネットシールドというものを利用して、ArduinoをWebサーバとして動かすプログラムを作成してみたいと思います。

 

目次

  1. 光センサがネットワークが繋がったら何ができる?
  2. 合体パーツShield(シールド)って何?
  3. イーサネットシールドを使う準備をする
  4. いよいよプログラムを動かしてサーバ稼働!

 

 

光センサがネットワークに繋がったら何ができる?

光センサは、暗いところにおくとセンサ自体の抵抗値が大きくなり、明るいところに置くと抵抗値は低くなる性質があることを前回説明しました。光センサがネットワークと繋がると、光センサの現象をネットワークへ流せるんです! このArduinoWebサーバとPHPやRubyなどのプログラムと組み合わせることで毎日の日照時間の計測や、オフィスの明かりを条件にまだ人が残っている、いないなどの簡易的なプログラム、TwitterのAPIと連携させて一定時間ごとに明るさをつぶやくbotプログラムの作成などさまざまなことが可能になります。

 

今回の電子工作レシピ:

 

合体パーツShield(シールド)って何?

Arduinoには、いろいろな機能を手軽に拡張できるシールドというものが数多く存在します。今回利用するイーサネットシールドの他、加速度センサなど電子回路を0から作らなくても手軽に利用できるようなシールドが用意されています。

「Arduino シールド」で検索

 

今回は、イーサネットシールド(Ethernet Shield R3)を利用して制作を行います。イーサネットシールドはArduinoを手軽にネットワークにつなげることができるシールドです。 Arduinoのスケッチサンプルでも、イーサネットシールドを利用したさまざまなサンプルが事前に用意されていますので、今回はそれを利用してArduinoをサーバとして動作させましょう。サーバへアクセスした際には、前回作った、光センサから入力された値を表示してみたいと思います。

 

イーサネットシールドを使う準備をする

まず始めにイーサネットシールドをArduinoに取り付けてみましょう。

1.開封

2014-08-05 13.36.07

(Arduino関係の製品はいつもかっこいい箱に入っていますね…)

 

2014-08-05 13.40.32

箱から出すとこのような感じです。

 

2.Arduinoに取り付け

さっそくArduinoに取り付けていきます。いざ合体!

DSC_1049_2

Arduino本体を下に置いて、該当の箇所にイーサネットシールドの足を接続します。

DSC_1051

Arduinoにイーサネットシールドを接続した状態。足が数本はみ出ますが問題ありません。

 

これでArduino本体とイーサネットシールドの接続は完了です。抜き差しする際に、足が曲がってしまったりしてうまく接続できないことがありますので気をつけてください。

 

3.サンプルプログラムを開きます

次にプログラムの方を作成していきます。作成と言っても難しいことはありません。今回は、スケッチの例からEthernet内のWebServerというサンプルプログラムを利用します。

Arduino Sample

[ファイル]-[スケッチの例]-[Ethernet]-[WebServer]

4.プログラムを書き換える

このサンプルでは、Arduinoをサーバとして利用できるプログラムが記述されています。Arduinoサーバにアクセスした際には、HTMLの結果としてアナログピンの入力データを表示する内容となっています。

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //イーサネットシールドに記載されているMACアドレスを指定する
IPAddress ip( 192,168,0,177); //Arduinoサーバーに割り当てるIPアドレスを指定する
EthernetServer server(80); //サーバーが利用するポートを指定(HTTPで利用するので基本このままの80番ポートで問題ないです)
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Ethernet.begin(mac, ip); //ここからイーサネットシールドで接続の確立を試みます
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available(); //サーバーに対して外部から接続があるかどうかを監視
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
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"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("");
client.println("");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("");
}
client.println("");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}

このプログラムで書き換える必要がある箇所は基本的に2カ所。

  • MACアドレス
  • IPアドレス

MACアドレス

MACアドレスとはハードウェアごとに異なる固有の製品番号のようなものです。今回利用するイーサネットシールドでは、シールド上もしくは箱にMACアドレスが記載されていると思いますので、それを参考に、それぞれ「0x」をつけた形で書き換えてください。

DSC_1047

イーサネットシールドの後ろ側にこんな形で記載されています。

 

IPアドレス

IPアドレスは今利用しているコンピュータのネットワーク設定に応じて設定してください。通常、自宅などで利用している場合はルーターを経由していると思います。その場合は、下記の方法からコンピュータで利用しているIPアドレスを調べた上で、他の端末と重複しないIPアドレスを任意で設定して下さい。

 

Macの場合: [システム環境設定]の[ネットワーク設定]から確認するか、 [ターミナル]上で「ifconfig」と入力して確認

MACでのIPアドレス確認

Windowsの場合:[コマンドプロンプト]上で「ipconfig」と入力して確認

windowsでのIPアドレス確認

今回、筆者の構成では下記のようにルーターからLANケーブルを通じてコンピュータ、Arduinoを接続しています。ネットワークの設定については各環境で確認する箇所が違う場合もあるため、その場合はみなさんご自分の環境を調べてください。

構成

今回の筆者のネットワーク構成

 

いよいよプログラムを動かしてサーバ稼働!

MACアドレス、IPアドレスの設定が完了したらさっそくプログラムをコンパイルして、アップロードしてみましょう。

Arduino本体へのプログラムのアップロードが完了したら、さっそくブラウザで書き込みを行ったIPアドレスからなるURLを入力してみましょう。今回は192.168.0.177で書き込みを行いましたのでブラウザには「http://192.168.0.177/」と入力しています。 アナログ入力の値が表示されました。

Arduinoアナログ入力

このプログラムでは5秒毎にブラウザを更新してアナログの入力値を表示するプログラムになっていますが、今はArduinoに何も挿していない状態なので入力値が上下にふれています。 ここに、前回作成した光入力センサの回路を組んで、光センサからの情報を常にサーバにアクセスした時に確認できるようにしてみます。

 

Arduino光センサー入力

前回作成したアナログ入力の回路

2014-08-05 15.13.02

 

回路ができたら、Arduinoと接続します。今回はアナログ入力0番目のみを利用したいので、プログラムも少し変更してみましょう。36行目付近のforから始まる部分で、アナログ入力の番号を指定して入力値を取得する処理しています。このforから始まる記述はfor文と呼ばれるもので、繰り返し処理をさせたい場合に利用します。

for(初期値の設定 ; 繰り返す条件 ; 繰り返し毎の後処理){ 条件を満たす場合に繰り返される処理を記述 }

ここでは、アナログチャンネルの0から5番目までを順に繰り返しで入力値を取得しています。今回は、0番目のみで良いので繰り返し処理を利用しないようにするか、もしくは1回だけで処理を完了するように変更しましょう。

//変数analogChannel(初期値を0に設定)が6以下の場合に繰り返し処理を実行。毎回の処理が終わった場合にanalogChannelに1を加える
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("
");
}

パターン1 0番目のみの値が欲しいのでfor分の条件を変更

 for (int analogChannel = 0; analogChannel < 1; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("
");
}

パターン2 for文を利用せずにそのまま記述

 int sensorReading = analogRead(0); //analogReadで0番を指定
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("
");

上記どちらかのパターンでプログラムを書き換えて実行してみます。

 

Arduino Server02

 

これで光センサによって入力された明るさの数値がサーバ上に表示されました。このサーバを利用し、別のPCから一定間隔でサーバにアクセスして明るさを取得し、何か別のプログラムを実行させることができます。 このようにArduinoの合体パーツ「シールド」を利用すればゼロから回路を作らなくても比較的早く作りたいものに近づくことが可能です。
次回は、Arduinoとネットワークシールドを使ってさらに実用的な作品を作ってみたいと思います!お楽しみに!!
アバター画像

電子工作や新しいデバイスをこよなく愛するエンジニア。日常生活のちょっとしたことを電子工作で作って試して、おもしろく過ごしたいと日々考えています。

出場ロボット解剖計画