« 2017年12月3日 - 2017年12月9日 | トップページ | 2018年1月14日 - 2018年1月20日 »

2017年12月24日 - 2017年12月30日の1件の記事

2017年12月27日 (水)

ロボットアームのESP8266ワイヤレスリモコン化(続き)

ボタンの操作性を向上(12/8/2017)
 ロボットアームのリモコン(ESP8266のUDPクライアント)操縦用のボタン(スイッチ)は、5つのモーターの作動を指示するスイッチと、その正逆転の共通スイッチのひとつ、合わせて6つである。動かしてみるとやっぱり、アームの上下や左右の回転の操作は、それぞれが独立したタクトスイッチで動かす方がはるかに操作しやすい。

 しかし、ESP8266の使えるIOピンは6本が最大で、増やすわけにはいかない。というのでこのあいだ、I2Cで16チャネルまで増やせるI/OエキスパンダーIC(MCP23017)というのを秋月で買ってきてあるのだが、まあ、ここまでこだわることもあるまい。

 つらつら考えているうちにアイデアが浮かんだ。タクトスイッチは5X2の10個を並べ、対のボタンには、正転逆転のモードが同時に通電されるようなハード的なやり方を加えれば実現できるのではないか。例えばダイオードみたいなもので。

Tactsw_with_diode

 その昔、少年時代の頃、階段の明かりを単極双投のスイッチ2つでどちらから点けても、その先で消せるという回路を知って、ひどく感動した記憶がある。今度はそれほどでもないが、思いついたときは近来になく興奮した。

 でも、本当に動くのだろうか。これは試してみるしかない。小信号用の順電圧降下の少ないショットキーバリアダイオードの買い置きがある。早速、これを持ち出して同時に押す側のタクトスイッチから、正逆転のモードのピンと、本来の制御ピンに対して順方向に2つのダイオードをつなぎ、LEDをつけてみた。

 見事に、2つのLEDが考えたように点灯した。いやあ嬉しい。ウェブで調べると、キーマトリックスではダイオードが盛大に使われていることを知った。まあ車輪の再発明みたいなものだけれど、自力で思いついたところが偉いと自分で自分を褒める。

組み立てたけど動きが遅くなった。電池切れでもない(12/9/2017)
 遊んでいるうちに、アームの動きが急に鈍くなってきた。単一電池なのでまだまだ大丈夫なはずだが、グリッパーでものをつかんで運ぶのに結構長時間夢中になって動かしている。気がつかないうちに、電池がへたったのかもしれない。 Dsc01269

 オリジナルの電源は、単一電池4本を直列に接続し、その真ん中を共通グランドにして、これだけで正逆転の運転を巧妙に実現しているのだが、リモコンにするときは、この配列をモーター電源と制御電源(ESP8266とモータードライバー)に独立させて供給するように変更した。

 制御電源は、多くても数十mAしか流れない(但し、連続して流れる)。一方、モーターの方は数百mAではるかに消費が激しい。そこで、これを制御側と交換してみた。これで元気が戻るはずである。しかし、同じように勢いがない。ふーむ、これはおかしい。電池切れとは考えにくい。電圧を測るとモーター側もまだ一本1.5V近くある。

 マルチメーターで各部の電圧を測る。確かにモータードライバーのモーター出力は正規の1/3に近い1Vしか出ていない。念のため制御側のGPIO電圧も測る。おかしい。ここも1.8Vくらいしかない。ESP8266のGPIOピンのプルアップ不足かと思い、4.7KΩの少し強めのプルアップ抵抗をつけるが全く効果はない。

 モータードライバーDRV8835が早くも駄目になったのだろうか。ウェブで調べる。モータードライバーの損傷の原因は、過電圧、過電流、逆接続、モーターなどの逆起電力とある。電池なので過電圧はあり得ない。過電流に対してはモーター回路には用心して0.9A(遮断1.8A)のポリスイッチを入れてある。 逆向きに通電した覚えもない。

 ただ、モーターの逆起電力を抑えるダイオードは入れていない。考えられる原因は、やはり、逆起電力なのだろうか。しかし、リレーなどと違って正逆転するHブリッジのモーターの逆起電力を逃すダイオードの付け方がわからない。

 DRV8835がモータードライバーと銘打つからには、こうした備えは当然あると思うし、データシートには何の注意書きもない。しかし、現実には、モータードライバーがへたったとしか考えられない症状だ。仕事の帰り、秋葉原の秋月によって腹立ちまぎれにDRV8835を5つも買ってきた。

 交換する前に、念のため各部の電圧を測ってみた。すると奇妙な結果が出たのである。モーターの起動/停止ピンの電圧は低いが、左/右を決めるピンは、ばっちりVccと同じ電圧が出ている。

 おかしい。これは何か発振している。マルチメーターなので平均電圧しかわからないが、その可能性はある。 こうなると、オシロの出番だ。必要なピンにハンダ付けで臨時のプローブを出し、それをブレッドボードに差して動かないようにして慎重にIOピンの電圧波形を測定することにした。

