物理ボタンをIoT化 – ESP32で Swich bot を自作し、スマホからスイッチをON,OFFできるようにしてみた |じょるブログ

じょるブログ

電子工作やプログラミング関連の情報を発信している技術系ブログ

電子工作 esp32-wifi-module

物理ボタンをIoT化 – ESP32で Swich bot を自作し、スマホからスイッチをON,OFFできるようにしてみた

投稿日:2020年11月17日 更新日:

  

この記事ではESP32をIoTデバイスとして使用し、家の電気のボタンや電子レンジのボタンなどの、あらゆる物理ボタンを押すことのできるスイッチボットを作成する方法について解説します。

市販されているスイッチボットは安いやつでも4000円くらいしますが、ESP32で自作すれば1500円程で作れます!

   

   

ESP32-CAMについて

ESP32-CAM は Arduino と同じように Arduino IDE で開発を行うことができる開発ボードです。

wi-fi, BLE(Bluetooth low energy), カメラが搭載されています。

  

今回作成したもの

今回作成したものは↓こちらです。

ESP32のローカルIPアドレスに特定のURLパラメーターを付けてアクセスする(GETリクエストを行う)ことでサーボモーターを回し、以下のような物理スイッチをON、OFFします。

例えば、スマホから以下のようなURLにアクセスするとモータが回り、スイッチが押されます。

http://192.168.1.111/?angle=50&delay=500&

このURLの?以降の文字がURLパラメーターと呼ばれるものです。

このURLパラメーターを変更することで、モーターを左右に回したり、LEDを付けたりなどの事前に設定した動作を行わせることができます。

   

また、URLパラメーターを付けていないローカルIPアドレス

http://192.168.1.111

にアクセスすると、以下のような画面が表示されます。このボタンを押すことでもESP32を制御できます。

さらにIFTTTと組み合わせることで、AlexaやGoogle Homeを使用して、声で操作することもできます。

   

必要なもの

  • ESP32-CAM
    (今回のメインである格安マイコン)
  • パソコン

 

手順

  1. ESP32-CAMのセットアップ
  2. コードの書き込み
  3. スイッチボット本体の作成

   

①ESP32-CAMのセットアップ

ESP32-CAMのセットアップについては以下の記事で紹介しています。

上記の記事を参考に、Arduino IDE でコードを書き込める状態まで行ってください。

   

②コードの書き込み

Arduino IDE のスケッチを開き、以下のコードを書き込んでください。

//アクセスするときはURLパラメーターの最後に&をつけること!

#include <WiFi.h>

// 使用するWi-Fiとそのパスワードに書き換えてください
const char* ssid     = "abc-2g";
const char* password = "pass";

// ポート80番を使用
WiFiServer server(80);

// HTTPリクエストを格納する変数
String header;

// 値の設定に使用する変数
String valueString = String(5);
String delay_valueString = String(500);
int pos1 = 0;
int pos2 = 0;

//pin
const int servo_pin = 16;

//サーボモーターの回転角
const int servo_left   = 26;
const int servo_center = 75;
const int servo_right  = 123;


