物理ボタンを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

執筆者:


comment

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

CAPTCHA


関連記事

Google Apps Scriptを使用してスプレッドシート上の図形を押した際に、プログラムを実行させる

    大学生の電子工作 ラズパイでスマートロック作ってみた⑤の記事に関連して、スプレッドシート上に設置したボタンを押した際に Google Apps Scriptを用いたプログラムを実行することで、 …

壊れたイヤホンを半田ごてを使って直してみた – 修理方法解説

   長年使用していたイヤホンが壊れてしまったので、半田ごてを使用して直してみました。この記事ではイヤホンの直し方について解説します。 (イヤホンの構造によって多少直し方は異なる場合があります。) 今 …

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

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

RaspberryPiのセットアップ ② – SSH,VNC(遠隔操作)の設定とファイルサーバーの設定

 この記事では、前回の記事(RaspberryPiのセットアップ ① – 2種類のOSインストール方法と基本設定)に引き続き、ラズパイを遠隔操作するためのSSH・VNCの設定方法と、パソコ …

Alexa, Google HomeをRasberryPiと連携する

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




関連記事