コロコロハック

Extreme Home Hackというイベントがあって、そこで作った物=コロコロについて書こうと思って、放置していたから書くことに。

まずはコロコロはニトムズさんが1983年から販売している物ですね。殆どの人が目にした事があると思われる、掃除でコロコロと床を粘着シートでゴミを取って綺麗にする物。

IMG_9611

1. コロコロ Specifications

取手がついて、このままコロコロと…枝の部分は緩めて長さを調整できる。コロコロの用途としての基本機能としては、

1. 掃除で使う物
2. 粘着シートで床をコロコロして綺麗にする
3. 枝の部分を緩めて伸ばせる
4. 取手(グリップ)が付いている
5. コロコロの粘着ロールは取り外して交換可能

この辺でしょうか。お掃除で毎日使われますね。
コロコロの粘着ロールを外すと、次のように分解されます。まずは中の支柱(?)部分。

そしてロールはモチロン空洞ですね。

この5×2(裏表)の計20個に区画された空洞は、耐久性と軽量化、回した時の使いやすさを考えた結果の物と思われるですが、この部分は「仕込める!!」かなり熱いポイントです。
この空洞部分にセンサーやら電力、マイコンやら通信部分を仕込むと、このコロコロを激しく活用できるようになる。実際、他のハックでは、コロコロを回して床のどの部分が掃除できているか?といったネタが出ていた。この中空部分は割と広くて、ぶっちゃけ何でも仕込み放題という。
また枝の部分も中空になっていて、中にケーブルを通して利用できます。

コロコロのhackableな要素としては次のようになります。

1. コロコロは分解するとロールと支柱に分かれる。
   -> 5x2(裏表)の20個の区画の中に何でも仕込めそう。
   -> 耐久性との兼ね合いだが、区画の部分を切って広く使える。
2. 枝の中は中空になっている。
   -> ケーブルを通したり中に何か仕込める。
   -> 枝の伸び縮みも利用可能。
3. グリップの部分も取り外して仕込める。
   -> 取手に静電容量センサやスチッチ・ボタンを仕込んで握ると何か反応するような事ができる。
   -> 枝の中に線を通すor何か仕込んで枝を握ったら何かできるような。

2. コロコロ Hack idea

基本機能だけでぶっちゃけゾクゾクしてくる魅力があります。掃除で(毎日)使う生活に密着した物。これをハックするぜ!!という事で最初に上がったのは、

1. コロコロすると充電される
2. 充電した電気を取り出して利用できる

といったアイディアに合流して、これはイケる!!と。例えば電気のない地域で、お昼はコロコロと持って歩いて発電、そして夜は光って照明になるという使い方や、災害時の発電用途としても良さそう。ただ、実際に出来上がったものは全く違う物になっちゃいました。
この他に出来そうなのとかネタが以下です。

1. コロコロの中にLEDを仕込んで転がすと光る。
2. 色センサーを枝の部分からロールに向けて使って、汚れたら(色の変化)何かブブっとする。
3. グリップの部分に静電容量センサを仕込んで、握ると光る or etc…
4. コロコロの中にスピーカ・マイクを仕込んで、コロコロとの対話(モノとの対話)。

とかです。時間と労力とのバランスでこれまた全く違うモノになったですが、機会を見てやってみようかと。実際に作ったのは、コロコロすると音が出るモノですね。

3. コロコロ Hack

ここからは実際に加工します。作るものは以下です。

1. コロコロの中空部分にMPU 6050(加速度・ジャイロ)を仕込む
2. センサーの値をKonashi(BLE)で取得する
3. iPhoneアプリで取得した値によって音がなる
4. APIで音をリモートで変えたり流しこめるSDKもおまけで作る

実際の物とアプリを1日ちょいで一気にスクラッチから作るので、ちょっとした勢いが必要でした。出来上がったものはこちらです。

チーム名がコロコロ革命だったので、そのままタイトルもコロコロ革命です。動きに合わせて再生する音のピッチを変えているので、お掃除する時の流れでいろんな音が流せますね。加工した状態はこちら。

ビックリしたのが「ミニブレッドボードがピッタリ収まるサイズ!!!!」。ちょっと作ってみる用途にはピッタリでしょう。電源にはLipoを使ってますが、普通の電池でも楽勝で収まります。この空間は素晴らしい!!!!
構成としては次の通りです。コントローラとして中華Prominiを使っているのは、ここからLEDを出して中から光らせたり、何か制御を挟もうとした名残です。MPU 6050のLibraryが使えて、ここで終端&何かできるという所もあったりしますが。
普通のコロコロと並べると、次のようになります。

