ESPr × Milkcocoa for Arduino SDK

この記事は、[Milkcocoa Advent Calendar 2016](http://qiita.com/advent-calendar/2016/milkcocoa) 17日目の記事です。枠が空いてしまったので、遅ればせながら書かせて頂きます。🙇

## ESPr × Milkcocoa for Arduino SDK

11月に[明星和楽](http://2016.myojowaraku.net/)というITフェスティバルで、アートをテーマにしたIoTの展示を行いました。
<img width="768" alt="IMG_1957.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/38442/5a1d1f4f-a083-341b-7bb4-6e3aee720487.jpeg">

今年のMashupAwardsにもエントリーさせて頂きました。
http://hacklog.jp/works/49919

展示物には、[ESPr Developer（ESP-WROOM-02開発ボード）](https://www.switch-science.com/catalog/2500/)を使用しているのですが、ESPrにはArduinoのスケッチを直接書き込むことができます。
つまり、<b>MilkcocoaのArduinoSDKを使ったスケッチをそのまま流用することが可能</b>です。

## サンプルコード
動作としては、

- ESPrでWiFiに接続する
- Milkcocoaへのデータpushを`onpush()`で監視して、処理を行う

という簡単なものです。
`setColor`周りは、作成したIoTデバイスのLED色を変える処理です。（今回は詳細割愛します。）

実際はArduinoIDEで作成したファイルなので拡張子が`.ino`ですが、コードハイライト有効化のため`.c`で記載しています。

```sample.c
#include <Milkcocoa.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_NeoPixel.h>

#define MILKCOCOA_APP_ID    "<your-milkcocoa-app-id>"
#define MILKCOCOA_DATASTORE_NETWORK "network_status"
#define MILKCOCOA_DATASTORE_COLOR "color"
#define MILKCOCOA_SERVERPORT    1883
#define MAX_VAL 64 // 0 to 255 for brightness

const char* ssid = "<your-wifi-ssid>";
const char* password = "<your-wifi-password>";
const char MQTT_SERVER[] PROGMEM    = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] PROGMEM  = __TIME__ MILKCOCOA_APP_ID;
boolean connectedStatus = false;
int colorCode = 1;

WiFiServer server(80);
WiFiClient client;
Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);
Adafruit_NeoPixel pixel = Adafruit_NeoPixel(60, 12, NEO_GRB + NEO_KHZ800);

extern "C" {
    #include "user_interface.h"
}

void onpush(DataElement *elem);
void setup() {
    Serial.begin(115200);

    // Connect to WiFi network
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");

    // Start the server
    server.begin();
    Serial.println("Server started");

    // Print the IP address
    Serial.println(WiFi.localIP());

    pixel.begin();
    pixel.show(); // Initialize all pixels to 'off'

    // Milkcocoa
    milkcocoa.on(MILKCOCOA_DATASTORE_COLOR, "push", onpush);
}

void loop() {
    if (!connectedStatus) {
        milkcocoa.loop();
        DataElement elem = DataElement();
        elem.setValue("status", "connected");
        milkcocoa.push(MILKCOCOA_DATASTORE_NETWORK, &elem);
        connectedStatus = true;
    }
    milkcocoa.loop();
}

void onpush(DataElement *elem) {
    Serial.println(elem->getInt("colorCode"));
    colorCode = elem->getInt("colorCode");
    setColor(colorCode);
}

void setColor(uint16_t colorCode) {
    uint16_t i;
    switch (colorCode) {
        case 1:
            // red
            for (i=0; i<pixel.numPixels(); i++) {
                pixel.setPixelColor(i, pixel.Color(MAX_VAL, 0, 0));
                pixel.show();
            }
            break;
        case 2:
            // green
            for (i=0; i<pixel.numPixels(); i++) {
                pixel.setPixelColor(i, pixel.Color(0, MAX_VAL, 0));
                pixel.show();
            }
            break;
        case 3:
            // blue
            for (i=0; i<pixel.numPixels(); i++) {
                pixel.setPixelColor(i, pixel.Color(0, 0, MAX_VAL));
                pixel.show();
            }
            break;
    }
}
```

## まとめ
Arduino系のIoTボードでは、SDKのおかげで簡単にMilkcocoaを使うことができます。ESPrはWiFiさえあればそれ単体でネットワークに接続可能なので、Milkcocoaとの相性は抜群です。

こちらの発表資料にも概要を載せてありますので、興味ある方はぜひご参照ください。

- #明星和楽2016 で #Milkcocoa に繋がる LEDデバイスを展示しました。
https://speakerdeck.com/shanonim/art-iot-in-myojyo-waraku-2016