ArduinoでIoTにチャレンジ<その3>Wi-Fi経由でLチカ
前回は「Wi-Fi経由でLEDのON/OFFを行うサンプル・スケッチ AP_SimpleWebServerを動かしてみます。」と予告しました。ArduinoのWIFININAのサンプル・プログラムにはWi-Fi経由でLEDのON/OFFを行うものが用意されています。
次に示すように二つあります。
(1) AP_SimpleWebServer
Arduino MKR WiFi 1010をWi-Fi のアクセス・ポイント(AP)に設定し、MKR WiFi 1010とWi-Fiを備えたPCなどと直接接続できるようになります。ただしルータ機能はないので、インターネットへは接続できません。SSID、パスワードはMKR WiFi 1010 上に新しく作成するアクセス・ポイント(AP)のものです。
(2) Simple Web Server WiFi
一般的なルータのアクセス・ポイントに接続してWi-Fiのネットワークに参加します。ほかのPCからは、WebブラウザでArduino MKR WiFi 1010に割り当てられたIPアドレスでアクセスし、Wi-Fi経由でArduino MKR WiFi 1010に接続されたLEDを点滅できます。
アクセス・ポイントを作成する命令はWiFi.beginAP()関数ですが、この関数はWiFiNINAライブラリを利用するボードだけしか利用できません。APとして設定するのは一般的でないので、Wi-Fi経由でのLチカの例はSimpleWebServerWiFiで行うことにします。
●テスト回路
テスト回路は、次に示すようにArduino MKR WiFi 1010をブレッドボードに挿し込み、GNDをブレッドボードの青のマイナスの電源ラインに接続します。赤のLEDは、次のように接続します。
- 足の短いほうをGNDに接続
- 1kΩの抵抗をLEDの足の長いほうに直列に接続
- その抵抗を9番ピンに接続
Wi-Fiのモジュールはオンボードで完結しているので、LEDの追加以外に何もしなくて済みます。
●WiFiNINAライブラリの導入
メニューの、
ツール->ライブラリを管理
から、WiFiNINAで検索し、WiFiNINAライブラリをインストールします。
●サンプル・プログラムを読み込む
Arduino IDE を起動し、
ファイル>スケッチ例>WiFiNINA>SimpleWebServerWiFi
を選択することで、該当するスケッチ例を読み込めます。
●今回使用するサンプル・プログラム
(1)SimpleWebServerWiFiのソース・プログラムのうち表示行数を削減するためコメントの一部を削除しています。命令は使用していなくても削除していません。削除したコメントに替えてプログラムの説明を追加しています。
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h" // SSID、パスワードを格納した変数のヘッダ・ファイル読む
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password WPAを使用
int keyIndex = 0; // 今回は使用しない
int status = WL_IDLE_STATUS;
ここまででライブラリの読み込み、主な変数の定義を行っています。
具体的なSSID名、パスワードは別のタブ(ソース)に保存しています。そのため、メインのソース・プログラムにはSSIDとパスワードが表示されていません。
(2)ポート80を使用するWiFiServerのオブジェクトServer(80)で作成します。
WiFiServer server(80);
(3)シリアル通信を初期化し利用できるようにしま。併せてLEDを点滅します。
出力ポート 9 を設定します。
void setup() {
Serial.begin(9600); // initialize serial communication
pinMode(9, OUTPUT); // set the LED pin mode
(4)ボードにWi-Fiモジュールが搭載されていることを確認します。
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
(5)ファームウェアのバージョンのチェックを行い 、最新のバージョンであることを確認、必要に応じてバージョンアップの指示が出ます。
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
(6)ここでWi-Fiへの接続処理を行い接続の確認を行います。
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to Network named: ");
Serial.println(ssid); // print the network name (SSID);
status = WiFi.begin(ssid, pass); // Wi-Fiへ接続する
Serial.println(status);
delay(10000);
}
server.begin(); // start the web server on port 80
printWifiStatus(); // you're connected now, so print out the status
ここで初期化の処理を終えます。
(7)メイン処理
void loop() {
WiFiClient client = server.available(); // クライアントからの要求確認
(8) 新しいクライアントからの要求があったら、文字列currentLineをクリアして行末まで読み取ります。応答を返します。
if (client) { // clientの問い合わせがあれば次の処理を行う
Serial.println("new client"); // シリアルモニタにnew clientと表示
String currentLine = ""; // 受信バッファをクリア
while (client.connected()) { // clientと接続中
if (client.available()) { // データがあると
char c = client.read(); // データを読み取り
Serial.write(c); // シリアルモニタにも書き出す
(9)クライアントからのデータを行末に受信以降、クライアントに応答を返します。
if (c == '\n') { // 行末以降 クライアントの応答を戻す
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
(10) 上記の定形の応答に続いてWebブラウザに表示する内容を送信します。LEDのON/OFFを行う処理には<a>タグの機能を利用します。
client.print("Click <a href=\"/H\">here</a> turn the LED on pin 9 on<br>");
client.print("Click <a href=\"/L\">here</a> turn the LED on pin 9 off<br>");
client.println(); // すべてが送信されたことを示す空行を送る:
break; // break out of the while loop:
}
(11)clientの要求が"GET /H" または "GET /L"なのか調べ、対応する処理を行います。
else { // if you got a newline, then clear currentLine:
currentLine = "";
}
} else if (c != '\r') { // 行末以外のデータの場合,
currentLine += c; // currentLineに読み取ったデータを追加する
}
if (currentLine.endsWith("GET /H")) {
digitalWrite(LED_BUILTIN, HIGH); // GET /H でLED オン
digitalWrite(9, HIGH); // この命令を追加する
}
if (currentLine.endsWith("GET /L")) {
digitalWrite(LED_BUILTIN, LOW); // GET /L turns the LED off
digitalWrite(9, LOW); // この命令を追加する
}
}
}
client.stop(); // close the connection:
Serial.println("client disconnected");
}
}
(12)printWifiStatus()は、Wi-Fiの接続状況をシリアルモニタに表示する関数です。
void printWifiStatus() {
Serial.print("SSID: "); // 接続している SSIDの見出しを表示:
Serial.println(WiFi.SSID()); // SSIDを表示
IPAddress ip = WiFi.localIP(); // IPアドレスを取り出す
Serial.print("IP Address: ");
Serial.println(ip); // IPアドレスを表示
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi); // WiFiの受信電波の強さを表示
Serial.println(" dBm");
Serial.print("To see this page in action, open a browser to http://");
Serial.println(ip); // print where to go in a browser:
}
オリジナルのSimpleWebServerWiFiには、9番ピンのLEDをON/OFFする命令が抜けています。代わりにdigitalWrite(LED_BUILTIN, LOW); とオンボードのLEDを点滅する命令がセットされています。その命令の下にdigitalWrite(9, LOW); とdigitalWrite(9,HIGH); の命令を追加してください。
●実行の様子
プログラムを実行すると最初にシリアルモニタに、次のようなメッセージが表示されます。
Wi-Fiの信号の強さと、割り当てられたIPアドレスが表示されます。
●Webブラウザの表示
シリアルモニタに表示されたIPアドレスをPCで動くChromeブラウザのアドレス欄に入力し、Arduino MKR WiFi 1010のWebServerにアクセスすると、2行のメッセージが表示されます。
表示されているように、上段のhereをクリックするとMKR WiFi 1010の9番ピンに接続されたLEDが点灯します。下段のhereをクリックするとLEDが消灯します。
最初のテストではLEDが点灯しませんでした。ソースを確認すると9番ピンでなく6番ピン(LED_BUILTIN)に接続され、オンボードの黄色いLEDがON/OFFするようになっていました。実際この黄色いLEDが点滅しました。
マウスでクリックするたびに、WebブラウザとMKR WiFi 1010の間で行われる通信の様子が示されています。
次回、Webブラウザの表示内容、いろいろ操作をする方法を検討します。
(2021/09/19)
<神崎康宏>