(日々の記録)デジタルオシロを買った。(HC-SR04)のI2C化が難しい今回もブログの更新が長い間滞った。正直なものでブログのアクセス回数は間違いなく記事更新間隔に反比例する。商売ではないので別に構わないのだが、アクセスが減っていくのを見ているのは余り気分が良くないものである。この間、電子工作をやっていなかったわけでもない。最近になく没頭しているのだが、結果が出ないので記事に出来ないだけである。先月、EdisonのPWM動作をオシロで確認して、実際にサーボを動かしたところまでは順調だったのだが、そのあとがいけない。思いつきで始めた全く別の工作にはまり、泥沼から抜け出すことができなくなった。動いてはいるのだが、どうもすっきりした形にならない。その工作というのは、タイトルに書いた超音波測定ユニット(HC-SR04)のI2C化である。あとで詳しく説明するが、要するにAVRのGPIOでI2Cのスレーブ側を開発して、HC-SR04をEdisonでも動かそうという目論見である。気楽に作り始めて次々に落とし穴にはまって身動きが出来ないでいる。日をあけるわけにもいかないので、このあたりで、この一か月の経過をご報告しておこう。EdisonのPWMで2つのサーボモーターが同時に動いた(7/25/2015)前回記事にあるように、mraaライブラリーを使ってEdisonのPWM出力波形をオシロで確認することはできた。次はこのPWM波形で実際にサーボモーターを動かすことである。パンとチルトの角度(0から180)の数字をシリアルコンソールから入力し、PWMパルスに変換する。コンソール入力ソフトは、通常のgetchar()とかfgets()などの標準関数を使う。Linux(UNIX)の標準入出力関数にはAVRなどと違ってキー入力を教えてくれる関数がない。これなしにコンソール入力コマンドを出すと、そこで処理が止まってしまうので具合が悪いのだが今回はコンソール入力をキーにパンやチルトをやるので問題はない。コーディングそのものはたいしたことはない。Edison内の開発環境は、まともなエディターもなく(あのviしかない)、リストの印刷もできない貧弱なものだが、紙に印刷してからデバッグするような大層なことはやらないし、ウェブなどで制御するのはまだ先の話だ。やれば、角度3のパンだけ、>(ブランク)角度4(enter)とやれば、角度4のチルトだけということにする。テキスト入力(0から180までの数字キャラクタ)の解析(パース)は、入力の最後から文字を拾って行くというのが鉄則である。文字列の頭から解析しはじめると泥沼になる。擬似コーディングで何度もシミュレーションして仕上げる。いうパズル的なコーディングは久しぶりなので楽しい。PWMにつなぐのではなく、コンソール出力で2つの数字が間違いなくとりこめているかを確認する。2組の数字のときはやさしいが、一つだけの数字のときは、かえって面倒である。ふーむ、どうしても、後の組の数字が10倍になってしまう。何度もロジックを見直すが間違っていない。なったら、変数を片っ端から出力させてみる。いわゆるprintfデバッグである。文字数を出してみて原因がすぐわかった。標準入力は、文字列の最後に必ず'¥0'(0X00)がついて文字数がひとつ多いのだ。ロジックでは無精してブランク以外を数字(0-9)とみなしていたので、これも数字とみなされ、あとが10倍されていた。やれやれプログラムは書いたようにしか動かない。コンソール出力に目指す数字が出たので、本番のPWM入力に進む。こちらは、浮動小数点なので単純に数式をいれるだけですむ。このあたりのCプログラミングはLinuxなのでとても楽である。整数しか使えないときは、変数を32ビットにしたり桁溢れに気を遣ったりする必要があるが、全く心配しないで気楽にコーディングできる。以前に開発したmraaライブラリーのテストプログラムのソースをこのコンソール入力のプログラムに足して、いよいよサーボのテストである。サーボモーターの動力はとりあえず手持ちのリチウム電池で独立させる(サーボの突入電流をさけるためEdisonの電源と共用しない)。EdisonのコンソールでCプログラムをスタートさせる。プロンプトがでて順調に立ち上がった。カメラが上下と左右に同時に動いた。念のため入れたオシロには、数ミリsec遅れて出る2つのPWMパルスが映っている。片側だけの数字入力のテストもする。数字出力のテストがすんでいるので、それぞれカメラが、ピッ、ピッと左右上下に反応する。何でもないことだけれど無性に嬉しい。夢中になってカメラを動かして楽しんだ。(ここにパンチルトの数字をPWMに変えるCプログラムソースを置きます。何かの参考まで)「pantilt.c」をダウンロードEdisonで2台目のウェブカメラ完成(7/27/2015)サーボがコンソールから操作できるようになったので、勢いに乗って画像も出すようにしてみた。2台目のパンチルト式ウェブカメラである。カメラの操作はSSHで、画面はHTMLなので実用性はまだゼロだが、とりあえずでも動くことをこの目で見ておきたい。EdisonのコンソールをPC上で2つ立ち上げて、片側でウェブカメラを動かし、もう一方は、パンチルト操作のCプログラムを動かす。PCの方はブラウザーも立ち上げる。カメラは30万画素の操作キットのカメラだ。PCのウェブ画面で映像を確認する。パンチルトのコンソールに戻って、コマンドを投入する。カメラは、ビビッという音と共に所定の方向に向いた。画像は一瞬見えなくなるが、納まると画像が見えて、別のシーンが映った。ははは、出来た、出来たぞ。大きく動かしたときはカメラを固定した蒲鉾の板を手で持っていないと、ひっくり返る。こんな手元でも、自分の手以外で画像が変わるのを見るのは感動である。片側数値だけ(パンチルトどちらか)の操作は、カメラが余り揺れないので画像の乱れは少なくて済む。コマンドの投入で目指した目標にカメラの画面が移動できるか遊ぶ(これは意外と難しい)。いずれにしても、これで当研究所での2台目のパンチルト操作の出来るウェブカメラが実現した。これの具体的な用途はまだない。猫カメラはアクリルケースに入れないとこいつも攻撃される。残っていることは、カメラのパンチルト操作を画面の左右上下のバーでやれるようにすることだが、これは所長の不得意なウェブプログラミングになるのですぐには手が出ない。このあたりはアプリケーションによっても大きく仕様が変わるところなので簡単には先に進めない、とやりたくない理由を上げて自己を正当化する。次の野望は超音波測定ユニットのI2C化(7/28/2015)実は前から企画しているプロジェクトがある。EdisonのI2Cシフターを買って来たころ思いついた企画だ。SR04)が使用されないまま、ころがっている。一年ほど前にはやったことがあって当研究所も買ってあった。昔から秋月あたりで売っている、Parallax社のものと形態がそっくりで、価格がべらぼうに安い。通常の電子部品店ではなく、アマゾンなどから売り出され、最近は秋月やスイッチサイエンスなどの電子部品ショップでも売り出した。中華コピー品らしいが、動作報告がウェブに出るようになり、それほど評判も悪くなさそうだ。オリジナルは¥3000近くしているものが、¥400近辺である。当研究所にいつもコメントを寄せてくれる「ばんと」さんも以前動作報告されている。このユニットのインターフェースは5Vでアナログなので、EdisonやRaspiとは少々相性が悪い。このSR04を動かすArduinoのシールドがあるようだが、こちらは今さらArduinoをやるつもりはない。それにEdisonのArduinoボードは大分お高い。AVRか何かでI2CでSR04の測定の開始や、測定した距離値をディジタルで送るようにしてやれば、使い道が広がるのではないかと思う。Tinyの8ピンシリーズで実現することである。I2Cスレーブと言えば昔々、AVRを始めたころUSIインターフェースのライブラリを開発しているが、これはAtmel社のサンプルソースをほぼ忠実になぞったものでオリジナリティに欠ける。8ピンのAVRはUSIを持っていない。GPIOで作れば今度のやつはスクラッチなので大威張りだ。SR04距離測定ユニットのテスト。動いた(7/30/2015)おりしも時を同じくして、電子パーツショップのスイッチサイエンスのページに、件(くだん)のSR04のなかに不具合があるという記事が出た。問題があるという新製品の写真を子細に調べると、これはまさしくアマゾンで買った製品そのもので、秋月のものも写真で見た限りは同じである。スイッチサイエンスのページのとおりだとしたら大問題である。I2Cの前にここの実装を先にやって、本当に動かないのかどうか確かめてみることにした。I2CレシーブはTiny8ピンシリーズで実装するつもりである。これも時期を合わせたかのように、秋月でTiny85が妥当な価格で売り出された。こちらには以前、DigiKeyで送料無料にするゲタのひとつとして、Tiny85をいくつか買ってある(¥200前後だったか)。これでいきなり開発するのはちょっとハードルが高い。いうので、ちょうど手元にあったTiny861で実装にとりかかる。このあいだサーボモーターの実験をしたTiny861一式がブレッドボードに残っている。USIを使ったUARTが入っており手間が省ける。割り込みも使わない、タイマーひとつだけで、やってきたパルスの時間を測るだけである。大した時間もかからずにプログラムが出来た。結果としては、不具合は全くなく、問題なしに2cmから3.5m近くまで計測が出来た。確かに、3.5mあたりを超えると、Echoパルスが戻らずラインが1になったままになるが、リセットしなければ元に戻らないわけではない。再度トリガーパルスをかければ復帰する。とりたてて大げさに言うような不具合ではなさそうだ。スイッチサイエンスの使っているArduinoのプログラムなどでうまく動いていない可能性が疑われる。タイムアウトを設け、ある程度の時間、パルスが戻らなければ待つのをやめれば済む話である(当プログラムでもそうした)。SR04の動きは確認できたので、いよいよソフトI2Cスレーブの開発に移ることにする。このTiny861のセットに追加して実験し、うまく動けば、秋月で販売が始まったTiny85あたりで実装することにする。GPIOのソフトI2Cスレーブプログラムの擬似コーディングは終了(8/8/2015)GPIOによるI2Cスレーブの自作はI2Cマスターと違って、そう簡単ではない。Interface)というハードを使って、それもソースコードはAtmelのアプリケーションノートを丸ごと参考にして作ったものだ(デッドコピーではないが)。今度は、USIのないTiny8ピンシリーズが目標なので、これを利用することは出来ない。ソースを引っ張り出して調べる。割り込み駆動とUSIの機構を駆使した複雑な形だ。GPIO化にあたって重要な課題が見つかった。USIはI2Cのスタート/ストップコンディションを検知するハードを持っているのに、GPIOではこれも手作りする必要がある。I2Cスレーブはあくまでも受け身の立場なので、通信ラインのSDA(データ)とSCL(クロック)は、データの採集や、収集とは別に、独立して割り込みをハンドリングしていないと、スタートコンディションなどは採集することはできない。あわててTiny8ピンシリーズの割り込みラインを調べた。外部割込みはひとつだけだが、ピンチェンジが使える。何とか、この石でも2本の割り込みラインは確保できそうだ(デバッグ用のUARTは出力専用になるが)。Tiny861は外部割込み2本とピンチェンジ1本があるが、外部割込みは割り込み条件が2本で共通なのは注意しておかないといけない(実は開発途上で発見してえらい目に会った)。リソースの確認をして、いよいよ擬似コーディングにとりかかった。SCL(クロック)のパルスで駆動するのがI2Cレシーブの基本なので、どうしても割り込み関数の中が重くなる。C言語では、レジスターの退避などでタスクスイッチが重くなる。結局、ソースは、USIを使ったAtmelのアプリケーションノートのと同じような構造になってしまった。スタートコンディションを検知するルーチン(SDAのピンチェンジ)が悩ましい。このあたりは割り込みが重なり、オーバーヘッドが気になる。理屈ではこれで良いのだが、果たして考えたように動いてくれるか。3日近くかけて、擬似コードは何とか出来上がった。ISP-UARTでつまづいている(8/10/2015)I2Cスレーブの開発が一段落したので、実際のコーディングの前に、I2Cマスターのドライバーの制作に取り掛かった。I2Cマスターは、これまでに沢山開発しており、参考にするソースは選ぶのに迷うくらいだ。秋月のRTC(リアルタイマークロック)を動かした7年以上前のソフト(記念すべき最初の作品、温度ロガー)から、最近のLPCMプレーヤーのI2CインターフェースのLCDドライバーまで沢山ある。古いが、みなさんに使ってもらっているRTCを動かしたUSIを使ったI2Cマスターが信頼性が高そうなのでこれを選ぶ。いえば、このソースは、ISPケーブルで動くUARTが不調で、別のGPIOのUARTを使っている。良い機会なので、このデバッグもしてしまおう。UARTをISP-UARTで動くよう換装する。これが、つまづきの始まりだった。オシロで波形を見てみると、PCからのキー入力は入ってきているが、受信が全く動かない。何かループをしている感じである。デバッガーを入れれば何かつかめるのかもしれないが、この程度でデバッガーをセットアップするのも難儀な話である。ロジアナも、こういう暴走状態の時はあまり役に立たない。あーでもない、こーでもないとソースコードを調べるうち、遂に問題点を発見した。発見してしまえば何故こんな簡単な間違いに気が付かなかったのかと思うぐらい、馬鹿馬鹿しいミスなのだが、バグと言うのはこういうものである。ピンチェンジの受信割り込みで、ピンが立下りかどうかを調べるIF文の条件が間違っていた。これまでに何回も経験したつまらないミスだ。(1<<Pin番号)の結果を1で比較していたというお粗末である。最初のコードは、たまたまPin番号が0だったのでこれで動いていたのだが、ピンが移動していたのでバグになってしまったようだ。こんどは、USIを使った前のI2Cマスターが動かない(8/12/2015)ようやっとUARTが動いて、I2Cマスターの動作確認に入る。スレーブはまだ出来ていない。出来たとしてもいきなりつなぐのは無謀だ。確認はオシロで波形を調べることになる。ところが信頼性の高いと思われたUSIのI2Cマスターが思うような動きをしてくれない。最初は良いのだが、2回目になると全く波形が出なくなる。電源を切って、再度投入すると、1回目は動くがやはり次から駄目になる。一難去ってまた一難である。単なるドライバーのつもりのI2Cマスターのデバッグをこれからまたやらされる羽目になった。I2Cラインのハード設定がおかしいようである。I2Cのラインインターフェースはとても微妙に出来ていて、単純なポートのオンオフではなく、入出力方向の切替で行う。ラインをハイインピーダンス化する形でラインを上げるようだが、どうもこのあたりの設定がおかしい。迷ったが、これ以上USIのI2Cマスターのデバッグをする気力がどうにも生まれない。I2Cのマスターなら、まだ他にも手段がある。GPIOのもあるし、いざとなったらMegaシリーズのハードのI2Cを使うことも出来る。マスターの開発をしているわけではないのだ。GPIOのI2Cマスターは簡単に動き接続テストに移る(8/13/2015)お盆が近づいて事務所もお休みである。猛暑なので外に出かける気も起きない。このところ熱心に通っているジム(ヨガとプール)もお盆休みである。必然として、工作室にこもる時間が増える。日がな一日、電子工作で過ごすが、進展はいまいち順調ではない。使ったものにライブラリをとりかえる。このオリジナルは、ChaN氏のソースで、LPCMプレーヤーのミニLCD(I2C)に使っている。ChaN氏制作のソースである。はなから全く問題なく動いた。綺麗にオシロにI2Cマスターの一連の波形が並んだ。始めからこれにしておけばよかった。I2Cのマスター書き込み宣言は、スレーブアドレスがないということで戻ってきているが、これはスレーブ側が動いていないので問題ない。問題のスレーブのコーディングである。擬似コーディングから実際のソースに落としていく。SCLの両エッジの割り込みを受けて、ステートマシンでビットデータをハンドリングしていくのだが、スタートコンディションの検知と、ACK/NACKを伝えるステージのタイミングが難しい。実際に動くことを祈って、せっせとコーディング。ほどなく出来上がった。スレーブは、はなからロジアナの力を借りる。(8/14/2015)ISP-UARTのトラブルにこりて、ここは最初からロジアナでデバッグを始めることにしている。割り込み駆動のプログラムのデバッグは普通のprintfデバッグでは出来ない。マイクロセカンドオーダーで動く割り込みルーチンに、printfなどのミリセカンドレベルのルーチンを入れたらデバッグにも何もならなくなる。久しぶりのロジアナである。GPIOピンで沢山のプローブ点を入れ、逐一、ステートマシンの進行を追うことにする。各ブロックの入り口と出口にプルーブピンをいれて、これをロジアナで観察する。これまでのところ最強の解析手段である。ブレッドボードに2つのCPUを乗せ、スレーブ側、マスター側それぞれ1つづつUARTを立ち上げ、ついでにSR04も一緒に実装して、最終的には距離がマスター側のUARTに出力されるようにセットした。上には賑やかにロジアナのジャンパーコードが盛り上がる。スレーブ側はSR04の測定システムを兼ねており、スレーブのPCコンソールのリターンキーを押せば、距離値が出てくる。マスター側からの指示で、スレーブ側のHR04にトリガーがかかり、測定した距離値がマスター側のUARTに出てくるというのが、当面の最終ゴールである。開発の手段が少しわずらわしい。マスター側のUARTをISP-UARTにしたので、スレーブ側のコンパイルの度に、ISPケーブルを抜き差ししなければならない。それでも準備が整って、いよいよマスター側のコマンドでスレーブが動くかどうかを試すところまできた。