[PR]記事内のアフィリエイトリンクから収入を得る場合があります
スポンサーリンク
Funliday

初期のビンテージルンバをESP8266とBlynk活用でスマホからリモートで掃除してIoT

Wi-Fiなし旧型ルンバを遠隔操作 Wi-Fiなし旧型ルンバをスマホからリモート操作でIoTを実現する方法について述べている記事。

サーボをくねくねと動かして気を良くした自分はいよいよルンバかなということでやってみた。

ぶっちゃけちゃうともうわかっちゃったので手順さえ踏めば誰でもできるよといえる。

【関連】

【Blynk】Wi-Fi機能の無いルンバをAlexaと連携させることができる
...

スポンサーリンク

初期型Wi-Fiなしルンバのリモート操作に至る発端

興味なかったら飛ばしてください。

Raspberry Piの応用例として

Raspberry Pi楽しいですよね。

いろいろRaspberry Piの応用について書かれたサイトを見ているうちに旧型ルンバでもIOポートがあってIoT化できるという記事を見かけたわけだ。

それならやりごたえあるし実際にすごく実用的なのでやりたい。

ではルンバをリモートで操作できるようにできたらどんな機能を付けたいかというと、

  • カメラ
  • スケジュールで掃除開始
  • 部屋の間取り覚える(実現方法は不明)
  • アレクサやGoogleとの連携プレー(IFTTTは有料うんこだから却下)

といったところ。これらはかなり贅沢な機能だから素人としては、とりあえず掃除開始だけでもつけられれば十分と考える。

手持ちルンバのスペック

同じようなことを考える人のために我が家のWi-Fiなし旧型ルンバのスペックも述べておく。

  • ルンバ型番は620
  • Wi-Fi機能ない
  • リモコンあるけど効かない(SwitchBotから操作しようと画策もした)
  • リモコン操作機能は多少ある

もうかれこれ10年前に買ったものでまだバッテリーを変えたりして現役ビンビンだ。

実現への調査項目

「ルンバ Raspberry Pi」などで検索

無数の参考サイト

以下に列挙しておく

 

Raspberry Piによる当初の実現手順構想

  1. Raspberry PiにUbuntu(LinuxOSの一種)入れる
  2. Raspberry PiにROS(ロボットOS)入れる
  3. Raspberry Piってシリアル出力ポートがないらしいのでルンバに命令送るにはシリアル変換ボードが必要とのこと
  4. なんか相互通信して命令だす
  5. ハードル高すぎ
  6. ROSのインストールを何度やってもどこかしらでエラーになって最後までノーエラーで到達できない
  7. 自分のスキルレベルでは到底エラー除去などできるはずもない
  8. あきらめる

という感じで数行でまとめてしまっているがいろいろパターンを変えて数週間かけて多少の知見は得たものの何も実利を得ていないという結果。

ESP8266等のマイコンボードでもできるらしい

そのころ同時並行的にESP8266マイコンボードでサーボを動かしてBlynkサービスも使ってコントロールできるようになったのでこっちのボード使えないかと調べる。

スマホ見守りカメラをESP8266とBlynk使ってリモートで首振りさせる
...

Raspberry Piに比べたら結構かんたんそうで、ROSなんて入れる必要ないのはもちろん、簡単なコマンドをいくつか送るだけで実現している実例を見かける。

特にさきほど参考サイトでも紹介したこことか、ここのYouTubeの人のはかなりかんたんそうなコード進行。ただし前者のサイトはコードがまともに紹介されてないので実例があるというだけで参考にならない。

ルンバの仕様書は英語のみ

前述参考サイトのひとつにも入れてあるけど、→これ(ルンバIO仕様書(英語))が英語だから理解するのに少々難儀する。

やっぱり若いうちには勉強しておかないとやりたいことがまともにできなくなるよって一例。

とはいえ今は翻訳サービスが充実しているからそんなに障害にもならんけど。

Wi-Fiなし旧型ルンバをリモートで動かす手順

能書きが長かったがいよいよ本題。

必要なハード

ルンバへのつなげ方

Wi-Fiなし旧型ルンバを遠隔操作

ルンバ遠隔操作ESP8266

絵心ないから一応言葉で付け足すと、左のボードは下にMicroUSBポートをおいて見た図である。

【追記】7ピンのプラグを買ってつけたので色を備忘録として残しておく。

コード色
電圧変換基板のIN+ルンバの電源ピン(2個のいずれか)
電圧変換基板のINールンバのGNDピン
電圧変換基板のOUT+→ESP8266のGND(2個のいずれか)
電圧変換基板のOUTー→ESP8266の3.3V
ESP8266のTXD0ピン(=GPIO1)→ルンバのRXDピン
ESP8266のGNDピン(いずれか)→ルンバのGNDピン(2個のもう片方)
ESP8266のGPIO4(D2)ピン→ルンバのBRCピン