よく見ると穴が開いている方が”Hack済みコロコロ”です。中から光らせて、暗いとキラキラしてよく見えるように穴を開けてもらいました。このハッカソンではおかげでニトムズ賞を頂きました。ありがとうございます。

4. おまけ

作る時に気をつけたのが、

普通のコロコロとして使える

これに尽きます。上記の写真の通り、普通のコロコロと見た目も使い勝手も一緒です。「普通に生活している状態を損なう事なく、今まで通りの物として使える」これを意識しました。偶然、コロコロの中に何でも仕込めたので、完全に同一の物として使えます。
何か事前準備や環境条件をしなくても(まぁ、スマホにアプリは入れる必要がありますがw)、普段通りの物として使えるというのは一つのポイントかなと。IoT的な物とかは、何かプラスアルファのデザインや物といった他にも、今まで通りの物として生活に溶け込んで使えるという部分は、見た目のインパクト外の所で必要でしょう。

次に中の区画に仕込む時の注意として、耐久性とのバランスを考えて区画をカットしたりしました。恐らく凄く検討&試験を重ねて、今の2×5(裏表)の20区画に切られていますが、ここに手を入れるのでコロコロする時の耐久性が失われます。自分の力でゴリゴリして動かしてとりあえず大丈夫ですが、連続運転(連続コロコロ)するとかなりこの部分は心配になります。まぁ、この点は1-day hackなので…
区画を使いやすいようにカットする時は、この耐久性とのバランスを考えて行った方が良いです。

あ、もう一つ大切なのが、

実際に使ってもらったら、別に掃除している時に音とか要らないし、ウザイ

と言われたことです。ただし、子供ウケは良かったです(オモチャとして見ている)。よくアイディアでオモシロネタや、見た目のインパクトがあったりする物がありますが、実際に生活で使っている人の感想というのは大切なものです。これsuge-!!と思って作るのも大切ですが、フィールドテスト(アイディア段階でも)を行ってみると、また違った感想が出てきます。それを持ってフィードバックとして改良していくといった感じですね。ギークだけじゃなく、普通の人に使ってもらったりしてどうか?という所は、ハッカソンだと期間が短いのであれですが…大切なポイントかなーと。

他にやってみたい事は、コロコロさせて正転・逆転で違った音を出せたり遊べたので、コロコロを持って100人くらい体育館で並べて、一斉に歩くとメロディーが出来るとか楽しそうだなーと。まったく掃除と関係ないですが。

MQTTについて少し

ParticleでQoS1|2を実装しれ!!みたいに言われて、それっぽく使いやすいように実装してみたりして思ったりする所。Spark/Photonを持っている人なら一度は使ったと思われるMQTT、なぜかIoT(的)な物で使われるMQTT…に対してQoSを意識して実装する時の注意点を少し。

MQTT QoS0|1|2のシーケンスは以下の通り。

ここではよく利用すると思われるPUBLISHを例にする。MQTTはQoSのレベルによって接続するMQTTサーバとの通信が変わる。レベルが上がる毎に、応答確認(ACK)メッセージのやり取りが増える感じ。このACKを利用すると、次のような実装が期待されると思う。

これはQoS1の場合について。timer処理を入れて、ACKが来なかった時に同じメッセージを再送するといった事ができるようになる。実際MQTT 3.1のプロトコル定義にもDUPフラグを付けて再送信処理を行うと記載されている。(MQTT V3.1 Protocol Specification, 4.1. Quality of Service levels and flows, QoS level 1: At least once deliveryから)
NWの一般的なQoS(流量制御や遅延への保証)とは違って、メッセージの到達保証にかかるシーケンスが変わる感じですね。ここで、自分的にはこのtimer処理を入れて再送するという実装をしている場合は、それは止めた方が良いと思われ。そう言ったクライアントを利用しているなら、ちょっと危ない気はする。ちなみに、サーバ側はACKを送って、その再送処理を行わないのが殆どだと思われ(その必要がない)。

というのはTCP over TCP問題(Why TCP Over TCP Is A Bad Idea)という、よくある問題がベースになる。短い資料だけど、遅い&遅延が発生するようなNW(特にIoT的な端末だと、低帯域なNWを利用すると思われるので、このケースがよく合う)で発生する問題で一度は目を通した事がある人も多いはず。ザックリだと、TCPの上に信頼性(再送を行うような)のあるプロトコルを載せた場合、そのNWは破綻するといった感じ。

MQTTは足回りにTCPを利用していて、QoS1|2のケースでメッセージの到達性の確認(ACK)を利用した再送処理を行う場合、同様の問題(輻輳)が発生する可能性がある。上位(MQTT)の再送処理が、足回りTCPの再送を更に増加させて、輻輳により結果として止まってしまう現象が起きる。条件としては。

