前回は、光センサから明るさの情報をアナログ入力でArduino上に表示しました。これで、Arduinoでの入力・出力どちらも扱えるようになりましたね!今回はもう一歩進んでArduinoをネットワークに繋いでみたいと思います。 Arduino単体で通信ができるようになるとぐっと制作の幅も広がりますよ。こんなに小さいのに、なんとWebサーバにもなるんです!
今回はArduinoをLANケーブルで接続して、通信を可能にするイーサネットシールドというものを利用して、ArduinoをWebサーバとして動かすプログラムを作成してみたいと思います。
目次
光センサがネットワークに繋がったら何ができる?
光センサは、暗いところにおくとセンサ自体の抵抗値が大きくなり、明るいところに置くと抵抗値は低くなる性質があることを前回説明しました。光センサがネットワークと繋がると、光センサの現象をネットワークへ流せるんです! このArduinoWebサーバとPHPやRubyなどのプログラムと組み合わせることで毎日の日照時間の計測や、オフィスの明かりを条件にまだ人が残っている、いないなどの簡易的なプログラム、TwitterのAPIと連携させて一定時間ごとに明るさをつぶやくbotプログラムの作成などさまざまなことが可能になります。
今回の電子工作レシピ:
-
- Arduino本体(Arduino Uno R3)
- イーサネットシールド(Ethernet Shield R3)※2023年2月現在は販売を終了しており、後継品が発売されていますのでご注意ください。なお、デバプラでは後継機での実装は行っておりませんので、責任は負いかねます。
合体パーツShield(シールド)って何?
Arduinoには、いろいろな機能を手軽に拡張できるシールドというものが数多く存在します。今回利用するイーサネットシールドの他、加速度センサなど電子回路を0から作らなくても手軽に利用できるようなシールドが用意されています。
今回は、イーサネットシールド(Ethernet Shield R3)を利用して制作を行います。イーサネットシールドはArduinoを手軽にネットワークにつなげることができるシールドです。 Arduinoのスケッチサンプルでも、イーサネットシールドを利用したさまざまなサンプルが事前に用意されていますので、今回はそれを利用してArduinoをサーバとして動作させましょう。サーバへアクセスした際には、前回作った、光センサから入力された値を表示してみたいと思います。
イーサネットシールドを使う準備をする
まず始めにイーサネットシールドをArduinoに取り付けてみましょう。
1.開封
2.Arduinoに取り付け
さっそくArduinoに取り付けていきます。いざ合体!
Arduino本体を下に置いて、該当の箇所にイーサネットシールドの足を接続します。
これでArduino本体とイーサネットシールドの接続は完了です。抜き差しする際に、足が曲がってしまったりしてうまく接続できないことがありますので気をつけてください。
3.サンプルプログラムを開きます
次にプログラムの方を作成していきます。作成と言っても難しいことはありません。今回は、スケッチの例から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」をつけた形で書き換えてください。
IPアドレス
IPアドレスは今利用しているコンピュータのネットワーク設定に応じて設定してください。通常、自宅などで利用している場合はルーターを経由していると思います。その場合は、下記の方法からコンピュータで利用しているIPアドレスを調べた上で、他の端末と重複しないIPアドレスを任意で設定して下さい。
Macの場合: [システム環境設定]の[ネットワーク設定]から確認するか、 [ターミナル]上で「ifconfig」と入力して確認
Windowsの場合:[コマンドプロンプト]上で「ipconfig」と入力して確認
今回、筆者の構成では下記のようにルーターからLANケーブルを通じてコンピュータ、Arduinoを接続しています。ネットワークの設定については各環境で確認する箇所が違う場合もあるため、その場合はみなさんご自分の環境を調べてください。
いよいよプログラムを動かしてサーバ稼働!
MACアドレス、IPアドレスの設定が完了したらさっそくプログラムをコンパイルして、アップロードしてみましょう。
Arduino本体へのプログラムのアップロードが完了したら、さっそくブラウザで書き込みを行ったIPアドレスからなるURLを入力してみましょう。今回は192.168.0.177で書き込みを行いましたのでブラウザには「http://192.168.0.177/」と入力しています。 アナログ入力の値が表示されました。
このプログラムでは5秒毎にブラウザを更新してアナログの入力値を表示するプログラムになっていますが、今はArduinoに何も挿していない状態なので入力値が上下にふれています。 ここに、前回作成した光入力センサの回路を組んで、光センサからの情報を常にサーバにアクセスした時に確認できるようにしてみます。
回路ができたら、Arduinoと接続します。今回はアナログ入力0番目のみを利用したいので、プログラムも少し変更してみましょう。36行目付近の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(" ");
上記どちらかのパターンでプログラムを書き換えて実行してみます。