Wi-Fiなし旧型ルンバを遠隔操作

▼一旦分解してスリーブの中にコードを通してからはんだ付けする。

旧型ルンバを遠隔操作

▼スリーブの一番上のコード保護の部分は切り落とした。じゃないと背が高くなりすぎる。

旧型ルンバを遠隔操作

▼最終的にはこんな感じにできあがってなんとなくコンパクト。旧型ルンバを遠隔操作

▼最終的には100均ケースにうまく仕込んでこんなふうにコンパクトにできた。一見するとルンバの上になにかプラケースが乗ってるだけにしか見えない。カムフラージュする必要ないけど。

旧型ルンバを遠隔操作

スマホ側での準備

Blynkアプリを使うが以前別の記事でBlynkアプリの設定について触れたのでここでは割愛する。

ラズベリーパイ-スマホ-スマートロックを開閉-4 blynk仮想ボタン設定
...

注意点としてはプログラムコード内のV0とかV1という仮想ピンとスマホ画面での仮想ピンの番号をあわせる。

処理の流れ

スマホでBlynkアプリで操作

例えばスマホのBlynk画面にボタン1とボタン2と用意しておく。

ボタン1には掃除開始のV0を当てはめ、ボタン2にはドックへ戻るV1を当てはめる。

▼左のV3~V5が今回つくったボタン上の2個は前回のサーボ用。右画像がそのうちのV3の機能を展開したところ。とくに変わったことはしていない。
blynk操作手順blynk操作手順

ルンバへの命令の例

たとえば掃除開始ボタン→ルンバが掃除開始なら下記のようなコードを送る。

最初に通信開始コードを送る:128
Serial.write(128);

次に掃除開始コード送る:135
Serial.write(135);

さらにドックボタンを押すと掃除を中断してドックに戻るということができるのが下記コード

掃除中に送る:143
Serial.write(143);

こんなコードだけ見たってそれをどうやって実装するんじゃ?ってところが知りたいことだよね。でも実際ほぼこれらを組み合わせるだけで実現できた。

ほかにもコマンドあるけどハマりたくないからそれだけで良し

掃除開始とドックに戻るさえできればよしとする。

ほかのマニアックな人達はルンバを自由自在にリモート操作して前進、後退、右、左とか音楽を再生させたりとかして楽しいみたいだけど俺はそんなのぜんぜん興味なくてQOL上げるのが目的。

だから遠隔で掃除命令さえ出せれば最低限OKで、欲をいえばスケジュールによる掃除開始、もっと欲をいえば間取り記憶とかあるけどさすがにそこまでは無理。ましてや自由に操るとかいうのは方向性が違う。

備忘録

いろいろ調べていく中で「そういうことか」と学んだことがらをここに書いておく。

  • スリープしていると開始コマンド128を送っても無効だった(スリープとはルンバ620でいえば中央のランプが消灯している状態)
  • スリープから起こすにはルンバのBRCポートにハイ&ロー信号を送ると目覚めるらしい
    開始コマンド128とスリープから起こすデジタル出力はどっちが先?って思うけどポートが違うから一律ではなくスリープから起こすにはBRCポートに送るし、スリープしてないときは最初にRXDポートに128を送るってこと。←間違ってるかわからん。
  • ESP8266のシリアル送信ピンはGPIO1でおそらくどのESP8266ボードも同じ
    だからSerial.write(nn)ってコマンドするだけでルンバに命令を送れる。ラズベリーパイでせっせことROS入れてやるのなんてオーバースペックも甚だしい。さらになにかやる(間取り記憶とか)なら別だけど。
  • alexaに認識させるエミュレーターライブラリは数年前まで使えてたが今は無効。そういうサイトで見本コードがあったから入れてみて散々動かしてみたけどうんともすんとも言わなかった理由があったわけ。時間の無駄だった。
  • ESP8266の電源はモバイルバッテリー繋げてる人いるけどルンバから取れる
    ただし→3.3Vに降圧すること
  • シリアル通信のボーレートは115200で基本いく
  • ドック以外の場所でのスリープ中にはコマンド効かない
    起こす呪文が前述のBRCポートに信号送るっぽい

▼以下その他の引用。

  • ピン1(, 2):電源供給に使うピン。ルンバの充電状況によって出てくる電圧値が異なるので、レギュレータを挟んで5Vに整えてからESP32の5Vピンにつなぐ。(PCとESP32 を有線でつなぐ場合は、つながない)
  • ピン3:ルンバへのインプット。ESP32からの波形をそのまま入れてもよい(HIGHと認識される最低電圧が2.0Vのため)し、トランジスタなどでレベル変換して5Vの波形にしてから入れてもよい。
  • ピン4:ルンバからのアウトプット。抵抗を挟むなどして5Vから3.3Vに落とし、ESP32に入れる。
  • ピン5:ボーレート変更用のピン。Sleep状態からルンバを起こすのにも使う。ピン3と同様に、ESP32から3.3Vの波形をそのまま入れるか、5Vにレベル変換して入れる。
  • ピン6(, 7):グラウンド。ESP32のGNDピンとつなぐ。