void setup() {
  pinMode(4, OUTPUT);
  
  //ledc setting
  ledcSetup(0, 50, 10);  // 0ch 50 Hz 10bit resolution
  ledcAttachPin(servo_pin, 0); // 15pin, 0ch

  //シリアル通信開始
  Serial.begin(115200);

  //起動時にフラッシュライトを点滅させる
  for(int i=0; i<5; i=i+1) {
    digitalWrite(4, HIGH);
    delay(50);
    digitalWrite(4, LOW);
    delay(50);
  }
  
  // Wi-Fiに接続
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // ローカルIPを表示(このIPにスマホなどからアクセスします)
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            

            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" http-equiv=\"content-type\" charset=\"utf-8\"><title>ESP32 servo controller</title>");

            // CSS to style the on/off buttons 
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>.block{display: inline-block; vertical-align: middle; height: 50px; font-size: 0;}");
            client.println(".btn-square-shadow {display: inline-block; width: 300px; height: 50px; text-decoration: none; background: #668ad8; color: #FFF; border-bottom: solid 4px #627295; border-radius: 3px; font-size: 30px;}");
            client.println(".btn-square-shadow:active {-webkit-transform: translateY(4px); transform: translateY(4px);  box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.2);  border-bottom: none;}");
            client.println("</style>");
            client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
            
            // Web Page
            client.println("</head><body style='text-align: center;'><h1>ESP32 サーボモーター コントロールパネル</h1>");
            //servo slide bar
            client.println("<div class='left block'> <a href='http://192.168.2.111/?angle=50&delay=500&'><button id='entrance_button' class='btn-square-shadow' type='button'>玄関の電気</button></a></div>");          
            client.println("<div class='right block'><a href='http://192.168.2.111/?angle=100&delay=500&'><button id='room_button' class='btn-square-shadow' type='button'>部屋の電気</button></a></div>");
            client.println("</body></html>");     


            //HTTPリクエストの処理部分
            delay_valueString = "500";
            pos1 = header.indexOf('=',18);
            pos2 = header.indexOf('&',18);
            if(pos1!=-1 && pos2!=-1) {
              delay_valueString = header.substring(pos1+1, pos2);
              Serial.print("pos:");
              Serial.println(pos1);
              Serial.println(pos2);

            } else {
              Serial.print("defaultサーボ待機時間:");
              Serial.println(delay_valueString.toInt());
            }
            Serial.print("サーボ待機時間:");
            Serial.println(delay_valueString.toInt());

            
            pos1 = header.indexOf('=');
            pos2 = header.indexOf('&');
            valueString = header.substring(pos1+1, pos2);
            Serial.print("URLパラメーター:");
            Serial.println(valueString);


            if(valueString.toInt()>=26 && valueString.toInt()<=123) {
             
              //サーボモーターを回転
              digitalWrite(4, HIGH);
              delay(50);
              digitalWrite(4, LOW);

              
              ledcWrite(0, servo_center);
              delay(delay_valueString.toInt());
              ledcWrite(0, valueString.toInt());
              delay(delay_valueString.toInt());
              ledcWrite(0, servo_center);
              // バグ防止
              delay(delay_valueString.toInt());
              ledcWrite(0, 0);
              
              digitalWrite(4, HIGH);
              delay(50);
              digitalWrite(4, LOW);
             
              
            } else {
              Serial.println("URLパラメーター エラー!");
            }
            

            // HTTPレスポンスの終了
            client.println();
            // Break out of the while loop
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    // Clear the header variable
    header = "";
    // 接続を切断
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

上記のコードのうち、以下の箇所をご自身の環境に合わせて変更してください。

変更箇所補足
6

7
ssid = “abc-2g”;
password = “pass”;
家のWi-FiのSSIDとパスワードに変更
102

103
http://192.168.2.111ESP32に割り振られたIPアドレスに変更

ESP32に割り振られたIPアドレスが分からない方は、一度6~7行目の変更箇所を変更した状態で書き込みをして起動し、Arduino IDEのシリアルモニターを見てみてください。(通信速度は115200bpsに設定してください。)

上記の画像のようにESP32に割り振られたIPアドレスが表示されるので、102~103行目のIPアドレスをこの値に書き変えてもう一度書き込んでください。

   

   

③スイッチボット本体の作成

次にESP32とサーボモーターを接続します。

以下のように接続してください。

ESP32 ピン接続先
5V(左上から1番目)5V電源
GND(左上から2番目)5V電源のグランド
3V3(右上から1番目)サーボモーターの電源
IO16(右上から2番目)サーボモーターの信号線
GND(右上から4番目)サーボモーターのグランド

USBシリアルコンバータを5V電源として使用することもできますが、20㎝ほどの長さしかないため、必要な方は以下のような電源用のケーブルを使用してください。

   

使い方

ESP32を起動するとフラッシュが5回点滅し、1秒ほどで設定したwi-fiに接続されます。

その状態で、以下のようなURLにアクセスするとモーターが動きます。

http://ローカルIPアドレス/?angle=50&delay=500&

angleにはモーターの回転角を指定します。モーターは一度中心位置に動いた後、angleで指定した角度動き、その後また中心位置にモーターが動きます。

※angleで指定できる値はサーボモーターが動ける範囲(23~123)までです。

