カーテンの開閉
今回は、いよいよ、みんなが1回はやりたくなる?カーテンの開閉です。
前回はSwitchBot風にお風呂のスイッチをサーボで押すのを作りました。
https://qiita.com/ABK28/items/0681be13afca40687dff
基本的にはこのソースをベースにしていますが、前回の課題であった、DHCPで付与された自分のIPアドレスを知るために、Google Home NotiferでIPアドレスを喋らせることにし、mDNSでWEBでもアクセスできるようにしました。(下記参照)。
↓
https://qiita.com/ABK28/items/1672fe26837c364a8de3
カーテンはタミヤのラダーチェーンで引っ張ります。
アイデアは下記から拝借しました。ありがとうございます。
↓
https://cadottie.hatenadiary.org/entry/20110329/1301373783
使ったもの
・ESPr Developer (Switch Science製)
・モータードライバ(HiLetgo L9110S)(Amazonで購入)
・タミヤ ミニモーター低速ギヤボックス(yodobashiで購入)
・タミヤ ラダーチェーン&スプロケットセットを2セット(yodobashiで購入)
・Arduino IDE
・ESP8266ライブラリ
・fauxmoESPライブラリ
・Google Home Notiferライブラリ
・ダイソーの糸ようじの空箱
・木板(ダイソーで購入)
・プラ版(ダイソーで購入)
・ジャンパー線
・両面テープ(強力で剥がせるやつ。ホームセンターで購入)
参考URL
前回同様下記を参考にさせていただきました。
https://homemadegarbage.com/espalexa04
https://www.pentacreation.com/blog/2017/08/170822.html
http://okiraku-camera.tokyo/blog/?p=3426
さらに、Google Home Notiferで喋らせる方法
https://qiita.com/horihiro/items/4ab0edf415916a2cd542
https://www.mgo-tec.com/blog-entry-google-home-notifier-m5stack-esp32.html
と、IPアドレスを喋らせるための文字列変換
https://qiita.com/dojyorin/items/ac56a1c2c620782d90a6
のソースを拝借させていただきました。ありがとうございます。
工作
今回は、こっちが大変かも。
ギアボックスの組み立て
一番遅いギア比で組み立て。ちょっと遅すぎたかも・・
ラダーチェーンの組み立て
地道につなぎます・・。
1セットで90cmくらいだったので、2セット使いました。ちょっと足らなかったですが・・。
片端は木板につけます。
箱に収める・・
ダイソーの糸ようじの空き箱に、まるっと収めます。
材質が柔らかいので、ピンバイスやキリで穴をあけたり、ハサミで切っちゃったり・・・。
また、取り外しを考えてプラ版にビスをつけベースとします。収めた箱と連結できるようにしました。
配線は下記の通りにしました。
・ESPrDeveloperの04ピン =モータドライバのA-1Aピン
・ESPrDeveloperの05ピン =モータドライバのA-1Bピン
・モータドライバのVCCピン=ESP8266の3V3ピン
・モータドライバのGNDピン=ESP8266のGNDピン
・モータドライバAのプラスマイナス=モータのプラスマイナス
カーテンへの取り付け
・場所を考えて、ベース(プラ版)と片端木版の裏に両面テープをつけてカーテンレールに取り付けます。
・チェーンをつけます。
アレクサに登録
前述のお風呂スイッチの投稿を参照ください・・。
使い方
オンオフスイッチ型なんで、少し変ですが、下記のようになります。
「アレクサ!、カーテンをオン!」
「アレクサ!、カーテンをオフ!」
又は、
curtain-web.local:8080/cmd
で・・
ソース
# include <ESP8266WiFi.h>
# include <ESP8266WebServer.h>
# include <fauxmoESP.h>
# include <esp8266-google-home-notifier.h>
# define SERIAL_SPEED 115200
// Pin No
const int MotorFwdPin = 4;
const int MotorRevPin = 5;
// WiFi
const char* ssid="あなたのSSID";
const char* password="あなたのパスフレーズ";
// Google Home
GoogleHomeNotifier ghn;
const char displayName[] = "あなたのデバイスネーム";
String mes;
// Alexa
fauxmoESP fauxmo;
int CurtainFlag = 0;
# define ID_sw "カーテン"
// Web page (Port 8080)
ESP8266WebServer server(8080);
static const char* cpResponse200 = "<HTML>"
"<BODY style='background-color:#ffffde;font-family:sans-serif;font-size:32px;'>"
"Curtain Control Web<br/><br/><br/>"
"<a href=/cmd?POS=stop>Stop</a><br/>"
"<a href=/cmd?POS=fwd_always>Forword Always</a><br/>"
"<a href=/cmd?POS=rev_always>Reverse Always</a><br/>"
"<a href=/cmd?POS=fwd_10>Forword 10 sec.</a><br/>"
"<a href=/cmd?POS=rev_10>Reverse 10 sec.</a><br/>"
"<a href=/cmd?POS=fwd_1>Forword 1 sec.</a><br/>"
"<a href=/cmd?POS=rev_1>Reverse 1 sec.</a><br/>"
"</BODY></HTML>\r\n";
void setup() {
Serial.begin(SERIAL_SPEED);
Serial.println("");
// Motor
pinMode(MotorFwdPin, OUTPUT);
pinMode(MotorRevPin, OUTPUT);
digitalWrite(MotorFwdPin, LOW);
digitalWrite(MotorRevPin, LOW);
// WiFi
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,password);
while(WiFi.status() != WL_CONNECTED){
delay(300);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
// Google Home Notifer
mes = "カーテンマシンのIPアドレスは、";
mes += ipToString(WiFi.localIP());
mes += "です。";
googleHomeConnection( "ja", mes.c_str() );
// mDNS
if (!MDNS.begin("curtain-web")) {
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// WebServer
server.on("/cmd", WebCommand);
server.begin();
Serial.println("Web Server started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 8080);
// Alexa
fauxmo.createServer(true);
fauxmo.setPort(80);
fauxmo.enable(true);
fauxmo.addDevice(ID_sw); // Add virtual devices
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
if (strcmp(device_name, ID_sw)==0) {
if (state) CurtainFlag = 1;
else CurtainFlag = 2;
}
});
}
void WebCommand() {
String cmd = server.arg("POS");
if (cmd == "stop") MotorOff();
else if (cmd == "fwd_10") MotorFwd(10000);
else if (cmd == "rev_10") MotorRev(10000);
else if (cmd == "fwd_1") MotorFwd(1000);
else if (cmd == "rev_1") MotorRev(1000);
else if (cmd == "fwd_always") MotorFwd(0);
else if (cmd == "rev_always") MotorRev(0);
Serial.println("cmd=" + cmd);
server.send(200, "text/html", cpResponse200);
}
void loop() {
// fauxmoESP uses an async TCP server but a sync UDP server
// Therefore, we have to manually poll for UDP packets
MDNS.update();
server.handleClient();
fauxmo.handle();
if (CurtainFlag==1) { MotorFwd(60000); CurtainFlag=0; }
else if (CurtainFlag==2) { MotorRev(60000); CurtainFlag=0; }
}
void MotorFwd(int d) {
Serial.println("FWD Start " + String(d) );
digitalWrite(MotorRevPin, LOW);
digitalWrite(MotorFwdPin, HIGH);
if (d>0) { // if d<=0 then always ON !
delay(d);
digitalWrite(MotorFwdPin, LOW);
}
}
void MotorRev(int d) {
Serial.println("REV Start " + String(d) );
digitalWrite(MotorFwdPin, LOW);
digitalWrite(MotorRevPin, HIGH);
if (d>0) {
delay(d);
digitalWrite(MotorRevPin, LOW);
}
}
void MotorOff() {
Serial.println("Moter Off ");
digitalWrite(MotorFwdPin, LOW);
digitalWrite(MotorRevPin, LOW);
}
String ipToString(uint32_t ip){
String result = "";
result += String((ip & 0xFF), 10);
result += ".";
result += String((ip & 0xFF00) >> 8, 10);
result += ".";
result += String((ip & 0xFF0000) >> 16, 10);
result += ".";
result += String((ip & 0xFF000000) >> 24, 10);
return result;
}
void googleHomeConnection( String lang_str1, String talk_str1 ){
Serial.println("connecting to Google Home...");
if (ghn.device( displayName, lang_str1.c_str() ) != true) {
Serial.println(ghn.getLastError());
return;
}
Serial.print("found Google Home(");
Serial.print(ghn.getIPAddress());
Serial.print(":");
Serial.print(ghn.getPort());
Serial.println(")");
if (ghn.notify( talk_str1.c_str() ) != true) {
Serial.println(ghn.getLastError());
return;
}
Serial.println("");
}