1. QoS1|2を利用
2. 到達性の保証からACK待ちのタイマーでの再送を行う

この場合に発生する現象です。これを回避するには、

1. タイマーによる再送を行わない
2. QoS0を利用する
3. 必要な時だけ接続断

このくらいかしら。MQTTのプロトコル的にはQoS1|2を利用するとき、ACKを受け取れない場合、Sender(クライアント)はDUPフラグを付けて再送信する。これは足回りにTCPを利用するケース(MQTT-SN: UDP/non-IPの実装をしている場合は別)では止めた方が良い。再送信が1回だけならOK…な感じも少しするけど、送信する頻度、TCP接続の維持(は止めた方が良い気がする)などで、どういった実装をするか不明なので再送信が1回も10回も変わらない。結果としてタイマー処理を行うようあるにも関わらず使わない方が良いという事になる。これは違和感もあると思うけど、プロトコル定義と発生する現象は別なので。
ちなみにTCPを利用するのはNWの信頼性のためで、上位MQTTメッセージングの信頼性はMQTTとして保証する必要があるため、別々のレイヤーとして考えられる。そのため、MQTTとしてはACKが必要になるというのも理解が出来る。ただ、どちらかと言えば、HTTP(リクエスト・レスポンス、トランザクションレス)のようなACKとして考えた方が良いと思われる。MQTTとHTTPで比較がたまにあるように、HTTPのように再送信を意識したり期待はしない方が良い。

経験的にだけど、回線業者と専用線で帯域保証を付けているNWでない限り、インターネットはベストエフォートな世界なので、遅延や低帯域になる事は普通にあり得る。そういった所で、足回りがTCPで再送処理を行う時の注意点としても、一つ考えておいた方が良いと思われ。
同様にIoT的なプロトコルの一つにCoAPがあるけど、そっちは足回りがUDPでこのような事は考える必要がない。あと、Google Chromeに実装されているQUICなんかも足回りはUDPで、その上に独自に信頼性のあるプロトコルを構築する形になっている。上位と下位のNWで何を利用して、どういう実装をするか?と言うのは、その後に発生するであろう問題点の回避として、一考しておいて良いでしょう。

Particle MQTT 0.3.0 library

MQT library 0.3.0 for Particle Photon/Spark release. Already can use Web IDE. This release fixed some bug and implement QoS1|2 flag. MQTT V3.1 Protocol Specification is here. MQTT have QoS flag when it send PUBLISH/SUBSCRIBE…etc message. QoS level is following.

QoS 0
  Make the message available to any interested parties.

QoS 1
  Log the message to persistent storage, make it available to any interested parties, and return a PUBACK message to the sender.

QoS 2
  Log the message to persistent storage, do not make it available to interested parties yet, and return a PUBREC message to the sender.

Previous Photon MQTT library already use QoS 1 when Photon/Particle send message to the MQTT server, but this 0.3.0 release can control the QoS level. If application don’t want to use QoS flag on program, library use QoS 0 level(of cource don’t need to change the source code, if application use before 0.3.0 release library).

Here is How to use QoS1|2 source code.
mqttqostest.ino

#include "MQTT.h"

void callback(char* topic, byte* payload, unsigned int length);
MQTT client("www.hirotakaster.com", 1883, callback);

// recieve message from MQTT server.
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);

    if (message.equals("RED"))    
        RGB.color(255, 0, 0);
    else if (message.equals("GREEN"))    
        RGB.color(0, 255, 0);
    else if (message.equals("BLUE"))    
        RGB.color(0, 0, 255);
    else    
        RGB.color(255, 255, 255);
    delay(1000);
}

// QoS ack callback.
// MQTT server sendback message id ack, if use QOS1 or QOS2.
void qoscallback(unsigned int messageid) {
    Serial.print("Ack Message Id:");
    Serial.println(messageid);
}

void setup() {
    Serial.begin(9600);
    RGB.control(true);
    
    // connect to the server
    client.connect("sparkclient");

    // add qos callback
    client.addQosCallback(qoscallback);

    // publish/subscribe
    if (client.isConnected()) {
        // get messageid parameter at 4.
        // if you want to check the QoS ack response from MQTT server,
        // store messageid(list or array) and check on "QoS ack callback".
        uint16_t messageid;

        // use QoS1
        client.publish("/outTopic", "hello world QOS1", MQTT::QOS1, &messageid);
        Serial.println(messageid);

        // use QoS2
        client.publish("/outTopic", "hello world QOS2", MQTT::QOS2, &messageid);
        Serial.println(messageid);

        client.subscribe("/inTopic");
    }
}

void loop() {
    if (client.isConnected())
        client.loop();
}