WiFi(アクセスポイント、サーバー)で近距離遠隔操作する方法(Arduinoプログラミング)

Arduinoコマンド:WiFiアクセスポイントの設定

「ATOM LITE」を例にアクセスポイントに設定して、スマホ等からWiFi通信で接続し、近距離遠隔操作を行う方法を紹介します。

「ATOM LITE」については以下のリンクで詳しく紹介しています。

ATOM LITE プログラミング初心者におすすめ超小型で高機能!
マイコンボードはRaspberry Pi、Arduino、M5Stack等がありますが、一通りやってみてそれぞれの良さはあるものの「最初に何を?」と聞かれたらATOM LITEが一番お手軽♪プログラミング初心者におすすめ
「開発環境の準備」がまだの方は → こちら

「ATOM LITE」をWiFiローカル接続で遠隔操作する方法は以下のリンクで詳しく紹介しています。

WiFi(ローカル接続、サーバー)で遠隔操作する方法(Arduinoプログラミング)
Wi-Fi通信でスマホから遠隔操作を行う方法を詳しく紹介。サーバーの仕組みを利用することで簡単にブラウザからの遠隔操作が実現できます。ATOM LITE使用

JavaScriptの「fetch」を使用してページを更新しない実用的なWiFi遠隔操作方法(ローカル接続)は以下リンクで詳しく紹介しています。

WiFi遠隔操作Arduinoコマンドでブラウザベースのスマホ、PCリモートコントローラの紹介
ブラウザベースで遠隔操作、リアルタイムデータ通信を行う方法をコピペ用サンプルプログラムを使って紹介します。 サーバー機能を利用して「JavaScript」の「fetch」を使うことでデータの送受信を行います。
スポンサーリンク

1.サンプルプログラムの動作紹介(ATOM LITE)

サンプルプログラムの動作について紹介します。

「ATOM LITE」は以下の設定でアクセスポイントに設定しています。
・SSID:logikara
・パスワード:atomlite
・IPアドレス:192.168.4.1

「SSID」はスマホ等でWiFiの接続先を検索した時に表示される接続先名です。
「パスワード」はWiFi接続時に入力するパスワードです。
「IPアドレス」はWiFi接続先のアドレスです。これをブラウザのアドレスバーに入力することで接続先にアクセスすることができます。
「IPアドレス」は特に指定しなくてもアクセスポイントを設定した時点で「192.168.4.1」に設定されます。
個別に指定することもできますが「102.168.4.1」は一般的な無線機器の「IPアドレス」のため、このまま使用することをおすすめします。

パソコンやスマホからWiFi接続先を検索すると「logikara(SSID)」が出てくるので選択します。
パスワードを聞かれるので「atomlite」を入力すると接続が完了します。

次に何でもよいのでネットを見るのに使っているブラウザを立ち上げて、アドレスバーにIPアドレスの「192.168.4.1」を入力してエンター等確定ボタンを押すと、以下のような画面が表示されます。(下画像はGoogle Chromeです。)

アクセスポイント接続トップ画面

これは「ATOM LITE」をサーバーとして設定おり、ブラウザからのリクエスト(要求)に対して「ATOM LITE」側からレスポンス(応答)として「htmlデータ」が送信され、ブラウザ側で表示されたためです。

「ON」「OFF」ボタンにもリクエストとしてアドレスが設定されており、ボタンが押されることでこのアドレスがリクエストとして送信されます。
「ATOM LITE」側はこれをうけて、それぞれに対応したプログラムを実行し完了するごとに設定したレスポンスを返します。

これにより「ON」ボタンを押すと「ATOM LITE」本体のLEDが青色に「OFF」を押すとLEDは白色に変わる動作が行えるようになっています。
出力端子21も同時にON/OFFさせているため、LED等を接続すると連動してON/OFFさせることができます。 設定した「SSID」や「パスワード」、「IPアドレス」はシリアルモニタを使用することでパソコンの画面上で確認することができます。
※表示されない場合は「ATOM LITE」側面の小さいリセットボタンを押すと表示されます。

「シリアル出力モニタ」については以下のリンクで詳しく紹介しています。

