今回はESP32を使ってガレージのシャッターを開閉するスマートロックを自作しました。
製作費用は2000円と激安でアルディーノのプログラムを少し勉強すれば誰でも作ることが可能です。
配線方法やサーボモーター動作原理、プログラムの解説も行っています。
ぜひ、最後までご覧ください。
ESP32で自作スマートロックの製作理由
スマートロックを作った理由はガレージのリモコンを持ち歩くのが嫌だったからです。
ガレージのシャッターは電動で専用のリモコンで操作します。
バイクに乗る時はリモコンも一緒に持ち歩かないといけないので荷物が増えます。
荷物が増えると紛失の可能性も高くなるので、スマホからwifi経由で操作できるようにしてみました。
ESP32で自作スマートロック 準備したもの
まずはスマートロックを自作するために用意したものを紹介します。
ESP32のマイコンモジュール
これはAmazonで800円ほどで売っています。
Arudinoのプログラム編集ソフトで、プログラムが編集できます。
さらにwifiとBluetoothのモジュールも入っています。
今回はESP32のwifiの機能を使ってスマホから操作できるようにしました。
SG90サーボモーター
ESP32の指令に対して動作するのはSG90のサーボモーターです。
これもAmazonで500円くらいで手に入ります。
動作用のアームも付属品を使います。単体で買うと入っていない可能性もあるので注意が必要です。
ちなみにこれはArudino勉強用に買ったセットに付属していたモーターです。
ジャンパー線
モーターとESP32を接続するための配線です。
ハンダつけをすれば必要ないですが、今後バージョンアップする可能性もあるため今回はジャンパー線で接続します。
ESP32、サーボモーター自作ホルダー
サーボモーターとESP32を固定するためにホルダーを3Dプリンターで自作しました。
両面テープで固定する予定ですが、これは見栄えとしっかりと固定するために出来るだけシンプルに作りました。
なお、直接貼り付けできればこれは要らないです。
最後にスマホです。
ESP32 スマートロックの配線図
それでは早速、作っていきます。
まずは配線です。
配線は非常にシンプルです。
ESP32のP18番にサーボモーターのオレンジ色のPWM線を接続します。
ESP32の3.3V(一番上のオレンジ)にサーボモーターの赤色の電源を接続。
ESP32のGND(一番上の黒)にサーボモーターの茶色マイナスを接続します。
これで完成です。
ESP32 スマートロックのアルディーノプログラム
実際に作ったプログラムがこちらです。
//アクセスするときはURLパラメーターの最後に&をつける。
#include <WiFi.h>
// 使用するWi-Fiとそのパスワードに書き換えてください
const char* ssid = "**********";
const char* password = "***********";
// ポート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 = 18;
//サーボモーターの回転角
//-90° 0.5ms パルス0.5ms*1024(10ビットの値)/20ms=25.6
//0° 1.45ms パルス1.45ms*1024(10ビットの値)/20ms=74.24
//90° 1.45ms パルス2.4ms*1024(10ビットの値)/20ms=122.88
const int servo_left = 26;
const int servo_center = 74;
const int servo_right = 123;
void setup() {
//シリアル通信開始
Serial.begin(115200);
//ledc setting
ledcSetup(0, 50, 10); // 0ch 50 Hz 10bit PWMの範囲は0~1023
ledcAttachPin(servo_pin,0); // 18pin, 0ch
// 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>ガレージの開閉</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>body{ text-align: center;}");
client.println(".btn{display: inline-block; width: 300px; height: 100px; text-decoration: none; background: #668ad8; color: #FFF; border-bottom: solid 4px #627295; border-radius: 3px; font-size: 30px;}");
client.println(".btn: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>ガレージのシャッター</h1>");
//servo slide bar
client.println("<div class='left block'> <a href='http://***.***.***/?angle=50&delay=500&'><button id='entrance_button' class='btn' type='button'>OPEN</button></a></div><p></p>");
client.println("<div class='right block'><a href='http://***.****.****/?angle=100&delay=500&'><button id='room_button' class='btn' type='button'>CLOSE</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("");
}
}
プログラムを0からプログラムを作るには初心者にはハードルが高いです。
自分は初心者なので、まずは人が作ったプログラムを丸コピーして、アレンジしたいところのコードを調べながら追加と修正をしました。
ESP32でWifiの接続
ESP32をwifiに接続するためには無線LANのssidとパスワードが必要です。
こちらは無線LANの本体に記載されているのであらかじめ控えておき、プログラムに入力します。
プログラムのconst char*にwifiのssidとパスワードを入力。
ESP32でサーボモーター
サーボPINは18番にサーボの信号線を接続します。
サーボ角度の変更ですが、-OPENで-90度、COLSEで90度動くように設定しています。
もし角度を変更したい場合は、26や123の数字を変更します。
26、123の数字はどっから出てきたのか?
少し詳しく解説していきます。
まずはプログラムで角度を指令するために Void setup内にledSetup関数で、pwmの設定をします。
左の0がチャンネルの設定
真ん中の50が周波数の設定。ここではサーボの周期が50HZなので50に設定。
右の10が解像度の設定。今回は10bitに設定。10^10なのでPWMの範囲は0から1023になります。
次にledcAttachPin関数で、先ほどのチャンネルのピン番号を設定します。
今回はピン番号18に設定しました。
サーボモーターのPWM制御
いよいよ本題です。
これはSG90のデータシートです。
サーボへの信号はデジタル信号です。
デジタル信号はONとOFFしか出力することができません。
ONの時間を調整することでモーターの回転角度を制御することができます。
これがデューティーサイクルですね。
SG90のサーボモーターの場合、PWMの周期は50HZ。秒に換算すると20msです。
-90°に回転する場合は次のようになります。
パルスが0.5msの時に-90度サーボが動きます。
パルスとは1周期に対するONが締める時間の割合。
パルス0.5(mmsec)×10(ビットの値は1024)÷20(mmsec)=25.6
同じように計算することで、0°は75、+90°は123になります。
26から123の間の数字を変えると任意の角度に変わります。
ESP32のウェブページのデザインを変更する
ウェブページのボタンの配置やデザインはclient.println関数でHTMLとCSSでデザインしました。
ウェブページのタイトルを変更したい場合はh1タグの中身を変更します。
ボタンの表示はリンク内の中身を変更します。
ESP32のプログラムの書き込み
プログラムが出来たら検証(コンパイル)を押してプログラムに間違いがないか確認します。
検証が出来たらESP32とパソコンをつないで、プログラムを書き込みします。
ここでひとつ注意が必要です。
マイクロUSBが安物だとパソコンがESP32を認識してくれませんでした。
もし認識しない場合はスマホの純正ケーブルを使うなど通信ができるケーブルに変更します。
書き込み中も通信がCONNECTING中と表示がでたらESP32のブートボタンを押し続けます。
これしないと書き込みができません。
書き込みが出来たらツールのシリアルモニターからIPアドレスをメモします。
メニューの「ツール」→「シリアルモニタ」からシリアルモニターを開きます。
表示されていない場合は、ESP32をリセットします。
文字化けしている場合は、右下のbpsを115200に変更してみます。
このIPアドレスがウェブページのURLになります。
スマホのブラウザからIPアドレス入力するとシャッター開閉ページが表示されるはずです。
iPhoneで自作スマートロック動作確認
まずは机上で動作確認します。
動きに問題がないことが確認できたら、いよいよガレージに取り付けします。
給電は100V電源からUSBケーブルで確保。
取り付けはすべて両面テープで取り付けです。
両面テープは3Mの両面テープが強力でおすすめ!!
無事にスマホから遠隔操作することができました。
コメント