ドリンクディスペンサーを IoT 化してみた。

今回は"お酒" を注いでもらうために、各種ドリンクディスペンサーを IoT 化してみた。

🍶 🍺 🍻 🍷 🍸 🍹 🍾 🥃　＋　🍲 🍔 🌭 🌮 🌯 🍕 🍖 🍗 🍙 🍛 🍜 🍝 🍢 🍣 🍚

・Vinaera 電動ワインディスペンサー [VN-014]
・電動ドリンクディスペンサー [小便小僧]
・電動ドリンクディスペンサー [マーライオン]
・グラスドリンクディスペンサー

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/f4cd473f-a821-2b24-ae52-c5b350df6769.png" width="25%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/49abb5eb-8bec-ceff-ede8-8b675730c95d.png" width="20%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/74980c98-11e6-f849-a0bc-8caf56582da2.png" width="20%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/ce76b56a-1aa8-bf2f-bf54-1c7d3afc3ef5.png" width="30%">

### Vinaera 電動ワインディスペンサー [VN-014]
Vinaera は液体吐出器として特許 <A HREF="https://astamuse.com/ja/published/JP/No/2009073519">特開2009-073519</A> の機構が含まれる。装置上部のボタン[30]が電動ポンプ (加圧装置) の電源スイッチ (ON/OFF) と封圧の役割を持っており、ボタンを押すと電動ポンプの電源が入り、容器ボトル内が加圧され、液吐出管経由[81]でボトル内の液体が外部に吐出される。ボタンを離すと電動ポンプの電源が切れ、容器ボトル内が解圧され、液体の吐出が止まる仕組みとなっている。また、吸入管[91]の途中に切れ込み[111]が入っており、切れ込み口から空気が吸入され、ワインのエアレーションが行われる。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/9b75d01f-fcfc-3941-3c74-c54101bc4bb4.png" width="30%"> 

### 電動ドリンクディスペンサー [小便小僧] / 電動ドリンクディスペンサー [マーライオン]
マーライオンと小便小僧は基本的に同じ構造で、容器ボトル内の液体を直接吸引して外部に吐出する仕組みとなっている。
<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/028f66fa-e22e-3e05-bd76-722cd7b2dcf3.png" width="30%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/a49535f2-4085-f97e-ede8-467fb2808eb3.png" width="34%">

### グラスドリンクディスペンサー
グラスドリンクディスペンサーは手動で蛇口を開ける仕組みとなっているため、外部に開放装置を取り付ける必要がある。

## 構成
スマートスピーカー (Google Home または Amazon Alexa) を入力として、Node-RED を経由して webhook リクエストを MQTT リクエスト (Publish) へ変換し、Milkcocoa 経由でおつまみディスペンサーへ MQTT リクエスト (Subscribe) を送る構成とした。音声入力の内容によって Node-RED からの MQTT リクエストの内容を変更して、おつまみディスペンサーへのリクエストを振り分ける構成とした。