オシロがお手柄。あけてみたら原因はハードではなくソフト(12/14/2017)
 実はオシロ測定に入る前に基本的なミスで大はまりした。こんどのESP8266受信サーバーは、モーターと制御系の電池を別にしているため、共通のグランドつまりローサイドで電源を切っている。これが原因で小一時間、頭を抱え込んでいた。

 念を入れてマルチメーターで電圧を測っていたときである。電源スイッチを入れてもいないのに電圧がでている。おかしい、どうしてだ。始めはスイッチがこわれているのではないかと疑った。しかしスライドスイッチがそうそう壊れるわけはない。

 ローサイドで電源を切っているときは、グランド側のプローブは、電池側でなく、スイッチの手前(回路側)にプローブをあてないといけないというのに気が付くまで暫く時間がかかった。図に書いたら一発でわかるミスだが、ブレッドボード上では中々わからない。実に情けない話である。

Dsc01265  この騒ぎが一段落して、やっと、オシロでGPIOピンの波形を出すところまで行った。そして、出てきた波形を見てさらにびっくりする。全く予想もしていない波形だった。最初、発振を疑っていたのでアナログっぽいランダムな波形を予想していた。

 それが、何とピンの電圧が、きれいなパルス状に出ているではないか。発振ではない人工的なパルス波形である。あっと思い当たった。これはソフトで作った波形だ。間違いない。

 動き始めた当初、暴走を止めるために受信メッセージが切れたときサーバー側で、とりあえず全ての制御を止めるロジックを入れた。こいつが原因に違いない。データが来るより、処理の方が速いため、次の受信データが来る前に制御は全部止まり、次のデータで再びONされる。

 マルチメーターでは平均電圧しかでないのでこの状況はわからない。ちょうどPWMのような動きをして回転が下がっているだけだ。モータードライバーはおかしくない。正しく動いている。全部自分が悪いのだ。モータードライバーさん疑ってごめんなさい。

 いやあ、世の中というのは恐ろしい。最初考えていた原因とは全く違っていて、犯人は暴走防止に気楽に入れたコードだった。ハードを疑った因果応報で、所長の本業のソフトの世界に弾が戻ってくるとは良く出来た話である。

無事、ロボットアームは元気を取り戻したが(12/16/2017)
 待ち時間を調整して、送る間隔と、受け取る間隔を同じにし、受信側も、受信データが来ない時は一定時間待ち、さらにデータの有無を聞いて、ないとき始めて制御を止めるロジックに変える。