シリアル(UART)出力で内部データの表示(Arduinoプログラミング)
シリアル出力モニタとはプログラム内の値やデータをパソコンのモニタ上に表示させることができる機能で、ほとんどの開発環境にこの機能があります。表示だけではなく出力したデータを記録して保存したり、機器間でデータをやり取りする時にも使用されます。
スポンサーリンク

2.サンプルプログラム(コピペ)

下のコードを「コピペ」して書き込んで動作確認してみましょう。
※コピーは下コード(黒枠)内の右上角にある小さなアイコンのクリックでもできます。

#include <M5Atom.h>
#include <WiFi.h>       //WiFi接続用
#include <WebServer.h>  //サーバー設定用

// アクセスポイント設定
const char ssid_AP[] = "logikara";  //SSID
const char pass_AP[] = "atomlite";  //パスワード(8文字以上)

// サーバー設定ポート80で接続
WebServer server(80);
// htmlメイン画面データ ※R"この中の文字列は改行は無視され連続した文字列として扱われる"
char html[] = R"(
  <!DOCTYPE html>
  <html lang="jp">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>REMOTE-SWITCH</title>
  </head>
    <body>
      <h1>REMOTE-SWITCH</h1>
      <div>
        <button style="height:50px" onclick="location.href='/get/btn_on'"> ON </button>
        <button style="height:50px" onclick="location.href='/get/btn_off'"> OFF </button>
      </div>
    </body>
  </html>
)";

// FastLED(CRGB構造体)設定
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
  return (CRGB)((r << 16) | (g << 8) | b);
}
//-------------------------------------------------
// サーバーリクエスト時処理関数
//-------------------------------------------------
// ルートアクセス時の応答関数
void handleRoot() {
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}
// エラー(Webページが見つからない)時の応答関数
void handleNotFound() {
  server.send(404, "text/plain", "404 Not Found!");  //text送信
}
// ブラウザONボタン処理
void btnOn() {
  digitalWrite(21, HIGH);                   //出力0 ON(青色LED)
  M5.dis.drawpix(0, dispColor(0, 0, 200));  //本体LED(青)
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}
// ブラウザOFFボタン処理
void btnOff() {
  digitalWrite(21, LOW);                    //出力0 OFF(青色LED)
  M5.dis.drawpix(0, dispColor(20, 20, 20)); //本体LED(白)
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}
//-------------------------------------------------
// 初期設定
//-------------------------------------------------
void setup() {
  M5.begin(true, false, true);    //Serial,POWER,LED
  Serial.begin(9600);             //標準のシリアル通信設定

  // アクセスポイント設定
  WiFi.softAP(ssid_AP, pass_AP);  //ソフトAP設定

  // サーバー設定
  server.on("/", handleRoot);         //ルートアクセス時の応答関数を設定
  server.onNotFound(handleNotFound);  //Webページが見つからない時の応答関数を設定
  server.on("/get/btn_on", btnOn);    //ボタンオン受信処理
  server.on("/get/btn_off", btnOff);  //ボタンオフ受信処理
  server.begin();                     //Webサーバー開始

  // シリアル出力
  Serial.printf("\nSSID:%s\n", ssid_AP);//SSID
  Serial.printf("PASS:%s\n", pass_AP);  //PASSWORD
  Serial.print("IP address: ");
  Serial.println(WiFi.softAPIP());      //IPアドレス(配列)

  // 本体LED設定
  M5.dis.drawpix(0, dispColor(20, 20, 20)); //LED点灯(白)
  // 入出力端子設定
  pinMode(21, OUTPUT);  //出力端子
}
//-------------------------------------------------
// メイン
//-------------------------------------------------
void loop() {
  server.handleClient();  //クライアントからのアクセス確認
  delay(200);             //遅延時間(ms)
}
スポンサーリンク

3.アクセスポイント設定プログラムについて

アクセスポイントに設定するプログラムについて紹介します。

まず上コードの2行目のように以下のWiFi接続に必要なヘッダーファイル「WiFi.h」を準備します。

#include <WiFi.h>       //WiFi接続用

アクセスポイントの設定を行うには、5行目~7行目のように「SSID」と「パスワード」の設定を行います。