![のみものIoT構成・配線図.png](https://qiita-image-store.s3.amazonaws.com/0/72479/6d0ae3db-e93a-8687-efb0-c53911112930.png)

## 分解
### Vinaera 電動ワインディスペンサー [VN-014]
外側のカバーを外すと単三電池 (AAバッテリー) を 6本入れるスペースがある。上部の 3本のネジをプラスドライバーで外すとカバーが外れ、封圧兼電源ボタンが外れる。さらに 2本のネジをプラスドライバーで外すと電源ポンプ (加圧装置) にモーター (RF-370CA-18250: 12V 7800 U/min, 300mA) が使用されていることを確認することができる。配線を確認すると、電源ボタンが押下されると電源のプラス端子が接続され、モーターが動作しLEDが点灯するシンプルな回路である。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/f742da9c-f93f-a772-396d-2c1b70be3603.png" width="60%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/2428f292-6177-1195-68f5-83e63ca77287.png" width="33%">

前回 <A HREF="https://qiita.com/kitazaki/items/db137536d4ce3f0cc3b8">おつまみディスペンサー</A> で使用した N チャネル MOS-FET (2SK4017(60V5A) または 2SK703(100V5A)) を流用するため、電源ボタンが押下されると電源のマイナス端子が接続される配線へ変更した。また、モーターは電源 9V (1.5V x 6本) で駆動しているが、Wio-Nodeの電源としては入力電圧を超えているため、6V (1.5V x 4本) を使用する。Grove ケーブルの黄色のリード線を MOS-FET (ゲート) へ、赤色のリード線を 6V プラス端子へ、黒色のリード線をマイナス端子へ接続し、Wio-Nodeへ接続する Grove コネクタをカバー上部の穴から外へ引き出した。封圧部分はグルーガンで仮塞いだ。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/6ae39253-cf29-0eed-5b5d-986262ff8cbf.png" width="50%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/764df89d-1cf9-84dd-1782-1dc690291249.png" width="40%">

### 電動ドリンクディスペンサー [小便小僧] / 電動ドリンクディスペンサー [マーライオン]
4本のネジをプラスドライバーで外すとカバーが外れ、ボタンを押下すると単三電池 (AAバッテリー) 2本 (3.0V = 1.5V x 2本) でモーター (RE-280) を動作させるシンプルな回路を確認することができる。Wio-Nodeの電源としては入力電圧が不足しているため、電源を単四電池 (AAAバッテリー) 3本 (4.5V = 1.5V x 3本) へ変更する。また、モーターの陰極 (−) を制御するため白色のリード線を MOS-FET (ドレイン) へ接続し、電池ボックスの陰極 (−) から MOS-EFT (ソース) へ接続し、Groveコネクタ (黄色のリード線) を MOS-FET (ゲート) へ接続する。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/c2b745f8-758f-c716-006f-cfbb5ec8876a.png" width="60%"> <img src="https://qiita-image-store.s3.amazonaws.com/0/72479/13f8890b-c270-fbee-ac70-1a7fa57c0750.png" width="28%">

### グラスドリンクディスペンサー
蛇口のレバーを押し下げる動作のため、グラスにサーボモーター (SG-5010) を取り付けて、軸を回転させることにより回転盤に取り付けた添え木を押し下げる仕組みとした。

<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/e78ce709-1af0-1b41-07af-4204298da4e0.png" width="50%">

## 配線図
### Vinaera 電動ワインディスペンサー [VN-014]
<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/b682797f-d727-efe3-abbc-422f94b968a5.png" width="50%">

### 電動ドリンクディスペンサー [小便小僧] / 電動ドリンクディスペンサー [マーライオン]
<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/16fbec42-82a7-4b9f-33e5-f68594162d02.png" width="50%">

### グラスドリンクディスペンサー
<img src="https://qiita-image-store.s3.amazonaws.com/0/72479/67f193fa-be67-d35d-3b8f-ce90636fa39c.png" width="50%">

## ソースコード
### Vinaera 電動ワインディスペンサー [VN-014] / 電動ドリンクディスペンサー [小便小僧] / 電動ドリンクディスペンサー [マーライオン]
前回 <A HREF="https://qiita.com/kitazaki/items/db137536d4ce3f0cc3b8">おつまみディスペンサー</A> と同じソースコードを使用することができる。
Wio-Nodeのソースコードは<A HREF="https://github.com/kitazaki/ESP8266_otsumami_dispenser/blob/master/ESP8266_MOTOR.ino">こちら</A>。

### グラスドリンクディスペンサー
Wio-Nodeのソースコードは<A HREF="https://github.com/kitazaki/ESP8266_nomimono_dispenser/blob/master/ESP8266_SERVO.ino">こちら</A>。

```c:ESP8266_SERVO.ino
#include <ESP8266WiFi.h>
#include <Milkcocoa.h>
#include <Servo.h>

#define WLAN_SSID       ""  // Wi-Fi
#define WLAN_PASS       ""  // Wi-Fi

#define SERVOPIN 5  // Wio-Node IO5 => SERVO 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.

Servo myservo;
int startPos = 100;  // Start Position of SERVO MOTOR
int endPos = 0;      // End Position of SERVO MOTOR

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) {
      moving(startPos);
      delay(timer * 1000);
      moving(endPos);
    }
  } else {
    moving(startPos);
    delay(100);
    moving(endPos);
  }
}

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) );
  myservo.attach(SERVOPIN);
  moving(endPos);
}

void loop() {
  milkcocoa.loop();
}

void moving(int pos) {
  myservo.write(pos);
}
```

## まとめ
IoT 居酒屋 (仮) の実現に向けてまた一歩近づけて幸いです。

[![スクリーンショット 2018-05-20 22.24.39.png](https://qiita-image-store.s3.amazonaws.com/0/72479/3864c767-a7d1-915c-9885-9f111083ac26.png)](https://youtu.be/XcKvQU2_yl0)