EdisonのPWMをmraaライブラリーで動かす
mraaライブラリーでEdisonのGPIOは動いたが時間が不定(6/20/2015)
Edisonプロジェクトの進展は相変わらず遅々としている。理由は簡単で、Edisonで具体的に何を作るかが決まっていないからである。しかし迷っていても先には進まない。無理やり目標を決めて進むことにする。結局、EdisonもRaspberryPiと同じ、パンチルトの出来るウェブカメラに仕立てることにした。まあ監視カメラはいくつあってもかまわない。何かの役に立つだろう。
前回にご紹介したサーボモーター2つでカメラをパンチルト出来る操作キットをEdisonのPWMで動かすことにする。ウェブカメラそのものは、既にEdisonで無線LAN経由で動いているが、サーボモーターの方はAVRで動かしただけで、Edisonではまだである。
このあいだのEdisonマザー基板には、秋月で調達した1.8~5Vのレベルシフター(FXMA108)が仮止めしてあるが、配線はしていない。Edisonのピン出力は1.8Vなので、PWMで市販サーボを動かすためには、このシフターが必要である。
久しぶりのハンダ付けである。とりあえずEdisonのPWM(4本ある)と、ジャイロセンサーなどに使うI2C(これは2本)をアートワークした。5V出力は、20ピン2段のピンソケット(メス)をマザー基板に実装し、こちらからジャンパー経由で実験できるようにする。
EdisonのGPIOピンの制御は、定番のmraaライブラリを使う予定だ。待ちきれないのでPWM部分だけ配線してすぐにテストを始めた。いきなりPWMのテストはきついので、スイッチサイエンスのページのnodeソースを参考にGPIO(12)を使ってLチカを最初にやる。ここはたまたまPWM0とピンが同じなので新たに配線を追加する必要がない。
nodeは、感心にもmraaのライブラリーが用意されている(require('mraa')で動く)。Edisonのviでソースコードを入力する。これくらいの入力なら大した時間はかからない。早速動かしてみる。
オシロでまず出力を確かめる。おおー、出た出た。おやあ、パルスが時々動かないときがある。それより不審なのが、レベルシフター(FXMA108)を通しているのに、LEDの点き方が安定しない。オシロで見るとパルス状になっている。
このシフターの電源供給力はスペックによれば、ピン単位50mA(全体では100mAまで)もあるので、10mAのLEDぐらい楽々なはずなのだが、いかにも頼りない波形だ。それに、点滅の間隔がかなりでたらめなのである。0.3秒で動いていると突然、点滅が止まったりして一定しない。
nodeでは正確なLチカは出来ないのか(6/26/2015)
あわてて、ウェブにお伺いをたてる。やっぱり時間は正確にはならないと書いてある。しかし、msレベルならともかく、こんなに不正確なのだろうか。現在の300msの間隔でも正確なパルスになっていない。Edison用のこのYocto Linuxは、一般のLinuxと同様リアルタイムOSではない。同時に沢山のプログラムが動いているので、正確な待ち時間は作れない。
考えてみたら、nodeのsetTimout( タイムアウトで呼ぶ関数, 待ち時間ms)は、再帰関数的な使い方で、確かに、そのあいだにコンソールに出力はしているし、無線LANの応答もしているだろう、LinuxはリアルタイムOSではないからそれまでと言ってしまえばおしまいだが、こんなに時間がまちまちなのはどうも納得できない。
Yocto LinuxにはリアルタイムOSにするためのオプション(PREEMPT_RTパッチ)があるらしいが、カーネルの再構成が必要である。そんな大げさなことはできないし、これで解決するとも思えない。
nodeではだめなのだろうか。いろいろ資料を探す。console.log()などのコンソール出力を省略すると、少しはまともになるが、時々、ずっこけて点滅をさぼるときがあることは変わらない。時間に厳密なPWMではこんなことは起きないだろうが、気になると先に進めない性分である。PWMそっちのけで色々ウエブを探し回る。
Edisonのクロスコンパイル環境の整備が難航(6/27/2015)
しかし、この状況を説明してくれるサイトは見つからなかった。そのうちこれにばかりこだわるのも時間の無駄のような気がして、正式なCでプログラムを組んでみようということになった。CにはCPUループを使ったsleepなどの時間待ちの標準関数があり、nodeのようなプロセスをまたがるような待ちではないので少しは正確なはずだ。
Edisonでのプログラム開発は面倒(エディターがviしかない)なので、このあいだやったPCのUbuntuで、Edisonのクロス開発をすることにする。ところが、Ubuntuに構築したはずのC言語開発環境をどう使ったらよいのか分からないのである。
Ubuntuに入れたのはEdisonカーネルの再構成のための環境で、Makefileで動く。情けないことに、ここにmraaのライブラリをどうやって組み込むのかがわからない。下手なライブラリのインストールで、折角作ったカーネル再構築の環境がおかしくなるのは避けたい。
ということで、これとは別に簡単なgccのクロス開発環境をこのサイトの案内で作ることにした。ここでEdisonの実行形式のプログラムまで作り(ここなら全画面エディターのgeditが使える)、Edisonへの実行ファイルの転送は、scpというコマンドを使う。
順調にインストールが済んだので、サンプルプログラム("Hello World")を入力し、gccを動かしてみる。コンパイルが出来て実行ファイルが作られた。scpでEdisonに送ってみる。これも簡単に送れて、Edisonで実行すると無事"Hello World"が出た。よーし、好調だ。
ところが、何故か肝腎のlibmraaのコード一式が別のところにインストールされてしまってリンクできない。/sysrootが決め手だったというサイトの言葉がカギなのだろうが、このあたりの技術レベルは見よう見まねレベルなので先に進めない。mraaが入らないのでは、何のために別の環境を作ったのか意味がないことになってしまった。
/sys/class/gpioでGPIOピンが動かない(6/30/2015)
まあ、クロス開発ができなくても、Edisonの中でもやろうと思えばプログラム開発はできる。Edison内でのmraaライブラリは、opkgで大分前にインストールに成功している。エディターさえ我慢すれば、規模の大きなプログラムでない限り大丈夫だ。
開発環境を調べているうち、さらに/sys/class/gpioという仮想ファイルを使えば、簡単にGPIOピンの操作が確認できることがわかった。脱線だがハードの状況を調べられる複数の方法があるのはありがたい。早速これを試してみる。
ところが、これがさらに暗礁に乗り上げて、一歩も先に進まなくなったのである。肝腎のGPIOが想定通り動かない。ピンの定義であるexportと、direction(入出力)の定義は問題なく済んでも、実際の値(value)が入らない。mraaとは違う枠組みで動いていると思うのだが、オシロで見る限り、ピンが動いていない。
しかも、汎用的なピンであるはずのGPIO40番(mraaでは37番、ややこしい)は4Hzで発振している。EdisonのI/OピンはUART以外にはどこも接続されていないはずだが、どうもすでに定義済みのピンがいくつかあるようで、export自体がエラーになるピンもある。わけがわからない。
ウェブで心当たりを探すが、このあたりを詳しく解説したサイトを見つけることができない。ちょうどソフトとハードの中間の世界なので詳しい資料が不足している。
そのうち、node.jsで不正確ながら動いていたGPIO(20)ピンもオシロで反応しなくなった。うーむ、これはどうしたことなのだろう、ハードだろうか。どうもGPIO(40)の発振といい、Edisonのハードそのものがおかしくなっている疑いが強くなってきた。
Edisonブレークアウト基板をもうひとつ買ってセットアップする(7/4/2015)
久しぶりに秋葉原に寄る。迷っていたが、もう一台のEdisonを買うためである。少し見ないうちに、秋月電子の界隈は大きく変わっていた。向いの空き地に立派なビルが建って人の流れが変わっている。しかしメイド喫茶の客引きと外国人の団体は相変わらずで歩くのが煩わしい。
今日は、本体以外にI2Cのコンバーター(FXMA2102)を買うことも目的の一つだ。このあいだの8チャンネルのレベルシフター(FXMA108)はプルアップが出来ないのでI2Cは接続できないということを知り、これを調達する。秋月の商売上手はさすがである。I2Cの配線をしていなかったのは幸運というか先見の明があったというか。
Edisonは本体だけでなく、ブレークアウト基板も一緒に揃える。前のブレークアウト基板は、充電中を示すLEDが点かなくなっているからだ。I2Cで何をやるかは決まっていない。I2Cで制御できる多チャンネルサーボ基板があるというので、これは将来のロボット構築に向けた準備でもある。
帰宅して早速、2号機のEdisonブレークアウト基板をセットアップする。一応、nodeのウェブカメラサーバーが動くところまで作る。2回目なので作業は順調に進む。今度のYocto Linuxのイメージには、既にmraaライブラリがインストールされていた。
ついでに、前記事で紹介したIPアドレスの固定化のためWiFiのwlan0をいじる。起動スクリプトでIPアドレスの設定をDHCP側にお願いするのでなく、単純に固定IPの設定をするだけである。簡単に変更できた。node側はこのアドレスで決め打ちにする。テストする。問題なく動いた。
マザー基板に差すには、2号機にもピンソケット(オス)を実装する必要があるが、その前に、 サンハヤトのスルーホールに差しこんで使うジャンパーを活用して、2号機での/sys/classのGPIOピンの状況を調べ始めた。すると驚くべきことがわかってきた。
何と使えないGPIOピンが沢山ある(7/6/2015)
これは驚いた。2号機でもおかしいのだ。使えないピンが続出した。ところがウェブサイトに出ているピンを試すとこれだけは動いている。サイトで使っているピンは大丈夫なのだ。一体これは何だ。
ちょっと脱線になるが、しらみつぶしに、GPIOピンを調べて行った。驚くべきことに、作動するピンと動かないピンがあることがわかった。
動かない状態は、2つあって、一見、sys/class/gpioXXが動いているように見えて(in/outのdirectionと1/0のvalueをノーエラーで受け付ける)、ピン上では何の変化もないもの。
もうひとつはgpioXXの仮想ピンの定義が、最初からdevice busyでexportを受け付けないものの2種である。このことは、ウェブサイトを探したが、どこにも書いていない。
サイト(Qiita)でまとめていただいたEdisonブレークアウト基板の早見表に、今回のテストの結果を加えてみた。GPIOとしてまとめたピンのところである。備考のところの赤が動かないピンで、青が動くピン、備考のところにこのGPIOピンに重複定義されている機能名を付加した。
これを見ていると、どうも、Yocto Linuxの立ち上げで動かしたデーモンあたりがこのピンを定義し、そのあと正しくピンを解放していないのではないかと思われる状況である。動かないピンは特定の機能に集中している。UARTピンが2つともbusyなのは当然だが(それでもUART1は使っていない)。
カメラを動かしたEdison1号機にヒートシンクをつけるが熱暴走(7/7/2015)
動作がおかしくなっている一号機でもGPIOピンの状況を調べた。全部のピンは調べなかったが、調べた限りでは(5~6本)すべて同じ状況だった。
ついでに、2号機に加えた変更(IPアドレスの固定化)をこちらにも与えてテストする。カメラを動かしてみる。問題なく動く。ただ、こちらの方が少し熱を持つようだ。
温度計で測ってみると、50℃を軽く超える。不安になったのでヒートシンクをつけてみた。 温度上昇は少し鈍化したが、60度近くになる。1時間程動かしたところでハングアップした。うーむ、ヒートシンクだけでは長時間には耐えられない。冷却ファンが必要かも。
しかし、こんなに熱かったかなあ。前はもっと低いところで安定していた。1号機には何か別の問題がある可能性が高い。GPIO(37)で4hzの発振信号が続いているなど、I/Oピンに不審な動きが多すぎる。
1号機でシリアルを失ったのは、やはりショートか(7/10/2015)
ヘッダーピンの実装のため、Edisonの2号機をブレークアウト基板から外した時のことである。2号機の裏面が絶縁ラベルで覆われている。おやあ、 1号機は違っていたような気がする。確かめてみる。
やはり、そうだ。1号機の裏面は表と同じようにアルミ生地のままプリントされている。ふーむ、何故変わったのだろう。閃きが走った。以前、この裏面とブレークアウト基板のピンヘッダーの配線部が接触していて、あわててはみ出たピンをニッパーで切り取ったことを思い出した。
そうか、当研究所で起きた事故が他でもあったのだ。それで、ここの表面が絶縁されるようになったのだ。シリアルが動かなくなったのは、このショートに違いない。
やっとEdisonでPWMが動いた。nodeのLチカも正確になった(7/14/2015)
道草を食っていたが、やっと2号機でPWMを実験する気運が盛り上がってきた。実はmraaのPWMの操作は実に簡単で、ピンを初期化した後、周期(usか秒)とduty比を整数と浮動小数で設定するだけである。
サンプルコードはここを参考にさせてもらう。サーボモーターはPWMで、一般的な仕様では周期は10から20ms。仮に15msとすると、大抵のサーボは0.5msから2.5msのパルスが動作範囲である。このduty比は0.033から0.166である。この間で動かせば、サーボが最大幅動く。中点は、1.5/15 = 0.100である。
Cソースの入力は10分もかからない。コンパイルも一瞬で終わる。問題なさそうである。本体のサーボに接続する前に、オシロにレベルシフターの出力を入れてテストする。
恐る恐る、コンソールからプログラム実行のキーを入力する。おーし、プログラム通り0.5msパルスが1秒ごとに少しづつ増えて2.5msまで進んだ。コンソールにもduty比の数値がならぶ。浮動小数点が気楽に扱えるというのは、フラッシュの少ないAVRと違って贅沢なものだ。
いやあ、ここまでが長かった。とりあえずはオシロ上だけだがEdisonでPWMが動かせることを確認した。今はPWMの1チャンネルだけだが、コンソールからパンチルトの2チャンネルのPWM値を入力し、自由に2方向にカメラを動かすことを次のステップにすることにしよう。
勢いに乗って、このあいだの 1号機では不正確だったnodeのLチカプログラムを2号機でも動かしてみた。これが何と、全く正確にパルスが生成されたのだ。暫く動かしていても、パルス幅が乱れることは全くない。
何ということだ。時間が不正確なのは、nodeのsetTimoutなどの関数ではなく、1号機の別の原因によるものだった。今のところ、ハードかソフトかはわからない。動画ストリーミングで高熱になるのも何かこれと関係あるような気もする。
| 固定リンク
| コメント (2)
| トラックバック (0)
最近のコメント