"お酒" には "おつまみ" が付きものということで、今回はタッチセンサー付きおつまみディスペンサーを IoT 化してみた。
🍶 🍺 🍻 🍷 🍸 🍹 🍾 🥃 + 🍲 🍔 🌭 🌮 🌯 🍕 🍖 🍗 🍙 🍛 🍜 🍝 🍢 🍣 🍚
キャンディ・ディスペンサーとか、おつまみディスペンサーとか、オートディスペンサーなどの検索キーワードで出てくる製品で、以下2つの製品を入手して分解したところ同じ基盤・部品・配線で実装されていたので、同じ仕組みでイケると思う。
構成
スマートスピーカー (Google Home または Amazon Alexa) を入力として、Node-RED を経由して webhook リクエストを MQTT リクエスト (Publish) へ変換し、Milkcocoa 経由でおつまみディスペンサーへ MQTT リクエスト (Subscribe) を送る構成とした。音声入力の内容によって Node-RED からの MQTT リクエストの内容を変更して、おつまみディスペンサーへのリクエストを振り分ける構成とした。
分解
本製品は中身 (おつまみ) を入れ替えるので基本的に分解して洗えるようになっている。
ケース、トレイ、回転体を取り外し、3本のネジをプラスドライバーで外すと基盤、モーター、タッチセンサーへアクセスできる。
台座は裏面の滑り止め (スポンジ) を取り外すと4本のネジが現れ、プラスドライバーで外すと電池ボックス、スライドスイッチへアクセスできる。
配線図
基盤に搭載されているシングルチャネルタッチセンサースイッチのチップの仕様はこちら。(仕様書)
既存のタッチセンサー機能を活かしつつ、リモート操作が可能となるよう、Wio-Node で MOS-FET のゲート電圧を操作することでモーターの陰極 (−) をスイッチングさせる配線とした。MOS-FETは定番の 2SK2232(60V25A) の入手が困難となったため、代替品として 2SK4017(60V5A) または 2SK703(100V5A) を使用した。
また、Wio-Node の電源は既存の電源ボックスから供給し、スライドスイッチで ON/OFF できる配線とした。
中蓋を取り外したあと、基盤 (基盤を止めているネジ付近) へ1本リード線をハンダ付けし、脚筒を通して台座の裏面へ配線する。
・モーターの陰極 (−) を制御するため基盤へハンダ付けし台座の裏面へ配線したリード線を MOS-FET (ドレイン) へ接続し、電池ボックスの陰極 (−) から MOS-EFT (ソース) へ接続し、Groveコネクタ (黄色のリード線) を抵抗 (220Ω) を挟んで MOS-FET (ゲート) へ接続する。
Wio-Node へ電源供給するための PH2 コネクタの陰極 (−) を電池ボックスへ、陽極 (+) をスライドスイッチへ接続する。
ソースコード
Wio-Nodeのソースコードはこちら。
#include <ESP8266WiFi.h>
#include <Milkcocoa.h>
#define WLAN_SSID "" // Wi-Fi
#define WLAN_PASS "" // Wi-Fi
#define MOTORPIN 5 // Wio-Node IO5 => MOTOR, NodeMCU D1=GPIO5 D6=GPIO12
#define DEVICEID 1 // if selector is 0, MOTOR works in 0.1 second for health check purpose.
// if selector is DEVICEID, MOTOR is switched on during timer. if NOT, MOTOR doesn't work.
WiFiClient client;
#define MILKCOCOA_APP_ID "" // MilkCocoa Application ID
#define MILKCOCOA_DATASTORE "" // MilkCocoa Datastore Name
#define MILKCOCOA_SERVERPORT 1883
const char MQTT_SERVER[] PROGMEM = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] PROGMEM = __TIME__ MILKCOCOA_APP_ID;
Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);
int red, green, blue, selector, timer;
void onpush(DataElement *elem) {
Serial.println("onpush");
Serial.print("r:");
Serial.print(elem->getInt("r"));
Serial.print(",g:");
Serial.print(elem->getInt("g"));
Serial.print(",b:");
Serial.print(elem->getInt("b"));
Serial.print(",s:");
Serial.print(elem->getInt("s"));
Serial.print(",t:");
Serial.print(elem->getInt("t"));
Serial.println();
red = elem->getInt("r");
green = elem->getInt("g");
blue = elem->getInt("b");
selector = elem->getInt("s");
timer = elem->getInt("t");
if (selector) {
if (selector == DEVICEID) {
digitalWrite(MOTORPIN, HIGH);
delay(timer * 1000);
digitalWrite(MOTORPIN, LOW);
}
} else {
digitalWrite(MOTORPIN, HIGH);
delay(100);
digitalWrite(MOTORPIN, LOW);
}
}
void setupWiFi() {
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void setup() {
pinMode(15, OUTPUT); // for Wio-Node
digitalWrite(15, 1); // for Wio-Node
Serial.begin(115200);
setupWiFi();
Serial.println( milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush) );
pinMode(MOTORPIN, OUTPUT);
}
void loop() {
milkcocoa.loop();
}
まとめ
現在構想中の IoT 居酒屋 (仮) の実現に向けて一歩でも近づければ幸いです。