Dsc01266  これで無事に普通のパルスが出た。ただ、どれだけ短くスイッチを押しても、100msちかいONになってしまうのが少し気になるが、とりあえずはもう大丈夫なはずだ。 もういちどロボットアームを組み立てなおす。試運転である。

 よーし、これまでへたったと思っていた単一電池でも元気よくアームが動いた。いやいや、お疲れさまでした。10個のボタンの制御はとても快適だ。まわりの消しゴムや、電池(単一でも持ち上る)を掴み、所定の位置に運んだりして遊ぶ。

 ロボットアームはワイヤレスで順調に動いた。動かすことが目的なのでこれでプロジェクトは大団円である。しかし、奥歯にものがはさまったように気になるところがまだひとつある。ワイヤレスのタクトスイッチをどれだけ短く打っても、モーターが100から120ms、動きを止めないことである。

 これはオシロで測ったときにわかったことなのだが、人間のタクトスイッチの押下の間隔は最小で50msくらいまで短く出来るはずなのにおかしい。実際の動作には殆ど影響がないのだが、何となく気になっている。

ロジアナでUDPを解析することを決断する(12/25/2017)
 現在クライアントとサーバーの間のUDP通信は17msという中途半端な時間間隔(オリジナルのまま)で送受信を繰り返しているが、この間隔で最小の動作時間が100ms以上というのは解せない。

 こうなってくると、オシロではわからない。もしかすると何かとんでもない動きをしているのかもしれない。データが溢れているのだろうか。UDPのパケットが未読のままだと、どういう状態でデータが残っていくのか、ウェブで調べてもはっきりとしたことはわからない。

 気になるといつまでも尾を引く、いやな性格である。オシロではなくロジアナで各部の動きを調べれば相当なところまでわかると思うが、ロジアナは準備が大変なのでなかなか決心がつかなかった。

 しかし、UDPの動きを知る良い機会でもある。ちょうど年賀状も出し終わって手が空いたところなので,結局、机の奥にしまってあったロジアナ一式を持ち出すことになった。

ロジアナで原因は一発で解明(12/27/2017)
 久しぶりのロジアナである。クライアントとサーバーの双方からプローブを引き出す。スケッチにはGPIO一本をつぶして動作点を記録するコードを追加して再ビルド。幸い双方にはUARTがついているのでこれも利用し、全体の動きを調べることにした。

Udpread  その結果、ロジアナはとても正直に実情を伝えてくれた。グラフを見れば一目瞭然である。受信側のデータの有無を調べる関数UDP.parsePacket()が正しく動いていない。暴走を避けるため、この関数を20msほど休んで再発行しているが、そのあとloop()の先頭に戻るので結果としてこの関数を連続して呼んでいることになる。

 UDP.parsePacket()は、連続して呼ぶと正しいデータを返さないようだ。いくつか空振りしたあとデータが入って処理が再開される。そのあいだの5回くらいの空振りが100msの原因だった。

Udp_read  要するに、Arduinoのloop()の中で、待ち時間を入れずにこのコマンドを実行させるとおかしくなる。まあ、通信関係では良くある、不具合とも言えないトラブルである。それにしても、ロジアナはいとも簡単に原因を解明してくれた。

 いやあ、さすがはロジアナだ。原因がわかれば解決は簡単である。loop()のUDP.parsePacket()が連続しないよう10ms程度の待ち時間を設ける。これでボタンの最小時間は50ms程度まで下げることが出来た。

 ま、しかし、それで動作が目に見えて早くなったわけでもない。完全な自己満足の世界だ。それでも何となくキビキビと動くように感じで(気のせいに違いないが)、気分が良い。

Dsc01276  こんどのスケッチのソースは、殆どが人さまからの借りものなので、ここで公開するのはためらっている。UDPのメッセージを漏らさずGPIOピンに反映させるのに少々手を入れたので、みなさんに使ってもらいたい気もするが、機種依存だろうから余り役に立たないかもしれない。

 もしどうしてもということなら、コメントかメールを頂ければ、ご送付申し上げる。

| | コメント (2) | トラックバック (0)

« 2017年12月3日 - 2017年12月9日 | トップページ | 2018年1月14日 - 2018年1月20日 »