はじめに
-スケッチサンプルを使って、Edisonでルンバを動かしたい!-
↓前回はオリジナル試作機として、音と光でクリスマスの雰囲気を盛り上げるべく、Edisonを使ってみるチャレンジをしました。
今回は動きを伴うものをやってみたいと思います。
オリジナル試作機の開発の構想
本命案
1台のEdisonを、お掃除ロボットのルンバに乗せて、
ルンバのシリアルポートに接続し、
ルンバの動き等をEdisonからコントロールしたいと考えています。
もう一台の別のEdisonにボタンスイッチ等をつけて、ルンバ上のEdisonへ
ボタンの状態等を送って、ワイヤレスリモコンにできれば良いなと思っています。
もしもルンバのシリアルポートからの制御がうまくいかなかった場合には
ルンバの赤外線リモコン信号をEdisonから送って制御ができればとおもいます。
予備案
万が一、ルンバの制御が、どうしてもうまくいかないときには「車両型ロボットベースキット 2WD ROBOT CAR」の制御に切り替えてチャレンジしてみようとおもいます。
http://eleshop.jp/shop/g/gE7E411/
目次
1.初期設定
2.スケッチサンプルを試してみる
2-1.EdisonLabさんの「EXAMPLES スケッチとコードのサンプル集」
2-2.「Blink LED | LEDの点滅 LEDを1秒おきに点滅させる。」をさっそく試す
2-3.SparkFun Danger Shieldを使ってみる
2-4.「Analog Read Serial | アナログ入力の読み込み 」
2-5.「Digital Read Serial | スイッチ状態を読み込み」
2-6.「Fade | アナログ出力を使ってLEDの輝度調整 」
2-7.「Blink Without Delay | 等間隔でLEDを点滅」
2-8.「Push Button | タクトスイッチでLEDの状態を切り替え 」
2-9.「Debounce | タクトスイッチでLEDを点滅 」
2-10.「Digital Input Pullup | INPUT PULLUPの実演 」
2-11.「State Change Detection | シリアルモニタにボタンの状態を表示 」
2-12.「Analog In Out Serial | アナログのシリアル入出力 」
2-13.「Analog Input | アナログ入力の実験 」
2-14.「Calibration | アナログセンサーの調整 」
2-15.「Fading Example | LEDのフェード点灯/消灯」
2-16.「ASCII Table Arduino Example | シリアルモニタにASCIIコード表を表示」
2-17.「Graph | アナログ入力値をグラフ表示」
2-18.「Phisical Pixel | 文字入力でLEDを制御」
2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」
2-20.「If Statement Conditional | “if”構文(2分岐選択)」
2-21.「Character Analysis | 文字の判定」
2-22.「Character Analysis | 文字の判定」
2-23.「Simple Web Server | LEDをネット経由で制御する」
2-24.「Web Server | アナログ入力値を表示するウェブサーバ」
3.ルンバの赤外線リモコンの調査
4.ルンバのシリアルポートの調査
5.ルンバの制御
5-1.Edisonとルンバの接続
5-2.先人のArduino用のスケッチで動作確認
6.オリジナル機の制作
6-1.システムの全体像案
6-2.リモコンの仕様
6-3.リモコンのスケッチ
6-4.PC側のスケッチ
6-5.Wifiでのルンバのコントロール
6-6.PC側のスケッチ Wifi版
6-7.完成版へ
7.まとめ
コラム ルンバの電源が入らなくなったとき・・
2015/9/23完
1.初期設定
こちらの手順を行いました。
http://edison-lab.jp/gettingstarted/edison-arduino/windows/
↑途中に記載の初期化も行いました↓
http://edison-lab.jp/flash/windows/
>Step 2 – Edison Arduino IDEのダウンロード
の部分のページ内容が変わっていましたので、
をクリックしてインストールしました。
2.スケッチサンプルを試してみる
2-1.EdisonLabさんの「EXAMPLES スケッチとコードのサンプル集」
EdisonLabさんの「EXAMPLES スケッチとコードのサンプル集」にはスケッチサンプルとその使い方がたくさん掲載されています。
http://edison-lab.jp/examples/
2-2.「Blink LED | LEDの点滅 LEDを1秒おきに点滅させる。」をさっそく試す
まずは「Blink LED | LEDの点滅 LEDを1秒おきに点滅させる。」を試してみます。
http://edison-lab.jp/examples/basic/blink-led/
Edisonのブロック図をみますと、EdisonのIO13端子には、LEDがすでに設けられています。
http://download.intel.com/support/edison/sb/edison_arduino_hvm_8_26.pdf
そのためブレッドボード等へ配線をしなくても、Edison上のLEDが点滅するはずです。
実際に↓こちらに記載の手順を試してみると・・・
http://edison-lab.jp/examples/basic/blink-led/
「インテル(R) Edison キット for Arduino」の中央のやや左下にある緑色のLEDが1秒おきに点滅しました。大成功。
2-3.SparkFun Danger Shieldを使ってみる
EdisonLabさんの「EXAMPLES スケッチとコードのサンプル集」ではブレッドボードへ配線をして試すようになっています。そのまま試しても良いのですが、今回はお手軽にいろいろ試してみるため、Arduino用のDanger Sheildを「インテル(R) Edison キット for Arduino」に差し込んで、スケッチサンプルをSparkFun Danger Shield用に少しだけ書き換えて試してみたいとおもいます。
これをルンバのワイヤレスリモコンの方(もう一台のEdisonのほう)として採用できるかについてもスケッチサンプルを試しながら検討していきたいとおもいます。
(a)ArduinoUno等の用のどのシールドがEdison キット for Arduinoで使えるの?
「インテル(R) Edison キット for Arduino」で、Arduino用のどのシールドが使用できるかは、以下pdfファイルにまとめられていました。
http://download.intel.com/support/Galileo-Edison_ShieldTestReport_330937-002.pdf
p137からp143にSparkFun Danger Shieldについて記載があります。
CapSense(タッチセンサー)以外の機能は動作するとの記載がp143にありました。
(b)SparkFun Danger Shieldとは?
回路図はこちらになります。
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Dev/Arduino/Shields/Danger_Shield-v17.pdf
商品の詳細はこちら
https://www.switch-science.com/catalog/1421/
写真の左上の列は左から右へ順に、
赤色のLEDが電源ランプのLED、
リセットスイッチ、
A4端子に接続された温度センサTMP36、
A3端子に接続されたCDS、
D5端子に接続された黄色のLED、
D6端子に接続された黄色のLED、
になります。
その下にスライダーとスイッチが3組あります。
上から順に、
A0端子に接続されたスライダー1(可変抵抗)とD12端子に接続されたタクトスイッチ1、
A1端子に接続されたスライダー2(可変抵抗)とD11端子に接続されたタクトスイッチ2、
A2端子に接続されたスライダー3(可変抵抗)とD10端子に接続されたタクトスイッチ3
となります。
その下に左から右へ順に
7セグメントLED(74HC595Nに接続されており、D3端子にSERIAL_IN, D8端子にCLOCK,D7端子にLATCHが接続されている)
D3端子に接続されたブザー
となります
D9端子は1Mの抵抗を挟んでD2端子と接続されCapSense(タッチセンサー)として機能するものですがEdisonではライブラリが対応していないので使用できません。
接続されていない端子は、D0, D1, D13, A5となります。
(c) SparkFun Danger ShieldをEdisonに取り付ける
(4)「Blink LED | LEDの点滅 LEDを1秒おきに点滅させる。」のサンプルスケッチを SparkFun Danger Shield用に変更する
スケッチサンプル
上記スケッチサンプルの20行、25行、27行で、13番ピンを指定している数字「13」をDanger ShieldのLEDのピンに書き換えます。
D5点滅
上記のように13を5に書き換えると、下のビデオのようにD5に接続されたLEDが点滅します。
上記のように6に書き換えると、下のビデオのようにD6に接続されたLEDが点滅します。
このようにスケッチサンプルのピン番号の指定箇所をシールドの配線に合うように変更するだけでスケッチが動作します。
それではほかのスケッチサンプルを試していきます。
2-4.「Analog Read Serial | アナログ入力の読み込み 」
http://edison-lab.jp/examples/basic/analog-read-serial/
スライダーはA0端子に接続されていますので↑こちらのスケッチのままでOKです。
以下のビデオのようにスライダーを動かすと値が変化します。
2-5.「Digital Read Serial | スイッチ状態を読み込み」
http://edison-lab.jp/examples/basic/digital-read-serial/
9行目の int pushButton = 2;を
int pushButton = 12;とします。
16行目の pinMode(pushButton, INPUT); の後に、
digitalWrite(pushButton, HIGH);を追加します。
この命令によってインテルEdison キット for Arduinoの内蔵のプルアップ抵抗がオンになります。
http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2025
DangerShieldでは下記回路図のようにプルアップ抵抗が接続されていないため、内蔵のプルアップ抵抗をオンにする必要があります。
インテル(R) Edison キット for Arduinoのプルアップ抵抗などの詳細は、下記pdfファイルのp12にありました。
http://download.intel.com/support/edison/sb/edisonarduino_hg_331191007.pdf
2-6.「Fade | アナログ出力を使ってLEDの輝度調整 」
http://edison-lab.jp/examples/basic/fade/
スケッチの10行目をint led = 5;にするだけでOKです
2-7.「Blink Without Delay | 等間隔でLEDを点滅」
http://edison-lab.jp/examples/digital/blink-without-delay/
26行目をconst int ledPin = 5;にするだけでOKです
2-8.「Push Button | タクトスイッチでLEDの状態を切り替え 」
http://edison-lab.jp/examples/digital/push-button/
下記の例のようにスケッチの29行、30行を変更し、40行目を追加でOK。
2-9.「Debounce | タクトスイッチでLEDを点滅 」
http://edison-lab.jp/examples/digital/debounce/
下記の変更後の例のようにスケッチの32行、33行を変更し、51行目を追加でOK。
2-10.「Digital Input Pullup | INPUT PULLUPの実演 」
http://edison-lab.jp/examples/digital/digital-input-pullup/
2015/8/16現在ちょっと記載に誤りがあるような・・・
正しくは↓こちらかな。
https://www.arduino.cc/en/Tutorial/InputPullupSerial
下記の例のようにスケッチの28行、29行、35行、44行、47行を変更でOK。
2-11.「State Change Detection | シリアルモニタにボタンの状態を表示 」
http://edison-lab.jp/examples/digital/state-change-detection/
下記の変更後の例のようにスケッチの29、30、39、58、65行を変更でOK。(コメントは修正していませんが修正するのが望ましいです。)
2-12.「Analog In Out Serial | アナログのシリアル入出力 」
http://edison-lab.jp/examples/analog/analog-in-out-serial/
スケッチの25行目をconst int analogOutPin = 6; に変更するだけでOK。
2-13.「Analog Input | アナログ入力の実験 」
http://edison-lab.jp/examples/analog/analog-input/
スケッチの31行目をint ledPin = 6; に変更するだけでOK。
LEDの点滅速度がスライダーの位置によって変わる。これは何かに使えそうな予感がします。
2-14.「Calibration | アナログセンサーの調整 」
http://edison-lab.jp/examples/analog/calibration/
下記の変更後の例のようにスケッチの30、31、41、42、60行を変更でOK。
2-15.「Fading Example | LEDのフェード点灯/消灯」
http://edison-lab.jp/examples/analog/fading-example/
21行目をint ledPin = 6;に変更でOK。
2-16.「ASCII Table Arduino Example | シリアルモニタにASCIIコード表を表示」
http://edison-lab.jp/examples/analog/fading-example/
スケッチは変更なしでOK。
2-17.「Graph | アナログ入力値をグラフ表示」
http://edison-lab.jp/examples/communication/graph/
スケッチは変更なしでOK。
スケッチサンプルの中のコメントにPC上のprocessingでシリアルからスライダーの値のデータを受け取ってグラフ表示するソースコードが入っている。それを実行するとスライダーの動きにあわせて以下のムービーのようにグラフが描画される。これは何かに使えそう。processing-1.5.1で動作を確認した。
2-18.「Phisical Pixel | 文字入力でLEDを制御」
http://edison-lab.jp/examples/communication/phisical-pixel/
スケッチの26行目をconst int ledPin = 6; に変更するだけでOK。
2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」
http://edison-lab.jp/examples/communication/visual-color-mixer/
スケッチは変更なしでOK。
3つのスライダーの値を取るスケッチサンプル。これは使えそう。
2-20.「If Statement Conditional | “if”構文(2分岐選択)」
http://edison-lab.jp/examples/control/if-statement-conditional/
30行目をconst int ledPin = 6;に変更でOK。
スライダーが閾値を超えたかどうかでルンバの動きを変えたいときに使えそう。
2-21.「Character Analysis | 文字の判定」
http://edison-lab.jp/examples/strings/character-analysis/
スケッチは変更なしでOK。
PCから文字を送ってルンバの動きを変えたいときなどに使えそう。
2-22.「Character Analysis | 文字の判定」
http://edison-lab.jp/examples/strings/string-length/
スケッチは変更なしでOK。
シリアルでPCからきた文字を文字列にしてその長さを求める方法がわかった。
2-23.「Simple Web Server | LEDをネット経由で制御する」
http://edison-lab.jp/examples/wifi/simple-web-server/
35行目をpinMode(6, OUTPUT); に変更。
下記の上の「here」をクリックするとLEDが点灯し、下の「here」をクリックするとLEDが消灯する。ブラウザからルンバをコントロールする場合の参考となるスケッチと感じた。
2-24.「Web Server | アナログ入力値を表示するウェブサーバ」
http://edison-lab.jp/examples/wifi/web-server/
スケッチは変更なしでOK。
スライダー1の値が1018、スライダー2の値が0、スライダー3の値が610、CDSの値が782、温度センサの値が172ということが表示されました。
ブラウザにルンバやコントローラの値を表示させるのに使えそうな印象です。
3.ルンバの赤外線リモコン
下記サイトのスケッチで試みるも、取得できた赤外線リモコンの発光間隔のデータを送信してみるもルンバは反応せず・・・。試行錯誤してみたが断念。
http://blog.gorugle.org/posts/2014/11/ir.html
https://github.com/lostman-github/arduino/blob/master/Uno/IR/sample/sample.ino
取得できた時間間隔 (数回分の繰り返しを取得しているものもあります)
(1).「CLEAN」ボタン押下時
.269,295,96,96,293,94,293,93,292,285,100,98,291,93,293,95,2049,292,100,95,293,93,293,93,292,286,99,98,291,93,293,93,2050,293,100,95,294,93,293,92,293,286,98,96,293,94,293,93,
(2).「SPOT」ボタン押下時
.86384,296,96,97,293,93,293,93,292,94,292,286,99,97,292,93,2050,294,98,99,290,97,290,96,291,96,290,286,98,99,290,97,2048,292,98,97,292,93,293,94,292,94,292,286,98,97,292,93,2075,293,99,96,292,94,292,94,292,93,293,286,98,96,293,93,2050,295,96,97,292,94,292,94,292,94,292,286,98,97,293,93,
(3).「・・・」ボタン押下時
.86406,296,96,97,292,94,292,94,292,94,292,285,98,97,292,286,1858,296,96,96,292,94,292,94,292,93,293,286,99,96,292,286,
(4).「↑」ボタン押下時
.46980,296,96,97,292,93,293,94,292,93,293,95,290,286,99,96,2074,294,98,97,293,96,290,97,290,96,290,96,290,286,98,99,2048,294,98,97,292,94,292,96,290,286,99,288,98,96,292,94,2050,293,98,99,291,96,290,97,290,285,99,288,99,96,293,94,2050,296,96,99,290,93,292,94,292,94,293,94,292,288,97,96,2074,296,97,96,292,94,292,93,293,285,99,291,96,96,293,288,1856,294,98,99,290,97,290,96,290,286,99,288,98,97,292,286,1859,293,98,96,293,93,292,94,292,285,99,290,96,97,292,288,
(5).「←」ボタン押下時
.54891,294,98,97,292,96,290,96,291,96,290,94,293,93,292,288,1856,294,98,99,290,96,291,96,290,93,293,94,293,93,293,288,1856,293,98,97,292,94,292,94,293,94,292,94,292,93,293,285,6744,292,99,96,293,94,292,94,292,285,99,291,96,96,293,288,1880,296,96,96,293,93,292,94,292,288,96,291,96,99,290,288,1856,294,98,97,292,94,292,96,290,285,99,291,96,97,292,288,
(6).「→」ボタン押下時
.52140,294,98,96,292,94,292,96,291,96,290,93,293,287,97,288,1858,294,98,96,293,96,290,93,293,94,293,93,292,286,98,291,1856,294,99,96,293,94,292,96,291,96,290,93,292,288,97,288,1882,295,97,96,292,94,293,93,292,94,292,96,290,286,98,288,1858,294,98,96,293,94,292,94,293,286,98,288,99,96,293,285,1859,293,98,97,292,93,294,93,292,286,99,287,100,96,292,286,1883,294,98,96,292,93,293,96,290,286,98,288,98,96,292,285,
4.ルンバのシリアルポート
免責事項:以下ルンバへの自作機器の取り付け等を推奨するものではありません。いかなる損害賠償責任を負いません。自己責任にてお願いいたします。
ルンバには、ROIというインターフェースがついており、シリアル通信でルンバをコントロールできる機能があります。詳細な仕様は以下のPDFファイルに記載されています。
http://www.irobot.com/~/media/MainSite/PDFs/About/STEM/Create/create_2_Open_Interface_Spec.pdf
シリアルポートは本体のフェースカバーを外すとあります。
フェースカバーの外し方はこちらのビデオを参考にしました。
https://www.youtube.com/watch?v=yssfvP-vS_4
https://www.youtube.com/watch?v=PEk30wPorZ8
なかなか外れず苦労しましたが、数日おいてから再チャレンジしたところあっさり外れました。最初外れなかった原因は不明のままです。
次はルンバとEdisonを接続してみたいとおもいます。(ここまで2015/8/16記載)
5.ルンバの制御
5-1.Edisonとルンバの接続
下図のようにEdisonとルンバを接続します。
実際の配線図
5-2.先人のArduino用のスケッチで動作確認
ルンバを動かすサンプルスケッチについて先人のお知恵をお借りします。
http://qiita.com/DUxCA/items/36a13e68722c51c72927
↑ DUxCA様の「ArduinoからRoombaをSoftware Serialで動かす」の
「Roombaが左右に身を振り「イヤイヤ」をする例」のスケッチをつかわせてもらいました。
ArduinoIDEにソースをコピーペーストします。
下図のように、1行目と2行目をコメントアウトして
#define device Serial1
を追加します。
実行結果のビデオです。Edisonからの制御で、ルンバが左右に首を振る動作ができました!。
同じく
http://qiita.com/DUxCA/items/36a13e68722c51c72927
↑ DUxCA様の「ArduinoからRoombaをSoftware Serialで動かす」の
「ArduinoとPC(Processing)をつなぐ」をEdisonで実行した例です。
スケッチの1行目と2行目をコメントアウトして
#define device Serial1
を追加します。
PCのシリアルモニタから下の図のように「0」「0」「0」「1」「1」「1」「2」「2」「2」「2」「2」「3」「3」「3」とシリアル経由で送信した例です。
0が前進、1が左回転、2が左回転、3が後退です。
ルンバにシリアル経由で指令したコマンド
6.オリジナル機の制作
6-1.システムの全体像案
接続図
2つのEdisonを1つのPCに接続します。
Edison1=PC=Edison2
Edison1は、「2.スケッチサンプルを試してみる」で示したDangerSheildを載せたEdisonです。
こちらをルンバのコントローラとします。
Edison2は、「5.ルンバの制御」で示したルンバに接続したEdisonです。
まずPCとそれぞれにEdisonをUSBシリアルで接続してみます。
6-2.リモコンの仕様
6-3.リモコンのスケッチ
2章で試した以下の3つのスケッチサンプルを組み合わせます。
2-5. 「Digital Read Serial | スイッチ状態を読み込み」
2-12.「Analog In Out Serial | アナログのシリアル入出力 」
2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」
「2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」」
のコードに他の2つを組みこみます。
三個のスライダーの値と3個のボタンの状態をシリアル経由で読むように
2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」
に
2-5. 「Digital Read Serial | スイッチ状態を読み込み」
のコードを次ぎのようにコピーしていきます。
「2-5. 「Digital Read Serial | スイッチ状態を読み込み」」の
int pushButton = 12;
を2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」にコピーします。
「2-5. 「Digital Read Serial | スイッチ状態を読み込み」で変更したsetup()内の
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT);
digitalWrite(pushButton, HIGH);
を、2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」のsetup()内にコピーします。
「2-5. 「Digital Read Serial | スイッチ状態を読み込み」のloop()内の
// read the input pin:
int buttonState = ! digitalRead(pushButton);
を、2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」のloop()内にコピーします。
コピーした次の行に
Serial.print(",");
Serial.println(buttonState);
を追加します。
Serial.println(analogRead(bluePin));
を
Serial.print(analogRead(bluePin));
に変更します。
実行してみます
3つのスライダの値とともに一番右にボタンを押していないときは0、押したときは1に変化する項目が追加できました。
同様にして残りの2つのボタンについてもコードを追加します。
先頭ブロックに
int pushButton2 = 11;
int pushButton3 = 10;
setup()内に
pinMode(pushButton2, INPUT);
digitalWrite(pushButton2, HIGH);
pinMode(pushButton3, INPUT);
digitalWrite(pushButton3, HIGH);
loop()内に追加
int button2State = ! digitalRead(pushButton2);
int button3State = ! digitalRead(pushButton3);
loop()内の下記箇所を変更
Serial.print(",");
Serial.print(buttonState);
Serial.print(",");
Serial.print(button2State);
Serial.print(",");
Serial.println(button3State);
実行してみます
3つのスライダの値とともに、3つのボタンについて
それぞれボタンを押していないときは0、押したときは1に変化する項目が追加できました。
次にこのスケッチに、2-12.「Analog In Out Serial | アナログのシリアル入出力 」のコードをコピーしていきます。
仕様としては、A0のスライダーが左にあるほどD6のLEDを明るくし、右にあるほどD5のLEDを明るくするようにし、真ん中にあるときはD5,D6とも消灯とします。
const int analogOutPin = 6; // Analog output pin that the LED is attached to
int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
を次のように変更してコピーします
const int analogOutPin = 6; // Analog output pin that the LED is attached to
const int analogOutPin2 = 5; // Analog output pin that the LED2 is attached to
int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
// map it to the range of the analog out:
outputValue = map(sensorValue, 0, 1023, 0, 255);
// change the analog out value:
analogWrite(analogOutPin, outputValue);
を次のように変更してコピーします
// read the analog in value:
sensorValue = analogRead(redPin);
// map it to the range of the analog out:
outputValue = map(sensorValue, 0, 1023, 0, 255);
// change the analog out value:
analogWrite(analogOutPin, outputValue);
Serial.print(analogRead(redPin));
を
Serial.print(sensorValue);
に変更します。
これで3つのスケッチを1つにまとめることができました。
ここで、スライダの値が511以下と512以上で処理を分けます。
「2-20.「If Statement Conditional | “if”構文(2分岐選択)」」のコードを参考にして
const int threshold = 511; // an arbitrary threshold level that's in the range of the analog input
を追加し、
loop内の下記コードを
// map it to the range of the analog out:
outputValue = map(sensorValue, 0, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);
次のように変更します
if (sensorValue > threshold) {
outputValue = map(sensorValue, 512, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);
}
else {
outputValue = map(sensorValue, 511, 0, 0, 255);
analogWrite(analogOutPin2, outputValue);
}
これで以下のビデオのように一番下のスライダが中心より右側にあればあるほど右のLEDが明るくなり、左にあればあるほど左のLEDが明るくなります(カメラですと明るさの違いがよくわかりませんが、肉眼ではよくわかります)
6-4.PC側のスケッチ
「2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」」のスケッチの中には、
/* Processing code for this example
以下のコメントされている部分にパソコンのProcessingで動作するスケッチが記載されています。
http://edison-lab.jp/examples/communication/visual-color-mixer/
このスケッチを動作させたビデオが以下のとおりです。
シリアルから読み取った各スライダの値によって画面のRGBを変化させる例になっていました。
このProcessingのスケッチサンプルを改造していきます
Serial myPort;
を
Serial myPort;
Serial roombaPort;
へ変更。myportがEdison1との通信、roombaportがルンバ側のEdison2との通信のためのシリアルポート(USB経由)となります。
myPort = new Serial(this, Serial.list()[1], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
の後に
roombaPort = new Serial(this, Serial.list()[2], 9600);
// don't generate a serialEvent() unless you get a newline character:
roombaPort.bufferUntil('\n');
を追加します。
blueValue = map(colors[2], 0, 1023, 0, 255);
の次に
if(redValue>128){
roombaPort.write(48);
roombaPort.write(13);
}
を挿入する。
これでA0のスライダを左に寄せればルンバが前進するはず!
あれれ?無反応・・・動きません。
以下のようなコードを書いて状況をみてみます。
Edison2から謎の文字列が返ってきた。
teratermで接続して0と入力してみます
まったく同じ謎の文字列
** B0100000063f694
** B0100000063f694
が返ってくる。
どうやら同様の問題が発生している方がいる模様です。
いろいろ格闘してみたのですが解決策がわかりませんでした。
https://communities.intel.com/thread/77831
https://communities.intel.com/message/277230
ArduinoIDEのシリアルモニタから入力した場合には問題が発生しないので
ひょっとするとArduinoIDEのシリアルモニタは、Edison Virtual Com Port経由で
Edisonと何等かの特別なプロトコルでやりとりしている??
仕方がないのでUSBシリアル接続でのルンバ上のEdison1コントロールはあきらめることにしました。
6-5.Wifiでのルンバのコントロール
シリアル接続はあきらめ、Wifi接続に挑戦してみます。
「2-23.「Simple Web Server | LEDをネット経由で制御する」」
のスケッチサンプルに、
「5-2.先人のArduino用のスケッチで動作確認」の
http://qiita.com/DUxCA/items/36a13e68722c51c72927
↑ DUxCA様の「ArduinoからRoombaをSoftware Serialで動かす」の
「ArduinoとPC(Processing)をつなぐ」の
motor関数を2-23のスケッチに組みこみます。また、
#define device Serial1
device.begin(115200);
を対応する箇所に加えます。
さらに
// the content of the HTTP response follows the header:
client.print("Click <a href=\"/H\">here</a> turn the LED on pin 6 on<br>");
client.print("Click <a href=\"/L\">here</a> turn the LED on pin 6 off<br>");
を
// the content of the HTTP response follows the header:
client.print("Click <a href=\"/F\">here</a> Forward<br>");
client.print("Click <a href=\"/B\">here</a> Back<br>");
client.print("Click <a href=\"/L\">here</a> Left<br>");
client.print("Click <a href=\"/R\">here</a> Right<br>");
に書き換えます。
if (currentLine.endsWith("GET /H")) {
digitalWrite(6, HIGH); // GET /H turns the LED on
を
if (currentLine.endsWith("GET /F")) {
motor(64, 64);
delay(100);
motor(0, 0);
に変更します
同様に
if (currentLine.endsWith("GET /L")) {
digitalWrite(6, LOW); // GET /L turns the LED off
を
if (currentLine.endsWith("GET /B")) {
motor(-64, -64);
delay(100);
motor(0, 0);
に変更し、
if (currentLine.endsWith("GET /R")) {
motor(64, -64);
delay(100);
motor(0, 0);
}
if (currentLine.endsWith("GET /L")) {
motor(-64, 64);
delay(100);
motor(0, 0);
}
を追加します
ブラウザ上でクリックすると、Wifi経由でルンバを動かすことができました。
これでスマホからもルンバを動かすことができます。
6-6.PC側のスケッチ Wifi版
「2-19.「Visual Color Mixer | 複数のアナログ入力読み込み」」のスケッチの中の
Processingのスケッチサンプルに、
ProcessingのExampleのLibraries-Network-HTTPclientのスケッチサンプルの内容を組み込んでいきます。
import processing.net.*;
Client c;
String data;
を追加。
client.print("Click <a href=\"/V\">here</a> Vacuum<br>");
を追加。
background(redValue, greenValue, blueValue);
の後に以下の内容を追加。
if (redValue>128+64) {
// roombaPort.write(48);
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /F / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
if (redValue<128-64) {
// roombaPort.write(49);
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /B / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
if (greenValue>128+64) {
// roombaPort.write(50);
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /L / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
if (greenValue<128-64) {
// roombaPort.write(51);
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /R / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
if (blueValue>128) {
// roombaPort.write(50);
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /V / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
void vacuum(byte vac) {
byte buffer[] = {
byte(128), // Start
byte(131), // SAFE
byte(144), // Vacuum etc
byte(0),
byte(0),
byte(vac)
};
device.write(buffer, 6);
}
これにより
スライダ1が左よりにあるとき前進、右よりにあるとき後退、中間にあるとき停止
スライダ2が左よりにあるとき左回転、右よりにあるとき右回転、中間にあるとき停止
スライダ3が左よりにあるときに吸引、右寄りにあるときに吸引停止
となるはず。
実行してみます。各スライダの移動に応じてルンバが動きました!。
6-7.完成版へ
スイッチを押したときの動作の実装をしていませんでした。
以下のコードをEdison2側のスケッチの該当箇所に加えます。
client.print("Click <a href=\"/C\">here</a> Clean button on<br>");
client.print("Click <a href=\"/P\">here</a> Power down<br>");
client.print("Click <a href=\"/S\">here</a> Dock Button on<br>");
if (currentLine.endsWith("GET /C")) {
byte buffer[] = {
byte(128), // Start
byte(135) // Clean
};
device.write(buffer, 2);
}
if (currentLine.endsWith("GET /P")) {
byte buffer[] = {
byte(128), // Start
byte(133) // Power
};
device.write(buffer, 2);
}
if (currentLine.endsWith("GET /S")) {
byte buffer[] = {
byte(128), // Start
byte(133) // SeekDock
};
device.write(buffer, 2);
}
これにより、ブラウザからもお掃除のスタートストップができます。
次にPC上のProcessingのコードを変更します。
int swstartState =0;
int swresetState =0;
int swstopState =0;
int lastswstartState =0
int lastswresetState =0
int lastswstopState =0;
を追加。
draw()内に
// Clean
if (swstartState != lastswstartState) {
if (swstartState == 1) {
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /C / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
}
lastswstartState = swstartState;
// Power
if (swresetState != lastswresetState) {
if (swresetState == 1) {
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /P / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
}
lastswresetState = swresetState;
// Seek Dock
if (swstopState != lastswstopState) {
if (swstopState == 1) {
c = new Client(this, "192.168.179.7", 8080);
c.write("GET /S / HTTP/1.0\r\n");
c.write("\r\n");
delay(100);
}
}
lastswstopState = swstopState;
を追加。
serialEvent()内の
if (colors.length >=3) {
を
if (colors.length >=5) {
に変更。
blueValue = map(colors[2], 0, 1023, 0, 255);
の後に
if (colors[3] == 1) {
swresetState = 1;
}
else {
swresetState = 0;
}
if (colors[4] == 1) {
swstopState = 1;
}
else {
swstopState = 0;
}
if (colors[5] == 1) {
swstartState = 1;
}
else {
swstartState = 0;
}
}
を追加。
このあたりのロジックは、Edisonのスケッチサンプルの「2-11.「State Change Detection | シリアルモニタにボタンの状態を表示 」を参考にしました。
さてボタンを押してみます。
速っ。あせりましたが、お掃除開始、停止が無事に?できました。
これにて試作機の完成とします。
7.まとめ
・複数台のEdisonで開発する場合、どのシリアルポートにどのEdisonが接続されているか、シールなどを貼って明示しておくとよいようです。意外に混乱してしまいました。
・どうもWifiがオンになるなど何等かのタイミングでUSB1本での給電ではEdisonとPCとの接続が切断されたり、つながったり不安定になることがありました。バスパワータイプのハブを介して接続してから安定したようです。
・サンプルスケッチは、一通り実行してみることで、EdisonのArduinoでどのようなことができるかを知ることができました。初心者の方は一通り実行してみるとよいと思われました。
・複数のサンプルスケッチを組み合わせるには、若干のプログラミングの知識が必要になりますが、何もないところから作るよりもはるかに効率的にプロトタイプを作ることができます。
・本家Arduinoとの比較でいうと、WiFiを使う場合には、ArduinoUnoなどですと、WiFiシールドを別途購入する必要があります。しかし、EdisonであればWiFiはもとから搭載していますので、追加費用は必要ありませんし、ピンがWifiシールドのために使われてしまうこともなく、すべてのピンを利用できます。これは大変なメリットだとおもいます。
以上、ご覧いただきまして、ありがとうございました。
2015/9/23完
コラム ルンバの電源が入らなくなったとき・・
私の場合、Edisonと接続しているときは問題が発生したケースはなかったのですが、Arduino互換機を接続してArduino互換機に電源を入れたときに、ルンバの電源スイッチを押してもルンバが起動しなくなってしまう場合がありました。
以下のようにバッテリをいったんはずして、装着しなおすことで、復活できましたのでメモしておきます。
1.赤丸をつけた5カ所のねじを緩める↓
2.赤丸部分の2つの帯を両手でもってバッテリを外す
3.バッテリを外した状態
4.上記と逆順の3.2.1.の順に組み立てて元に戻す。
ZIGSOWにログインするとコメントやこのアイテムを持っているユーザー全員に質問できます。