作ろうとしたきっかけ
僕自身非常にめんどくさがり屋で、スイッチをつけたら切るのが非常に面倒になって電気つけっぱなしで寝てしまうことが多いのです。
なので、その対策のためいろいろ探してたところ、switchbotってものをYouTubeで発見!!
一瞬で、これ欲っしい!!となったわけなのですが、値段が随分と高い...
Switch Bot ボタンを押してくれる超小型指ロボット (ワイヤレス / スイッチボット)
お値段1個、¥4,480
物理スイッチが多い僕の家では、これを何個も買わなくてはならず、これ何個も買ってたら総額何十万も行きそうなので、自作するしかないという結論に至りました。
必要物
・ESP8266 NodeMcu基板
https://bit.ly/2YxRavZ
※ヤフオクとかで探せば同型機が結構探せます。
・microサーボ
http://akizukidenshi.com/catalog/g/gM-08761/
これだけ!!
僕は全部Aliexpressで購入したので500円行きませんでした。超激安です!!
MQTT対話サーバーの準備
まずは、↓MQTTサーバーとして、これに登録します。
https://www.adafruit.com/
とりあえず、すぐ登録できると思うので、登録出来たら
IOのところをクリックしてください。
クリックしたら、次は「Feed」をクリックして、必要な項目を追加していきます。
Actionから、Create a New Feedをクリックします。
Create a New Feed でonoffと、
LightsStatusを作ります。
それができたら、次は表示部分を作っていきます。
クリックしたら上のほうにこんなアイコン軍があるので、LEFTから3個目の水色の「+」アイコンをクリックして、ブロックを追加します。
選択すると、FEEDを選んでくださいね画面になるので、onoffを選択して、次へ進みます。
あとは、APIトークンを取得しなければならないので、ダッシュボードのメニューから
View AIO Keyをクリックしてください。
クリックしたらアクティブキーなどが表示されるので、
Usernameと、Active Keyをどこかにコピーしておいてください。
ここまでくれば、ほぼ設定は完了です。
マイコンの配線
コードの書き込み
まず、Usernameと、Active Keyなどを合わせて設定します。
まず初めにWIFI定義のところにある、自分の家のアクセスポイントのSSIDとパスワードを記載します。
【書き換えるところ】
define WIFI_SSID ←アクセスポイントの名前
define WIFI_PASS ←アクセスポイントのパスワード
define MQTT_NAME ←AdafruitのUSERNAME
define MQTT_PASS ←Adafruitのアクティブキー
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
//サーボモーターを制御するためのライブラリをインクルード
#include <Servo.h>
//WIFI定義
#define WIFI_SSID "SSID"
#define WIFI_PASS "*********"
#define MQTT_SERV "io.adafruit.com"
#define MQTT_PORT 1883
#define MQTT_NAME "USERNAME"
#define MQTT_PASS "PASS***"
//任意のサーボモータークラスを用意。
Servo servo1;
int val;
int state=0;
int led = D7;
MQTTの設定は下記で定義します
AdafruitのFeedで設定した項目がこちらに設定されています。
//MQTTの設定
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);
Adafruit_MQTT_Subscribe onoff = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/onoff");
Adafruit_MQTT_Publish LightsStatus = Adafruit_MQTT_Publish(&mqtt, MQTT_NAME "/f/LightsStatus");
//初期セットアップ
void setup()
{
//COMのシリアルスピード設定
Serial.begin(9600);
//デジタル4番ピンをサーボモーターの出力ピンとして設定
servo1.attach(4);
servo1.write(150);
pinMode(14,OUTPUT);//LED
//WIFIに接続する
Serial.print("\n\nConnecting Wifi>");
WiFi.begin(WIFI_SSID, WIFI_PASS);
digitalWrite(LED_BUILTIN, LOW);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(">");
delay(50);
}
//接続できたとき
Serial.println("OK!");
//onoffへ要求を出します。
mqtt.subscribe(&onoff);
}
//サーボ定義(オン)の時
void on(void){
//スイッチを消すときの処理
servo1.write(200);
delay(500);
servo1.write(150);
}
//サーボ定義(オフ)の時
void off(void){
//つけるときの処理
servo1.write(150);
delay(500);
servo1.write(90);
delay (500);
servo1.write(150);
}
//ループ処理
void loop()
{
//MQTTに接続する
MQTT_connect();
//不足するまでサブスクリプションキューから読み取る
//サブスクリプションが更新されるまで最大5秒間待機
Adafruit_MQTT_Subscribe * subscription;
while ((subscription = mqtt.readSubscription(5000)))
{
//要求が完了したか判定
if (subscription == &onoff)
{
//更新値をシリアルモニタに表示
Serial.print("onoff: ");
Serial.println((char*) onoff.lastread);
//更新値が "ON"の場合は、ライトを点灯
//それ以外の場合はオフに
if (!strcmp((char*) onoff.lastread, "ON"))
{
//点灯
on();
LightsStatus.publish("ON");
}
else if (!strcmp((char*) onoff.lastread, "OFF"))
{
//消灯
off();
LightsStatus.publish("OFF");
}
else
{
LightsStatus.publish("ERROR");
}
}
else
{
//LightsStatus.publish("ERROR");
}
}
//テスト
// if (!mqtt.ping())
// {
// mqtt.disconnect();
// }
}
void MQTT_connect()
{
// Stop if already connected
if (mqtt.connected() && mqtt.ping())
{
// mqtt.disconnect();
return;
}
int8_t ret;
mqtt.disconnect();
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) // connect will return 0 for connected
{
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0)
{
ESP.reset();
}
}
Serial.println("MQTT Connected!");
}
取り付け後のイメージはこんな感じです。
一応Switchbotの動作を見て作ったのでオフもできるのですが、消灯する時はサーボが持ち上がる動作のためSwitchbotのように何か両面テープで貼り付けてサーボで物理スイッチを持ち上げる物理的工夫が必要です。
もし、物理的に持ち上げる工夫をされた方、是非やり方教えてください。
次回は、これをIFTTTでGoogleホームと連携できるようにします!!