【ビッグセール】Prime感謝祭はこちら

【ESP32】Wi-Fi経由でLEDを制御する方法・コード・Lチカ・ハードウェア学習

ESP32_Wi-Fi経由でLED制御 プログラミング
質問する人
質問する人

ESP32を使ってWi-Fi経由でスマホなどからLEDを制御してみたいな。

こんな質問にお答えします。

◆この記事の内容
・Arduino IDE使用してESP32のプログラミングを行い、Wi-Fi経由でまずはGPIOの制御を行う方法が分かります
うまし
うまし

ハードウェアエンジニア歴15年のうましが解説します。

スポンサーリンク

Wi-Fi経由でLEDを制御する

今回はESP32を使用してWi-Fi経由でGPIOの制御を行い、LEDの制御(Lチカ)を行います。海外のこちらの記事を参考にさせて頂いていますが一部変更を行っています。

【変更前】
GPIOピンがOFF時にボタンを緑色にON、ON時に灰色でOFFになっていました。

ESP32_Wi-Fi経由でLED制御1

【変更後】
GPIOピンがOFF時にボタンを灰色のOFF、ON時にオレンジのONに変更します。

ESP32_Wi-Fi経由でLED制御2

開発環境

・OS : Windows10 64bit
・Arduino IDE1.8.13

Arduino IDEのスケッチ

コピペしてもらうだけで動かせるかと思いますが以下の部分を使用される環境に合わせて変更をお願いします。

//Wi-Fiのssidとpasswordに置き換えてください
const char* ssid     = "********";
const char* password = "******";
//コメントは原文を訳させて頂きました
/*********
reference
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

//WiFi.hをインクルード
#include <WiFi.h>

//Wi-Fiのssidとpasswordに置き換えてください
const char* ssid     = "********";
const char* password = "******";

//ポート80にセット
WiFiServer server(80);

// HTTPリクエスト
String header;

//制御するピンの状態
String output26State = "off";
String output27State = "off";

//数値だけだと分かりづらいのでoutputxxと表記
const int output26 = 26;
const int output27 = 27;

//現在の時間
unsigned long currentTime = millis();
//以前の時間
unsigned long previousTime = 0; 
//タイムアウト時間
const long timeoutTime = 2000;

void setup() {
    Serial.begin(115200);     //シリアル通信のボーレート設定
    //GPIOピンの初期設定
    pinMode(output26, OUTPUT);
    pinMode(output27, OUTPUT);
    //LOWに設定
    digitalWrite(output26, LOW);
    digitalWrite(output27, LOW);

    //Wi-Fiに接続
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    //IPアドレスをシリアル通信で出力してWebサーバーとしてスタート
    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    server.begin();
}

void loop(){
    WiFiClient client = server.available();   //クライアント(スマホなど)の接続を確認

    if (client) {                             //もし新しいクライアントが接続されていたら
        currentTime = millis();
        previousTime = currentTime;
        Serial.println("New Client.");          //New Client.をシリアル通信出力する
        String currentLine = "";                //clientから入力されるデータの保持用の変数
        while (client.connected() && currentTime - previousTime <= timeoutTime) {  //クライアントが接続されている間のwhileループ
            currentTime = millis();
            if (client.available()) {             //もしクライアントからコマンドが来ている時
                char c = client.read();             //コマンドを読み込む
                Serial.write(c);                    //シリアルモニターに表示
                header += c;
                if (c == '\n') {                    //改行コード(エスケープシーケンス¥n)ならば
                // もし現在の行が空白ならば、この改行コードのみ受け取る
                // つまりHTTPリクエストの終わりなので、レスポンスを返す 
                    if (currentLine.length() == 0) {
                    //HTTPヘッダーはHTTP/1.1 200 OKのようなコードで始まることが多い
                    //コンテントタイプなどの送信
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-type:text/html");
                    client.println("Connection: close");
                    client.println();
            
                    //GPIOのON/OFF制御
                    if (header.indexOf("GET /26/on") >= 0) {
                        Serial.println("GPIO 26 on");
                        output26State = "on";
                        digitalWrite(output26, HIGH);
                    } else if (header.indexOf("GET /26/off") >= 0) {
                        Serial.println("GPIO 26 off");
                        output26State = "off";
                        digitalWrite(output26, LOW);
                    } else if (header.indexOf("GET /27/on") >= 0) {
                        Serial.println("GPIO 27 on");
                        output27State = "on";
                        digitalWrite(output27, HIGH);
                    } else if (header.indexOf("GET /27/off") >= 0) {
                        Serial.println("GPIO 27 off");
                        output27State = "off";
                        digitalWrite(output27, LOW);
                    }
            
                    //htmlページを表示
                    client.println("<!DOCTYPE html><html>");
                    client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                    client.println("<link rel=\"icon\" href=\"data:,\">");

                    // ON/OFFを切り替えるためのCSSを記述(ON = オレンジ/OFF = 灰色)
                    client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
                    client.println(".button { background-color: #FFAA05; border: none; color: white; padding: 16px 40px;");
                    client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
                    client.println(".button2 {background-color: #555555;}</style></head>");
            
                    //H1として『ESP32 Web Server』と出力
                    client.println("<body><h1>ESP32 Web Server</h1>");
            
                    //26ピン状態とON/OFFを表示
                    client.println("<p>GPIO 26 - State " + output26State + "</p>");
                    //output26StateがOFFなら、OFFを表示     
                    if (output26State=="off") {
                        client.println("<p><a href=\"/26/on\"><button class=\"button button2\">OFF</button></a></p>");
                    } else {
                        client.println("<p><a href=\"/26/off\"><button class=\"button\">ON</button></a></p>");
                    } 
               
                    //27ピン状態とON/OFFを表示
                    client.println("<p>GPIO 27 - State " + output27State + "</p>");
                    //output27StateがOFFなら、OFFを表示        
                    if (output27State=="off") {
                        client.println("<p><a href=\"/27/on\"><button class=\"button button2\">OFF</button></a></p>");
                    } else {
                        client.println("<p><a href=\"/27/off\"><button class=\"button\">ON</button></a></p>");
                    }
                    client.println("</body></html>");
            
                    //HTTPレスポンスを改行で終了
                    client.println();
                    //whileルールを終了
                    break;
                } else { //改行コードを取得したら、currentLineをリセット
                    currentLine = "";
                }
                } else if (c != '\r') {  //改行(¥n)以外のコマンドが来た場合
                    currentLine += c;      // currentLineに足す
                }
            }
        }
        //headerをクリア
        header = "";
        //接続を終了
        client.stop();
        Serial.println("Client disconnected.");
        Serial.println("");
    }
}

IPアドレスの確認方法

「ツール→シリアルモニタ」を選択してください。

ESP32_Wi-Fi経由でLED制御3

基板内の『EN』を押します。互換品では『RST』と記載されている場合もあります。

IPアドレスが表示されます。

ESP32_Wi-Fi経由でLED制御5

同じネットワーク(Wi-Fi)に接続したクライアント(スマホ、パソコン、タブレットなど)のブラウザのアドレスバーにIPアドレスを入力すると以下の画面が表示されてESP32を制御できます。

ESP32_Wi-Fi経由でLED制御6

うまし
うまし

よろしければ、サイトやブログでリンクを貼って紹介してもらえると今後のやる気につながります!