引用元:ルンバをESP32でBluetooth通信で動かす方法 | UEC Media Design Lab

▼最終的にほぼ完コピさせてもらった人の動画。ソースコードは公開されていなかったので概要欄からリクエストしてリンクを送ってもらった。ソースコードも公開されていた。

ソースコード(スケッチ)

基板への書き込み等についてはこちらの記事でさらっと述べているので多少は参考になるかもしれません。

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define Roomba Serial
int pozor=4; //na roombe c.5 na mini d1 D2 pin probuzení

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "あなたのBlynkトークン";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "あなたの環境のSSID";
char pass[] = "あなたの環境のパスワード";

// This function will be called every time Slider Widget
// in Blynk app writes values to the Virtual Pin 1

void led_blink(int OnSec,int OffSec,int n){
  for(int i=0;i<n;i++){
    digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)
    delay(OnSec); // wait for a second
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED off by making the voltage LOW
    delay(OffSec); // wait for a second
  }
}
void wakeUp(void){ //スリープから起こす
  digitalWrite(pozor, HIGH);
  delay(100);
  digitalWrite(pozor, LOW);
  delay(100);
  digitalWrite(pozor, HIGH);
  delay(500);
}
// virtual pin 0 = CLEAN
BLYNK_WRITE(V3){
  int pinValue = param.asInt();
  if (pinValue == 1){
    led_blink(20,10,2);
    wakeUp();
    Roomba.write(128); //comunication start
    delay(10);
    Roomba.write(135);//clean 
  }
}
// virtual pin 1 = DOCK
BLYNK_WRITE(V4){
  int pinValue = param.asInt();
  if (pinValue == 1){
    led_blink(90,10,4);
    wakeUp();
    Roomba.write(128); //comunication start
    Roomba.write(143); //dock
    delay(10); 
  }
}
// virtual pin 2 = SPOT
/*BLYNK_WRITE(V6)
{
  int pinValue = param.asInt();
  if (pinValue == 1){
    led_blink(20,10,5);
    Roomba.write(134); //spot
    delay(10);
  }
}*/

// virtual pin 3 = pause
BLYNK_WRITE(V5){
  int pinValue = param.asInt();
  if (pinValue == 1){
    led_blink(90,10,2);
    Roomba.write(133);//pause
    delay(10);
  }
}

void setup(){
  pinMode(pozor, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  Roomba.begin(115200);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
  led_blink(500,500,4);
}

void loop(){
  led_blink(10,1990,1);
  Blynk.run();
  if (millis() >= 86400000) { //1日1回リセットしますとのこと
    ESP.reset();
  }
}

なぜかソースコードのネストのスペースが自動で消えてしまいいちいち入れても消えるからくじけたので読みにくいがおそらくPV少ないだろうからあまり気にしないことにする。

ちょっとだけ解説を入れておくと、

wakeup()関数でBRCポートにハイローとかって信号を打ち込んでるけど効いてるのか効いてないのか不明。

ただこのコードをコピペしてエラーなくコンパイルできればルンバは動くんじゃないかって思う。

新しい知見(シーケンス整理)

一応メモ残しておく。

ドックで充電中に送るコマンドシーケンスとドックから出ているときで送るコマンドシーケンスで一時同じものを送ってしまって動かなくなってしまったことがあった。

ドックにいるときに送るシーケンスは

  1. デジタルピンにHIGH→LOW→HIGHと0.1秒間隔で送る
  2. シリアル128を送る(パッシブモードへ移行)
  3. シリアル135を送る(掃除開始)

ドックから離れているとき(掃除中)に送る終了シーケンスは

  1. ドックにいるときの1と同じ
  2. ドックにいるときの2と同じ
  3. シリアル131を送る(セーフモードへ移行)
  4. シリアル143を送る(帰還命令)

ドックから離れているとき(掃除中)に送る停止シーケンスは

  1. ドックにいるときの1と同じ
  2. ドックにいるときの2と同じ
  3. シリアル131を送る(セーフモードへ移行)
  4. シリアル150を送る(一時停止)

ドックから離れているとき(停止中)に送る帰還命令シーケンスは掃除中の終了シーケンスと同じ。

つまりドックにいるときだけはシリアル131を送らない。

動画もどうぞ

【関連】

【Blynk】Alexa対応にしたルンバを今度はメンテ対応機能を追加してみた
...

【Blynk】Wi-Fi機能の無いルンバをAlexaと連携させることができる

タイトルとURLをコピーしました