// アクセスポイント設定
const char ssid_AP[] = "logikara";  //SSID
const char pass_AP[] = "atomlite";  //パスワード(8文字以上)
パスワードは8文字以上に設定しないと上手く動作しないようですので8文字以上に設定しましょう

次に64行目, 65行目のように初期設定(void setup)の中で以下のように設定するだけです。

// アクセスポイント設定
WiFi.softAP(ssid_AP, pass_AP);  //ソフトAP設定

4.サーバー設定プログラムについて

「ATOM LITE」をサーバーとして設定するプログラムについて紹介します。

ここはWiFiローカル接続で紹介した記事とIPアドレス以外同じ内容です。
サーバーとはリクエスト(要求)に対してレスポンス(応答)を返すという動作をします。
この動作を利用して、リクエストを受けたら必要な処理を実行してからレスポンスを返すというのが本プログラムの基本動作になります。

まず3行目のように以下のWiFi接続に必要なヘッダーファイル「WebServer.h」を準備します。

#include <WebServer.h>  //サーバー設定用

次に10行目のようにサーバーのポート設定を行います。
一般的に「80」が使用されるので以下のように「80」で設定しましょう。

// サーバー設定ポート80で接続
WebServer server(80);
ポートは80以外に設定してもいいですが、この場合はIPアドレスの後に設定したポートを指定する必要があります。
例:ポート8080の場合、「192.168.4.1:8080」
※ポート80は省略されているだけで実際は「192.168.4.1:80」で送信されています。80にしておけば「:80」を書かなくてもよいです。

次に12行目~29行目のようにブラウザで表示させたい「htmlデータ」を文字列として以下のように準備しておきます。

// htmlメイン画面データ ※R"この中の文字列は改行は無視され連続した文字列として扱われる"
char html[] = R"(
  <!DOCTYPE html>
  <html lang="jp">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>REMOTE-SWITCH</title>
  </head>
    <body>
      <h1>REMOTE-SWITCH</h1>
      <div>
        <button style="height:50px" onclick="location.href='/get/btn_on'"> ON </button>
        <button style="height:50px" onclick="location.href='/get/btn_off'"> OFF </button>
      </div>
    </body>
  </html>
)";

今回の「htmlデータ」は「REMOTE-SWITCH」という表示と「ON」「OFF」ボタンを置いただけのシンプルなものです。

ボタンには「onclick」でリンク先のアドレスが指定されており、ボタンが押された時にそれぞれのアドレスへのリクエストを受けて「ATOM LITE」側で処理が実行されます。

各ボタンには以下のようにルートアドレスに続くアドレスを指定しています。
・ONボタン:192.168.4.1/get/btn_on
・OFFボタン:192.168.4.1/get/btn_off

アドレスの指定で「/」はルートのアドレス「192.168.4.1」を表します。
「htmlデータ」の文字列は「R”( )”」のカッコ内に書くことで、改行は無視され連続した文字列として扱われます。

次に67行目~72行目のように初期設定(void setup)の中でブラウザからのリクエスト(アドレス)を受けた時に実行する処理(関数)を以下のように設定します。

// サーバー設定
server.on("/", handleRoot);         //ルートアクセス時の応答関数を設定
server.onNotFound(handleNotFound);  //Webページが見つからない時の応答関数を設定
server.on("/get/btn_on", btnOn);    //ボタンオン受信処理
server.on("/get/btn_off", btnOff);  //ボタンオフ受信処理
server.begin();                     //Webサーバー開始
server.on ( アドレス関数名 ) ;

server.on:ブラウザからのリクエストに対して実行する関数を指定するコマンド。
アドレス:ブラウザから受信するアドレス(リクエスト)を指定(「/」はルート「192.168.4.1」を表す。)
関数名:ブラウザからのリクエストを受けて実行する関数を指定。レスポンスもこの関数内で返す。

設定が終わったら最後に「server.begin()」を実行してサーバー動作を開始します。


次に37行目~56行目のようにブラウザからのリクエストに対して実行する処理をそれぞれ関数にまとめて設定します。

この関数は初期設定(void setup)より上に書く必要があります。

まずは37行目~40行目のようにルート「/」(192.168.4.1)へのリクエストに対して実行される処理を以下のように設定します。

