前回の続きです。
https://qiita.com/llight/items/35c762179826c31b827f
今回は
⑶ 物理スイッチを作成して鍵の施錠を行う
です。
TL;DR
私の場合は賃貸なので施錠する必要がある場所は2つ。
(A)建物
こちらは部屋番号を受付で押して、家にある施錠ボタンをラズパイにつなげたモーターで施錠します。
(B)部屋
こちらはESP32を使用して、サーバーを立てて、モータの強いトルクで回転させます。
必要なもの
建物の施錠
(a)ラズパイ上にサーボモータを動かすプログラムmotor.pyを作成
(b)前回の記事で書いたラズパイのサーバーでmotor.pyを実行する。
参考までにソースコード
# coding: utf-8
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
gp_out = 24 #ここでPWMに使用するGPIOを指定
GPIO.setup(gp_out, GPIO.OUT)
# GPIO.PWM( [ピン番号] , [周波数Hz] )
# SG92RはPWMサイクル:20ms(=50Hz), 制御パルス:0.5ms〜2.4ms, (=2.5%〜12%)。
servo = GPIO.PWM(gp_out, 50)
# パルス出力開始。 servo.start( [デューティサイクル 0~100%] )
# とりあえずゼロ指定だとサイクルが生まれないので特に動かないっぽい?
servo.start(0)
# time.sleep(1)
# デューティサイクルの値を変更することでサーボが回って角度が変わる。
servo.ChangeDutyCycle(2.5) #-90度
time.sleep(0.5)
servo.ChangeDutyCycle(12) # 90度
time.sleep(0.5)
servo.stop()
GPIO.cleanup() #ラズパイのwsgiで実行するにはos.system('sudo python3 motor.py')とかで大丈夫。
部屋の施錠
ESP32をArudino IDEで書き込む。
以下参考に
# include <WiFi.h>
# include <ESPmDNS.h>
# include <WiFiClient.h>
# include <ESP32Servo.h>
const char* ssid = "" //ここはご自身の環境で。ちなみに2.4ghzしか対応していません。
const char* password = ""
//Servo
Servo servo;
int servoPin = 2;
int pos = 0; // position in degrees
// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);
void setup(void)
{
Serial.begin(115200);
// Connect to WiFi network
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Set up mDNS responder:
// - first argument is the domain name, in this example
// the fully-qualified domain name is "esp8266.local"
// - second argument is the IP address to advertise
// we send our IP address on the WiFi network
if (!MDNS.begin("esp32")) {
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// Start TCP (HTTP) server
server.begin();
Serial.println("TCP server started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
//Servo
servo.setPeriodHertz(50); // Standard 50hz servo
servo.attach(servoPin);
}
void loop(void)
{
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
String s;
if( req == "/O"){
if (servo.read() == 0){
servo.write(90); //90度に回転
delay(20000); // 20秒後に
servo.write(0); // オートロック
delay(2000);
s = "END";
}else{
servo.write(0);
delay(2000);
s = "RETURN";
}
}
else
{
Serial.println("Sending 404");
Serial.println("N");
}
Serial.println(s);
client.print(s);
client.stop();
Serial.println("Done with client");
}
これでhttp://esp32.local/O
にアクセスするとサーボが動きます。
ラズパイ側のwsgiでwget http://esp32.loacal/Oを実行させればおk
一応ESP32のDNSサーバに問い合わせるため時間が少しかかります。
直接http://ESP32にローカルIP/O
としたほうが私の環境では5秒速かったです。
配線は
DC電源(+)→MG996R(VCC)
DC電源(-)→MG996R(GND) → ESP32(GND) (ブレッドボードで直列につないでください)
ESP32(D2) → MG996R(PWM)
次回
⑷ エアコンの信号を解析してエアコンも操作