Milkcocoa+mbed OS5


この記事はMilkcocoa Advent Calendar 2016の22日目の記事です。

Milkcocoaについて

私のようなWebに詳しくない人でもMilkcocoaはインターネットを介して、リアルタイムにWebページや機器を連動させることが簡単にできるのでとても良いです。

mbed + Milkcocoa

そんなMilkcocoaを使い始めたのは1年ほど前で、mbedのライブラリを作ったのがきっかけです。(mbedについて、詳しく知りたい方はここここを参考にして下さい。私が書いた書籍もありますw)

作ったmbed向けのMilkcocoaライブラリは3種類のサンプルプログラムがあり、ネットに繋ぐインターフェースによって異なります。


無線LAN(ESP8266)用
https://developer.mbed.org/users/jksoft/code/MilkcocoaSampleESP8266/

有線LAN用
https://developer.mbed.org/users/jksoft/code/MilkcocoaSample_Eth/

3G用
https://developer.mbed.org/users/jksoft/code/MilkcocoaSample_3G/


サンプルプログラムは導入しやすいようにArduino向けのサンプルと同じような作りにしています。

main.cpp
#include "mbed.h"
#include "MQTTESP8266.h"
#include "MQTTClient.h"
#include "SoftSerialSendOnry.h"
#include "Milkcocoa.h"
#include "MClient.h"

// The default setting is for the Simple IoT Board(mbed LPC1114FN28)
// Please change to fit the platform
SoftSerialSendOnry pc(dp10); // tx
DigitalOut myled(dp18);

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "...SSID..."
#define WLAN_PASS       "...PASS..."

/************************* Your Milkcocoa Setup *********************************/

#define MILKCOCOA_APP_ID      "...YOUR_MILKCOCOA_APP_ID..."
#define MILKCOCOA_DATASTORE   "esp8266"

/************* Milkcocoa Setup (you don't need to change this!) ******************/

#define MILKCOCOA_SERVERPORT  1883

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
// The default setting is for the Simple IoT Board(mbed LPC1114FN28)
// Please change to fit the platform
MQTTESP8266 ipstack(dp16,dp15,dp26,WLAN_SSID,WLAN_PASS); // TX,RX,Reset,SSID,Password,Baud
MClient client(&ipstack);

const char MQTT_SERVER[]  = MILKCOCOA_APP_ID ".mlkcca.com";
const char MQTT_CLIENTID[] = __TIME__ MILKCOCOA_APP_ID;

Milkcocoa milkcocoa = Milkcocoa(&client, MQTT_SERVER, MILKCOCOA_SERVERPORT, MILKCOCOA_APP_ID, MQTT_CLIENTID);

extern void onpush(MQTT::MessageData& md);

int main() {
// void setup() {
    pc.baud(9600);
    pc.printf("Milkcocoa mbed ver demo\n\r\n\r\n\r");
    pc.printf("Connecting to %s\n\r",WLAN_SSID);
    milkcocoa.connect();
    pc.printf("\n\rWiFi connected\n\r");

    pc.printf("%d\n\r",milkcocoa.on(MILKCOCOA_DATASTORE, "push", onpush));

// }
    while(1) {
// void loop() {
        milkcocoa.loop();

        DataElement elem = DataElement();
        elem.setValue("v", 1);

        milkcocoa.push(MILKCOCOA_DATASTORE, elem);
        wait(7.0);
    }
}

void onpush(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;
    DataElement de = DataElement((char*)message.payload);
    pc.printf("onpush\n\r");
    pc.printf("%d\n\r",de.getInt("v"));
}

また、コンポーネントライブラリにも登録されています。

mbed OS5 + Milkcocoa

mbedの中では昨年から今年にかけてmbed OSというものが開発されていて、現在ではmbed OS5が最新になっています。
mbed OS5には次のようなリアルタイムOSのサービスもあり、現在、これらの機能を使って、mbed OS5対応のMilkcocoaライブラリを作成中です。


mbed OS5のリアルタイムOSサービス
〇Thread(スレッド)

・並行処理っぽいフローが作れる
・main関数も1つのスレッド
・各スレッドに対して優先順位を設定できる
・main以外のスレッドの動的メモリはスタックで扱われる
・スタックのサイズはデフォルト2KB(環境によって異なる場合あり)
・スレッド内でメモリをたくさん使うクラス等を動的に確保するとスタックが足らなくなるかも

■Mutex(ミューテックス)、Semaphore(セマフォ)、Signals(シグナル)


スレッドのフローを制御するための機能他のスレッドの処理を待ったり、共有リソースを使用するタイミングをコントロールしたり。

●Queue(キュー)、Mail(メール)


スレッド間でデータをやり取りするための機能
排他的に非同期でデータを交換できる


どんな風になるかというと・・。

現在のMilkcocoaライブラリはこんなイメージです。

単機能な機器であればあまり気にならないかもしれませんが、いろんな機能を実現する際にはMilkcocoaのアップするデータを作る処理やMilkcocoaから取得したデータを扱う処理のタイミングはあまり自由にならないので問題になります。

そこでmbed OS5のリアルタイムOSの機能を使うとこんな風になります。

複数のスレッドを使って、メインの処理とWi-Fi通信、Milkcocoaとの通信処理を分離し、シグナルで同期し、キューでデータをやり取りするようにする予定です。
こうすることによって、〜処理〜の部分のタイミングは自由になります。

完成したら公開しますので、もうしばらくお待ち下さい。
(本記事は既出ネタの書き直しです。すみません^^)