ここでは、レスポンスコード「200」で通信が正常に行われたことを知らせて、「html」に格納されている文字列を「htmlデータ」として返しています。

// ルートアクセス時の応答関数
void handleRoot() {
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}
server.send ( レスポンスコードデータ形式送信データ) ;

server.send:ブラウザのリクエストに対してレスポンスを返すコマンド。
レスポンスコード:通信結果をブラウザ側に伝えるに3桁のコード。
・「200」通信正常終了
・「404」Webページが見つからない・・・等
データ形式:ブラウザへ送信するデータ形式(MIMEタイプ)を指定。
・「text/html」htmlデータ
・「text/plain」テキストデータ
・「text/css」cssデータ
・「text/javascript」JavaScriptデータ・・・等
送信データ:ブラウザへ送信するデータ


次に41行目~44行目のようにブラウザからリクエストされたアドレスが見つからなかった時の処理を以下のように設定します。

ここでは、レスポンスコード「404」でページが見つからなかったことを知らせて、「404 Not Found!」を「textデータ」として返しています。

// エラー(Webページが見つからない)時の応答関数
void handleNotFound() {
  server.send(404, "text/plain", "404 Not Found!");  //text送信
}
textデータ」はブラウザ上でそのまま表示されます。

次に45行目~56行目のようにブラウザの「ON」「OFF」ボタンが押された時のリクエストに対して実行される処理を以下のように設定します。

「ON」ボタンの処理は出力端子をHIGH(5V)にして本体LEDを青色に点灯した後、レスポンスコード「200」で通信が正常に行われたことを知らせて、「html」に格納されている文字列を「htmlデータ」として返しています。

「OFF」ボタンの処理は出力端子をLOW(0V)にして本体LEDを白色に点灯した後、レスポンスコード「200」で通信が正常に行われたことを知らせて、「html」に格納されている文字列を「htmlデータ」として返しています。

// ブラウザONボタン処理
void btnOn() {
  digitalWrite(21, HIGH);                   //出力0 ON(青色LED)
  M5.dis.drawpix(0, dispColor(0, 0, 200));  //本体LED(青)
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}
// ブラウザOFFボタン処理
void btnOff() {
  digitalWrite(21, LOW);                    //出力0 OFF(青色LED)
  M5.dis.drawpix(0, dispColor(20, 20, 20)); //本体LED(白)
  server.send(200, "text/html", html);  //レスポンス200を返しhtml送信
}

最後に89行目のようにメイン処理(void loop)内で以下を実行し続けブラウザからのリクエストを監視します。

ブラウザからのリクエストが確認されたら、サーバー設定で設定した各処理を実行します。

server.handleClient();  //クライアントからのアクセス確認

5.まとめ

WiFi接続でアクセスポイントを設定するには、ヘッダーファイル「WiFi.h」を準備して、設定した「SSID」と「パスワード」で「WiFi.softAP」を実行するだけです。

サーバーの設定は、ヘッダーファイル「WebServer.h」を準備して、通信ポートを「80」に設定します。
ブラウザページとして表示する「htmlデータ」を文字列で準備します。

server.on」で各リクエストに対して実行する関数を設定し、この関数内の処理が実行された時には「server.send」でレスポンスコードとデータを返すように設定します。

メイン内で「server.handleClient」を繰り返し実行しブラウザからのリクエストを監視し、ブラウザからのリクエストが確認されたら、設定した各処理を実行しています。

今回の遠隔操作は、サーバーのリクエスト(要求)に対してレスポンス(応答)を返すという動作を利用して、リクエストを受けたら必要な処理を実行させることで実現しています。


以上のように、サーバーの基本的な動作を利用することでシンプルなプログラムで遠隔操作が実現できましたが、今回のプログラムではボタン操作を行うごとにページが更新されてしまっています。
こうならないように「javascript」を使用してボタンにイベントを設定することでページを更新しない動作も実現できます。
「css」も使えばページのデザインも凝ったものが作れます。
また「M5Stack GRAY」のようにSDカードが使えれば、そこからデータを読み込んで表示させると文字列ではなくそのままデータを読み込めて便利なので、また詳しく紹介したいと思います。

コメント

タイトルとURLをコピーしました