delayにはモーターが動く間隔を指定します。例えば500とするとモーターが中心位置に動いた後0.5秒待機し、指定した角度にモーターが再び動き、また0.5秒待機した後中心位置に戻ります。

   

応用

IFTTTやBebotteと連携することでAlexaなどを使用して、声でスイッチを押させることもできるようになります。

連携方法についてはまた次回ご紹介します。

   

google ads




google ads




-電子工作, esp32-wifi-module

執筆者:


  1. 楽がしたい貧乏 より:

    初心者すぎてほぼないも分かっていないのですが、最終的にON・OFFはどこで操作すればいいのでしょうか

    • joruji より:

      スマホなどでESP32-CAMのIPアドレスにアクセスすればコントロールパネルが表示されるので、そこで操作できます。
      また、
      http://ローカルIPアドレス/?angle=50&delay=500&
      というように角度やモーターの待機時間を指定してURLにアクセスすることで、直接操作することもできます。

  2. いのしし より:

    もう少し具体的に聞きたいことがあるのですがTwitterかインスタで質問できませんか?

  3. Nehalem より:

    ネットワークに疎いもので…申し訳ありませんが質問させていただきます
    もし外部から操作したい場合はどうすればいいのでしょうか
    接続するURLを自分のグローバルIPにするだけではダメですよね…?

    • joruji より:

      コメントありがとうございます。

      外部のネットワークから接続するには、ルーターの管理画面にアクセスして、ポート開放(ポートフォワーディング)の設定をする必要があります。

      設定の方法はルーターごとに違うので一概に説明することはできないので抽象的な説明となってしまいますが、
      ルーターの説明書を見てポート開放またはポートフォワーディングと書かれた設定項目を探し、手順に沿ってESP32のローカルIPアドレスの80番ポートを指定すればできます。

      設定したら
      {グローバルIPアドレス}:80
      という様にアクセスすれば外出先からアクセスできるようにできます。

      ただ、集合住宅の無料の回線を使用している場合などは、回線が他の部屋の人の回線と共通であることが多いので、ポート開放の設定をしてもできない可能性が高いです。
      自分で回線を契約しているのであれば問題ないです。

  4. George より:

    こちらの記事を元に組み立て・動作させるところまではできたのですが、スイッチに貼り付けるところがうまくいきません。
    どのように固定しているか教えていただけますか?
    よろしくお願いします。

    • joruji より:

      コメントありがとうございます!
      私は強力両面テープを使いました。
      ホームセンターとかで500~1000円くらいで売ってますよ。

      • George より:

        お返事ありがとうございます。
        強力両面テープが家の物置に眠っていたので、それを使ってみようと思います!

  5. しろ より:

    すげー!スイッチボット高いから互換品(クライアントの方)無いかなと探してて通りすがったけど値段云々より内容に見入った。
    コードとURLアクセスで制御する方がロマンあるわー。

joruji へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


関連記事

Alexa, Google HomeをRasberryPiと連携する

この記事ではスマートリモコンを作ってみたで作成した、スマートリモコンをAlexaやGoogle Assistantと連携するために利用した外部サービスについて記載します。     Amazon Ech …

ESP-WROOM-32の基本的な使い方 初期設定や書込み方法、Lチカについて画像付きで徹底解説

  この記事ではESP-WROOM-32の基本的な使い方について解説します。 ESP-WROOM-32は低価格(1000円以下)で買うことができるWiFi/Bluetoothモジュールです。 上の画像 …

AmazonDushボタンを改造してできること- ラズパイやIoT製品との連携方法

AmazonDushボタンはひと手間加えるだけで、IoT製品等の遠隔ボタンとして使用することができます。これにより、スマートロックと連携させダッシュボタンで鍵を開閉したり、スマートリモコンのボタンとし …

ラズパイで取得したIoTデータをグーグルスプレッドシートに自動記録

今回はPythonを使って、ラズパイに接続してあるセンサーから取得したデータなどをグーグルスプレッドシートに自動で記載する方法について記載します。グーグルスプレッドシートに記載することで、スマホなどか …

beebotteでSSL Errorが発生する原因と解決方法

   家で稼働させていた自作のスマートロックとスマートリモコンが昨日から突然動作しなくなってしまいました。 その原因が判明しましたのでここに記載しておきます。     症状 発生した症状としては、be …




関連記事