カテゴリー「AVR」の107件の記事

2017年9月 2日 (土)

ソフトI2Cはクロックストレッチまで手を出してあえなく沈没

 I2Cのスレーブライブラリの改訂が泥沼に入り込んだまま動けない。アナログの超音波距離計測センサーHC-SR04(以下SR04)を、電源3.3V、I2C化したブレークアウト基板を作ったところまでは良かったが、そのあと、計測を高速で動かそうとして、ソフトI2Cスレーブのプログラミングに大苦労し、気が付いたら一か月が経っていた。

 そもそも、このTiny85を使ったソフトI2Cのライブラリーは、もう2年も前に開発したもので、ソースコードまで公開している。今度の開発でいくつかの不具合が見つかったので、改訂版を出せばそれですむ話なのだが、せっかく再公開するのだから、もう少し機能を増やしておこうと欲を出したのが間違いの始まりだった。Dsc01170

 ソースコードをレビューしているうち、最初の版は、I2Cのマスター読み込みのストップコンディション検知が未実装だったことがわかった。ブログ記事では作ったことになっているが、ソースコードを読んでみると実装されていない。

 スレーブからマスターへの送信(マスター読み込み)の終了は、最後のデータバイトにマスターがNACK応答を返せば止まるので、ストップコンディションは不要と言えば不要である。しかし出来ていると書いてしまった手前、放置するわけにもいかなくなった。それにマスター書き込みの方は、リピートスタートまで(もちろんストップも)実装したのに、何となく落ち着きが悪い。

 そこで、これを追加しようと気楽にコードを加えたのだが、これがうまくいかない。出来上がったプログラムはどうやってもストップコンディションを受け付けないのである。マスターはストップコンディションを出しているはずなのにロジアナで見ると波形が出ていない。謎である。

 脱線につぐ脱線というのが、がた老AVR研究所の通例ではあるが、今回はどうもいけない。迷路に入りすぎだ。I2Cのスレーブ側のプログラムは、すべて割り込み駆動で、SR04を制御するバックグラウンドルーチンとは非同期で同時に動く。デバッグは一筋縄では行かない。

 こういう細かいことに興味のない読者の方々には申し訳ないが、実は所長は、こうした箱庭のような8ビットマイコンのマルチタスク的プログラミングが好きで、つい深入りしてしまう。ロジックアナライザーで全体の様子が手に取るように把握できるようになったので余計やめられなくなっている。

 以下は、この泥沼のようなプログラム開発の一か月の顛末である。しかも今回は撤退に次ぐ撤退の苦しい開発となった。まあ、こういうときもあると自分を慰めている。

懸案のI2C通信と計測の同時処理はあきらめる(8/6/2017)
 前回記事で、SR04のエコーと、I2C通信の共通変数(タイマーキャリーカウンター)を分離して、正しいデータが出たと喜んだのもつかの間、少し待ち時間を短くしていくとまたデータが不正確になってきた。どうも距離の計測値が低すぎるし、安定した値がでてこない。

 ソースコードをもう一度入念に調べる。すると、共用していないはずのタイマールーチンに続々とおかしな使い方が見えてきた。要するに被っていたのはキャリー変数だけではなかったのである。

 まず、肝心のタイマーのおおもとのレジスターTCNT0をI2Cが始まるたびに0に戻していた。最大でも0.26ms(8ビットのオーバーフロー)、音速にして5センチ余りの誤差は、今度の用途(人感センサー)を考えると、そう大きな問題ではないが正確でなくなることには間違いない。Ws000029 さらに、I2Cの通信が終わるたびに、タイマーのオーバーフロー割り込みを止めてしまっていることが判明した。タイマーそのものは動いていても、8ビットタイマーのキャリーが増えていかないのは致命的だ。これが、ときどき距離が不正確になる犯人であった。

 この一週間、デバッグに奔走していた。調べれば調べるほど、エコー時間計測とI2C通信の非同期処理は不可能であることがわかってきた。要するにタイマーが一つしかないところで、タイムアウトと計測を一緒にやろうというのが無理筋だったのである。

 とにかく、こんなにリソースを共用していたらマルチタスクもあったものではない。計測期間中にI2C通信を行うソフトの開発は中止することにした。今回の無駄足は疲労感が強い。もっと早く気が付くべき基本のところを忘れて、深入りしてしまったからだ。 

 当初の方式、センサーのエコーを少し長めに待ち(SR04の最大エコー30ms程度)、データを読み込む方式に戻した。これでも100ms以内で連続して計測が出来る。まあ、人感センサーならこの程度で十分だろう。

マスター読み込みのストップコンディション検知にチャレンジ(8/16/2017)
 エコー期間中にI2Cを動かして計測間隔を短縮しようという目論見は完全にはずれた。意気込んでプログラミングをしようと振り上げた拳(こぶし)の行き先がない。この高ぶった気分を鎮めるために、何か手を動かさないと納まりがつかなくなってしまった。

 そこで、未実装の「マスター読み込み」シーケンスのストップコンディションの検知機能を開発することにした。しかし、これも難儀したのである。しかけは、「マスター書き込み」と同じように最初のデータビットのクロック(SCL)立ち上がり区間で、データライン(SDA)を監視して、ストップコンディションを判定する。

 「マスター書き込み」では、スタートコンディション(これはリピートスタート)もストップコンディションも順調に検知し、動作も確認している。簡単に動くだろうと気楽にコーディングしたのだが、全く動かない。かえって、全体の動作が不安定になってしまった。Dsc01195

 いつものロジックアナライザーにプローブ点を増やして解析する。波形を見ると、マスターがストップコンディションを実行しているのにSDAが上がっていない。つまりストップコンディションが発生していない状態であることが分かった。謎である。

 メモに何枚もタイミングチャートを描いて調べていく。ひとつづつの動きを詳細に確認していくと、驚くべき事実が浮かび上がってきた。「マスター書き込み」なら容易に出来る処理は、「マスター読み込み」では不可能ではないかということである。

ソフトでストップコンディションは作れない(8/20/2017)
 誤解を招かないように補足すれば、ソフトウエアでは実現できないということである。ハードウエアならSCLがHIGHのときのSDAの動きを監視する機構を加えれば良いので問題はない。しかし、ソフトでは同時処理が出来ないので、「マスター読み込み」ではSCLクロックが来る前に、スレーブは次に送るべきビット値を用意してSDAに乗せておかなければならない。

 もし、その値がLOW(0)のときは、ストップコンディションを阻止してしまい、スレーブ側ではそれを検知できないということになる。そもそも、「マスター読み込み」はスレーブ側がSDAラインを上下させてデータをマスターに送る。スレーブがSDAを下げてしまうと、マスターはこれをHIGHにすることが出来ない。

 元から不可能な機能を作ろうと、もがいていたことになる。ack/nackビットを受け取って次のデータの第一ビットの間中SDAラインをスレーブは占有してしまうので、スタート/ストップコンディションをマスターが出せないのである。「マスター書き込み」では、SDAラインはマスターが制御するので問題ない。

 とにかく、「マスター読み込み」のとき、ソフトでスレーブ側のストップコンディション検知は実装できないことが明らかになった。この2週間余りの作業は全く無意味なものになった。お馬鹿としか言いようがない。エコー期間のI2C騒動と、このストップコンディション開発を撤退するにあたり、反省をこめて何が悪かったのかまとめてみる。

教訓:

  •  一度に複数の機能をデバッグしてはいけない。どれが原因か特定するのが難しい(欲張るな)。プログラムをなめてかかって、いくつかの機能をまとめてコーディングしていた。原因が見つけにくいうえに、単独でバグをつぶしていくより、結果として余計な時間がかかっている。
  • 基本的な機能から確認していかないと何をやっているのかわからなくなる(急がば回れ)原理を理解せずに、小手先のコーディングが多すぎた。タイミングチャートをいくら詳しく描いて、コードを工夫しても、I2Cの基本を忘れていたら何にもならない。
  • 思い込みは可能な限り見直す(これは定数だから変わらないと思い込むな)わかっているはずなのに、この思い込みというやつは魔物である。すべてを疑うという視点をなくさないようにと気を配っていても、つい先のことに気を取られて基本部分を忘れがちになる。

 やれやれ、現役時代、さんざん後輩に言い聞かせてきた原則ばかりである。このブログにも偉そうに何度も同じようなことを書いてきた。それがこのざまである。お恥ずかしい。まさしくプログラムは考えたようには動かない、書いたようにしか動かない、である。

 この記事はあとから書いているので、まだ冷静な話になっているが、デバッグの最中は暗中模索、ロジアナの前で悪戦苦闘であった。もうやめようかと何度も思った。Tiny85のファーム書き換えはSR04を外す必要があり、ビルドを繰り返しているうち、ブレッドボードの接触不良で動作が不安定になったりする。散々である。

 ただ、ロジアナの威力は今さらながらすごいと感動した。プローブの数を増やしていけば、色々な所の可視化が可能になる。今回も、マスター側からもプローブを出せることに気づいたのは大きかった。これによって、マスター側が正常に動いていることを確認でき、自分の愚かな思い込みに気づくことが出来たからだ。

超音波センサーユニットの配線図とライブラリソースコードの再公開(8/19/2017)
 とにかく開発は一段落した。ライブラリーも安定して、これまでのように時々、0値が連続したり、異常値が出たりすることはなくなった。思い当たる不具合は、これまでのところ全部つぶした。

 最後までわからなかった偶に起きるデータ異常値は、ロジアナの波形を精密に調べなおして、SCL割り込みがタイマー割り込み(オーバーフロー)によって遅れ、その結果、SCLクロックが外れているのを発見した。I2cslaveoverhead

 タイミングによっては、これがスタート/ストップコンディションとみなされ、そのあとのデータが欠落する。Tiny85のCPUクロックは8MHzで、内蔵CRクロックなのでこれ以上は上げられない。SCL割り込みのオーバーヘッドは8μs内外で、クロックが40Khz(半サイクル12.5μs)のI2Cでは、ギリギリである。

 I2Cはこれ以上遅くしたくないので、タイムアウト用のタイマーの割り込みを起こさないようにするしかない。プリスケールを8から64に上げ、メッセージが16文字以内なら割り込みが起きないようにした。テストの結果、20文字以上送っても、数値の乱れはなくなった(必ず起きるわけではない)。

 お約束のソースコードと配線図を掲載する。I2Cライブラリーそのものは上記のようにすべて改善に失敗したが、マスター側とSR04制御部には若干の機能を追加してある。
 以下に例によってZIPで固めたソースライブラリ、readme.txt、配線図ファイル(.bs3)を置きます。 
   「I2CslaveSet_2.zip」をダウンロード

 コマンドの解説など詳しくはreadme.txtに説明した。以前の公開したライブラリーはうまく動かないところもあるので、この版のライブラリを使われることをお勧めする(当該ブログ記事にも注記)。

I2CスレーブライブラリーとSR04測定ルーチンの改善点(8/21/2017)
 テスト用の親機のTiny861とのペアで追加した機能と、修正した不具合の部分を以下にまとめておく。

I2cslave_85_2

追加した機能:
(1)    連続距離測定
SR04の距離測定が0.2秒間隔で開始され、UARTコンソールに測定値が1行づつ表示される。人感センサーなどで機器を動かしながら最適位置を見つけるのに便利。リターンキーを押すことで測定は中止される。

(2)    スレーブ側からの独自データ送出
サンプルとして、スレーブ側のソフトのバージョン番号をフラッシュに定義し、それを表示させる。I2C化するディバイスのレジスター値などを表示するのに使える。

(3)    バッファーデータの16進データ表示
スレーブの持つ送受信バッファー(36バイト)を全部表示する。本来はデバッグ用。

修正した不具合
(1)    マスター読み込みでのスレーブ側の不正データ送信のバグ修正
タイマー割り込みのオーバーヘッドで、送ったデータが欠落したり、文字化けが起きていたのを修正。

(2)    スレーブ側の連続データ送出でのバグ修正
マスターから送ったデータの戻しでバッファーサイズ分を全部表示できなかったのを修正。

 いやいや、長い間かかったけれど、何とか納まった。ウェブで見る限り、AVRマイコンでソフトI2Cスレーブの開発例は殆どない。あっても、すべてUSIというAVR独自のハードインターフェースを使ったもので、この開発のようにGPIOだけで作った例はひとつもない(自分で探した限り)。

 ちょっと鼻が高いのだが、これは完全な自己満足の世界である。ということで、さらに挑戦しようと、欲を出して恥の上塗りをすることになった。それが、次に紹介するクロックストレッチの実装である。まあ、笑わずに聞いてください。

クロックストレッチ実装の野望、もろくも砕ける(8/23/2017)
 I2Cは、原則、すべての通信の主導権をマスターが握っており、マスターの出すクロック(SCL)に従って複数のスレーブが動作する。これに対し、クロックストレッチとは、I2C通信でスレーブが、マスターを待たせる唯一の手段である。

 スレーブの処理速度が遅く、マスターの要求に応えられないときなどに使う。SCLラインをいずれかのスレーブがLOW(0)に落とすことによって、マスターはSCLの発行を止め、スレーブが解放(HIGH)にすることで再開する。
実装は簡単に見える。マスター側で、クロックライン(SCL)を監視していて、誰か(スレーブの誰か)がSCLをLOW(0)に落とせば(いわゆるワイアードNOR)、それがHIGHになるまで通信を止める(クロックパルスを延期する)。

 スレーブ側はもっと簡単である。必要な時にSCLをLOWにしてしまえば、すべての交信はストップする。また、HIGHに戻せば、マスター側が待っているから再開する(はず)。鼻歌交じりで、双方をコーディングし、勇んでテストに入った。これが地獄の始まりとは露知らず。

 テストの前は、クロックストレッチが実際に行われているかの実測のため、タイマーを再整備したりして余裕だったのだが、実際には全く動かなかった。スレーブでクロックストレッチをかけた途端、すべての反応は止まる。ハングアップである。

 ロジアナで様子を見る。通信シーケンスは、スレーブがクロックストレッチをかけたとみられるところから、見事にSCLがLOWになったまま、最後まで動かない。あれ、おかしい。マスターが待つのはともかく、スレーブがどうして引きすられる?

 スレーブには1秒タイムアウトが設けてあって、I2Cの通信が1秒以内に終わらないと通信を終了させて初期状態にもどるようになっているはずだ。

 あっあっあー、だめだ。スレーブ側の割り込みプログラムのなかで、SCLがHIGHになるのを待っている。これではバックグラウンドのコマンドでいくらSCLを元に戻そうにも、永遠にバックグラウンド側に戻ってこない。いわゆるデッドロックである。

 悪あがきで、多重割り込みでスレーブ側に短いタイムアウトを設け、別のところで待つようなしかけも考えた。avr-libcには多重割り込みを認めるマクロはあるが(リニアPCMプレーヤーで使用)、今度の場合は、バックグラウンドに戻っても、スレーブの割り込みプログラムに帰れないので意味がない。

 クロックストレッチをスレーブ側が要求するとき、あらかじめ割り込みルーチンの進入を止めておくという姑息な方法もあるが、マスター側の通信要求がいつ発生するか分からないときに、スレーブを止めるのは著しく可用性を失う。

 要するに、ハードでのみ実現できる機能で、そもそもソフトでやろうというのが無謀だったのだ。クロックストレッチという誰も実現していない機能を実現してやろうという野望は、もろくも消えた。

 やれやれ、三度にわたる敗退である。暫くは立ち上がれそうにない。ただ、この電子工作は、定年後の重要なライフワークのひとつになっており、もう今さら止めるわけにはいかない。

 今、考えている次のテーマは、ESP32で、課題になっていたSPIFFS(フラッシュメモリを使ったディスクシステム)だ。フォーラムなどを見ていると、ESP-IDFという、Arduinoとは違うプラットホームで動き始めたようだ。これを試すのも悪くないかと思っている。

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

2017年7月26日 (水)

オシロのテストどころかソフト開発で大はまり

 新しいオシロで色々テストするつもりが、久しぶりにソフトのデバッグにはまってそれどころではなかった。超音波距離センサーSR04のI2C化の最中に、avr-libcのバグらしいもの(と最初は確信)に遭遇して意気込んでいたのだが、何のことはない、わかってみたら全てこちらのミスと判明した。いやあ情けない。まあ、それまでのいきさつを最後まで聞いてください。

新しいオシロは機能がありすぎて持て余し気味(6/30/2017)

 ほぼ10年ぶりにオシロ(帯域200MhzのSiglent SDS1202X-E)を新調して、埃をかぶっていた自作のファンクションジェネレーター(以降FG)を棚から持ち出し、FFTとか、シーケンスモードとかの新機能を試そうと、張り切ってオシロに向かった。

Dsc01176 ただし、まだ操作に慣れていないので簡単な測定でも四苦八苦である。トリガーのかけ方がいまいち理解できない。スロープとエッジの違いも良くわからない。FGで矩形波を出し、FFT(高速フーリエ解析)の波形を見るが、思っているような形にはならない。だいたいアナログ機器の調整ならともかく、単にFFTでスペクトル波形を出しても、「で、それがどうした」と言われたら黙るしかない。

  というので仕事の帰り、秋葉原の書泉ブックセンターに寄ってオシロの参考書を探した。入門書はいくつかあるが、中上級のものはほとんどない。技術の進歩が激しいので単行本になりにくいのだろう。雑誌の特集を集めたムック本が2種見つかったが、ひとつはすでに初代のオシロの時に買ったものだった。しかたがないので残りの一冊も買う。Dsc01175

 参考書の中のオシロはメーカーが違うので、パネル面や用語が手持ちのものとかなり異なる。まあ基本のところは大体似たような機能なので迷わないが、ちょっと細かくなってくるとわからなくなる。本来はこの会社(Siglent)のマニュアルを探すべきなのだろうが、日本語のものはないし、とっつきにくい。

 ウェブには何故かこういう紹介サイトもある。しかし、情けないことに半分も理解できない。うーむ、難しいな。知らなければならないことが山ほどある。ここは基本的なやり方を参考書の最初から読みこんで少しづつ理解していくしか方法はないようだ。

 前記事にあるように測定の時間的な範囲が広がったのはとても収穫だが、アナログ波形を見なければ進まない工作は現在していない。そう、宝の持ち腐れと言っても良い。使い道が見いだせないというのはつらいものだ。

センサーのブレークアウト基板を作る。久しぶりハンダ付けが楽しい(7/4/2017)
 いうことで、これまでの工作の続きをすることにした。ブレッドボードに組んでいた超音波距離センサーHC-SR04のブレークアウト基板の制作である。入力を電源3.3VとI2Cだけの結線にしぼり、RaspiやESP8266などの最近のCPUと簡単に接続できるようにする。

 手持ちのケース(タカチのSW70 75X50X35)に全体が入ることを考慮して、秋月のC基板を少し小さくする(72X40)。ここにSR04とTiny85、それに例のストロベリーリナックスのDC-DCコンバーター、秋月で入手したI2C用のレベルシフター(FXMA2102 ¥200)をレイアウトする。Dsc01164

 過去のブログ記事を見てみたら、本格的なアートワークをやる汎用基板でのハンダ付けは数年ぶりのことだ。久しぶりのアートワークそのものが楽しい。ここでの醍醐味は、複雑だった引き回しが部品の位置を少し変えるだけで簡単になることだ。

 パズルを解くのと同じである。何度もアートワークをメモに描きなおし頭を捻る。配線を交叉させないというルールは守れないかなと諦めたころ、ピンヘッダーの方向を逆にするときれいに解決したりする。鬼の子をとったような気分である。実際の工作前にもこれだけ楽しめる。

 アートワークも完成したので、部品を揃えてハンダ付けの工程に入る。ハンダ付けは一気にやらない。楽しみながら少しづつやる。実体顕微鏡を買っておいてよかった。最近TVのCMでメガネにかける拡大鏡を見かけるが、これは精々1.6倍程度で、倍率20倍のこの顕微鏡にはかなわない。ただ、顕微鏡は慣れないと対象物に絞り込むのが一苦労だ。Dsc01171

 配線作業は進む。サインペンでアートワークにハンダ付けした部分を塗りながら、出来上がっていく基板を矯めつ眇めつ(ためつすがめつ)眺めて感慨にふける。考えてみたら、この方式を始めて、そろそろ10年。このパズルのような、UEW線を交差させないアートワークと、この細かいはんだ付けの絶妙な組み合わせが、心をひきつけてやまない。

 自分がこの小宇宙の創造神である。満足感、達成感は、悪いけれどArduinoやRaspiなどでの工作とは比較にならない、至福の時間である。この基板にI2Cスレーブライブラリーを使ったSR04のインターフェースソフトを合わせて記事にしたら喜んでもらえるかもしれない。期待が膨らむ。

使えないHC-SR04があった。ブレークアウト基板はミスなし(7/6/2017)
 サインペンで線を塗るところがなくなった。完成である。ニチアツのコネクターを奢って、圧接ペンチでソケットに入れるピンを用意する(久しぶりなので1ピン失敗した)。SR04は背の高さを低くするため、センサーのピンソケットを平型に換えてある(オリジナルはL型)。テストに入る。Dsc01172

 最初、動かなくてあせったが、沢山あるセンサーユニットSR04のうち、選りによってトラブルのある方を使っていたことがわかり、あわてて正常な方にピンを付け直す。さあこれでどうだ、電源ON。良かった。ブレッドボード上の親機(Tiny861)のUARTコンソールに、距離が表示された。

 やった、やった。基板のハンダ付けは完全試合だった。腕はまだ落ちていないぞ。SR04距離センサーは、このあいだ秋月で同種のセンサー(US-015)を買ってある。ついでにこれも平型ピンに取り替えてテストする。これも問題なく動いた。 

 これで当研究所には、なんと合わせて5つもの距離センサーが揃ったことになった。アマゾンでは2つも買ってあった。このうち正常に動くのは3つ。具合が悪いのは、アマゾンの一つと秋月で最初に買ったもの合わせて2つである。Dsc01166

 ハードは一応、これで一段落である。用途は現在、階段の照明切り替えに使っている赤外線人感センサーの代替を考えているが、人間の近接を距離によってどうやって検知するかロジックが決まっていない。これからテストをして決めていくことになる。

親機のコマンド新設。距離が安定しない。DC-DCコンバーターが怪しいか(7/8/2017)
 SR04ブレークアウト基板のソフトの整備に入る。これまでにI2Cスレーブそのもののソフトは、Tiny85に組み込み、かなり作りこんだライブラリーが完成してコードも公開済みである。

 マスター書き込みでデータを送った後、ストップコンディションを送らずに、続けてスタートコンディションが来ても、これに対応する機能(リピートスタート)や、書き込み/読み込み双方のストップコンディションの対応、タイムアウトなど、I2Cスレーブとしてはほぼ満足できる機能がライブラリーとして実現している。

 ここはもう余り手を加える必要はない。残るは、このブレークアウト基板が部品として使えるように、親機のTiny861に必要なUARTコマンドを追加して、汎用的なソフト環境を整備することである。Dsc01169

 まずは、連続して測定した距離を表示するコマンドを新設する。これは先のロジックを作るのにも必要な機能で、人が近づいたときどう距離が変化していくか連続的に調べるためである。作るのは簡単で、SR04の測定を開始するコマンドと、SR04のエコーを調べるコマンドを連続的に実行すれば良い。停止は、コンソールからのリターンキーである。

 簡単に出来たので、三脚にブレークアウト基板を固定して測定を開始する。順調にデータが出始めた。ところが、出力データが安定しないのである。階段の下から上部に向けて超音波を発射し、最上部に人が立てば、距離が変化して照明などの回路をONする理屈なのだが、無人なのに距離が安定しない。

 壁に囲まれた閉空間なので反射が多いからか、また、空気中の微粒子からの反射か、突然距離が短くなる。安定した距離が続かない。困った。このままでは、実用的な目的を果たせない。

DC-DCコンバーターを調べているうちにレベルシフターを壊したか(7/12/2017)
 三脚に固定しているのに、距離センサーが不安定な原因は、どうもDC-DCコンバーターのせいではないかという疑いがでてきた。埃が原因というのも考えにくい。DC-DCコンバーターはSR04にごく近い所に固定されている。疑うところはこれくらいしかない。

 というので、5Vの昇圧コンバーターの動作を停止し、別のスイッチング電源からコードを引き込んでテストした。最初、これで安定したので、DC-DCコンバーターの影響に間違いないと思っていたのだが、少し長い間測っていると、やっぱり別電源でも測定値の揺らぎは発生した。がっかりである。

 障害物がまわりにあるときは、測定値が不安定になってしまうようである。気流の動きで反射した音波が遅れて到着し距離が不当に伸びるのかもしれない(ロジックは良くわからない)。そうこうするうちに、突然センサーが動かなくなった。I2Cの通信自体がNO Responseである。

 何度も確認したが、接触不良ではない。トラブルシューティングの原則通り、マルチメーターで各部の電圧をひとつひとつ調べていく。電圧も問題なかった。DC-DCコンバーターも5Vを作っている。

 次はI2Cだ。まだ使い慣れていないがオシロでI2Cの波形をチェックする。まず親機。大丈夫だ。次はスレーブI2CのTiny85、おやあ、クロックがおかしい。パルスは受けているようだが、0になっていない(負論理なのでactiveにならない)。

 I2Cのスレーブはクロックは受信するだけである。異電圧間をつなぐレベルシフター(FXMA2102)が正しく伝えていないのではないか。

新しいオシロがお手柄。すぐにレベルシフター不調を表示(7/13/2017)
 オシロの波形によれば、I2C信号がレベルシフターを介するところでクロックのパルスが痕跡だけになる。Tiny85のUARTは動くし、親機も正常にI2C信号を出している。配線でおかしなところもない。これはレベルシフターICが壊れたとみるのが順当なところだろう。

 この実験中、DC-DCコンバーターをはずして、5Vを別の電源アダプターなどで供給した。何度かやっているうちに逆差したのかもしれない。Tiny85などのDIP製品は逆差しに案外耐えるが、こういうSMD(表面実装)部品は一瞬でも壊れる可能性がある。

 幸い、レベルシフター(FXMA2102)は予備が買ってあった(こういうときのため)。後ろ向きの仕事で気が進まないけれど、交換してみるしかない。低温ハンダで基板とピンヘッダーをはずし(ピンヘッダーはハンダ付けしてしまった)、チップだけ載せ換えた。

 電源を入れ直す。SR04基板は問題なく動き始めた。I2Cの信号もちゃんと見える。やっぱりレベルシフターが死んでいたのだ。いや、レベルシフターを失ったのは残念だけれど、新しいオシロが手柄を立ててくれた。自らを慰める。

 距離が時々違う値を示す現象は、照射する方向を選ぶと殆どなくなることがわかった。反射面の形によって値が不安定になるようである。人感センサーとしては、垂直方向(音波の方向)で使うのは無理な気がする。水平方向(音波を横切る)なら100%検知できるのだが。

一進一退のデバッグ。同時処理でこける。avr-libcがおかしい?(7/16/2017)
  SR04を動かす分のソフト開発は大体終わった。SR04では使わない連続データの入出力機能などは開発済みだ。考えられる機能はほぼ実現したが、ただひとつ気になっているところがある。

 連続測定のとき、SR04のエコーが返ってくるまで余裕を見て50msの待ち時間を設けていることだ。用途から言って、そう短い測定間隔が必要なわけではない。実用上は全く問題ないのだが、距離が短くても、待ち時間は変わらない。そのあいだ何もしないというのも芸のない話だ。 Dsc01173_2

 この間隔を短くするのは、超音波のエコーが返ってくるまでに、親機の方から、エコーが返ってきたがどうかを調べるコマンドを送れば良い。親機はそのフラグを見て、バッファーに収容されたデータを読む。簡単なロジックだ。

 トリガーをSR04にかけるまえに、フラグを0にし、帰ってきたらこれを1にする。親機は適宜マスター読み込み宣言でこのフラグを読み取って1になるのを待つ。造作のない話なのだが、これがつまづきの始まりだった。どうにもうまく動かないのである。

 何故かフラグが1になったあとの計測データがでたらめになる。計測が割り込みを受けている間にデータが不正になるのである。慌ててAVRの参考文献を調べるが、AVRと、avr-libcは基本的にはリエントラント(複数のタスクを受け入れる)で、同じプログラムに複数のスレッドが通ることを許している。Ws000027

 これまでにこうしたプログラムはいくつか作り、何の問題なく動いている。リニアPCMプレーヤーなどは、DACの音声発生、SDカードの読み込み、LCDの進捗表示と3段のマルチタスクで動いている。

 勿論、リエントラントといっても共通のグローバル変数や、printfなどの標準関数はリエントラントには動かない。しかし、I2CとSR04の計測ルーチンは全く無関係だ(とこのときは確信していた)。だから問題なく動くはずなのだが、現実にはデータが汚されている。ハングするならともかくまともに戻って動くのが気に入らない。

 満を持してロジアナを出動させる(オシロでは無理)。I2Cとエコー、実際にデータをセットするプロセスにプローブを入れ、状況を見る。確かに、エコー期間の時にI2Cが動くとデータが不正になる。共通リソースもないのにどうしてこんなことが起きるのだろう。

情けない。とんでもない思い込みだった。立派に共通変数が被っていた(7/23/2017)
 このブログは原因がわかってから書いている。原因が解明される前のメモを今読み返しているが、いつものデバッグのときと同じで、なぜこれに気が付かなかったのだろうと感心するほど、思い込みというのは恐ろしい。 Ws000028

 I2Cの割り込みと、計測ルーチンとは全く独立していると完全に思い込んでいるから、最初は、もしかしたらavr-libcの不具合とか、もっと別なことが原因ではないかと思っていた。そのあいだに以下のような副次的なバグまで発見された。

(1)    親機から子機(スレーブ)のデータを読み込むのに、いちいちコマンドを送っていたが、そんなことをせずにマスター読み込み宣言で自由にデータが読めることがわかった。SR04のトリガーをかけてからの動作をひとつ省略した。出来る限り競合を避けるため。
 ->全く効果なし 

(2)    データをマスターに送る時、スレーブのバッファーに各ビットにひとつだけ1 の立ったマスクビットをANDしてバッファーを壊していた。データを送り終えると、元のバッファーデータはALLゼロになる。つまり、一旦送ったデータの再送が出来ていなかった。 
->これも特段の変化なし。データの再利用はしていなかった。

 完全な迷路にはまっていた。I2Cとエコーロジックは無関係だと思っているから、割り込みのときにレジスターなどが破壊されて値が不正になるのではとも考え、測定部分が関数になっていたので直接にコーディングしなおしたりした。もちろん変わりはなかった。ほぼこれで一週間悩んでいた。

 それが見るともなくソースコードを見ているとき、ふと気になるところが見つかった。スレーブのソフトI2Cは先方からの想定したビット列が来ない時は、ハングアップを避けるため1秒程度のタイムアウトを設けて、通信自体をリセットするようになっている。

 このタイムアウトのメッセージに、"No_Echo or Timeout..."というところがある。ちょっと待て、このNo Echoというのはどういうことだ。あっあっあー、何ということだ。このタイマーのキャリーを記録する変数をSR04のエコー期間を測定するときにも使っているではないか。

 たとえプログラムがリエントラントでも、変数を共通にしていては駄目になるのは当たり前だ。I2Cは通信開始時に必ずこの変数を0に戻す。これで、これまでに測っていたエコーのキャリー変数は0に戻り値はでたらめになる。あーあ、何というお馬鹿なプログラム。

 この修正は極めて簡単である。キャリー変数を、I2Cのタイムアウト用と、エコー測定用のものを分けて定義するだけだ。これで、どれだけエコー期間にI2Cが被っても正常な値を表示するようになったのは当然のことである。

 やれやれ、長い間かかった。思い込みというのは恐ろしい。「すべてのものを疑え」というデバッグの格言をかみしめる。 配線図や、コードの公開は、今ちょっとショックが大きすぎて作業する気力が生まれない。公開は次回以降としたい。

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

2017年6月29日 (木)

超音波方式の人感センサーI2C化と新しいオシロ

 PCの横で超音波距離センサーHC-SR04がブレッドボード上に残されたままになっている。他の電子部品に比べると特徴的な形をしているので何かと目立つ。ブログを調べてみたら、このセンサーにはまっていたのはもう2年も前のことで(2015/7/28)、そのあいだ放置したままということになる。Dsc01163

 ブログによると、このあとこの距離計測センサーをI2Cでつなごうとして、AVRの8ピンプロセッサーTiny85を使ってソフトのI2Cスレーブライブラリーを苦労して開発した。ソースコードをブログに上げたのは良かったのだが、そのあとは力が抜けてそのままになっている。

 このセンサーはアナログで動作電圧は5V、距離をパルス時間幅で返してくる。Edisonやesp8266などの3.3Vベースの32ビットプロセッサーとは電圧が違うし、それよりもプロセッサーにOSが入っていたりWiFiなどの割り込みが起きると、こうしたアナログのパルス幅の正確な時間は測れない。 

 そういうことでI2C化を始めたのだが、工作は全然別の方向に迷走したままになっている。そういえば、秋月で異電圧間のI2CをつなぐICも買ってあったのに部品箱の不良在庫になっている。Raspi3の電源問題も一段落したので、このあたりを次のテーマにすることにした。

 HC-SR04のブレークアウト基板(Vccは3V)をつくる。I2CスレーブのTiny85と3.3->5Vコンバーターをつけ、外部へは3.3V入力とGND、それにI2CのSDA、SCLの4本のケーブルをつけて、32ビット機器に簡単に接続できるようにする。

 親機はEdisonはもはや重いので、esp8266あたりを想定する。アプリケーションは、人が近づいたら反応する人感センサーにしようと思う。現在の階段のセンサーは焦電型で結構、反応が微妙で調整が難しい。距離測定の超音波なら、扉を開けるだけで反応するはずだ。

これまでの工作の再現だけで2日を要した(6/19/2017)
 裸になっていたSR04とTiny85を取り出して、ミニブレッドボードに移し替え、ブレークアウト基板のテストベンチをつくる。これまでのブログ記事を参考に(もうこれなしでは生きていけない)、もういちど配線をし直す。Tiny861の親機の方はまだブレッドボード上に生き残っていた。Dsc01157

 UARTを2つつないで意気揚々とテストに入った。しかし動かない。親機は動いたようだが、子機のTiny85は UARTにWelcomeメッセージは出るが、反応が全くない。親機からコマンドを送っても「そんな機械はない」と門前払いだ。

 接続を確かめる。プルアップ抵抗が隣のピンに入っているのを見つけた。最近は目が悪くなって良く間違える。さあ、どうだ。駄目だ。依然として動かない。しようがない。オシロを取り出す。なにー、ちゃんとI2Cの波形が見えるではないか。それでも動かないとはどういうことだ。

 暫く大騒ぎしていたが、落ち着いて配線を見直し、間違いを見つけた。要するにジャンパーコードの接続ミスだった。SDAとSCLが逆さまになっている。Tiny85と親機のTiny861の間のピンが揃っているかだけに気をとられ、ピンそのものが逆だったというお粗末である。情けない。Ws000022

 つまらない配線ミスで時間をとられたが、完動した。次はこのSR04のブレークアウト基板のソフト仕様である。どの程度の独立性を持たせるかで、基板ハードの仕様に影響が出る。何から何まで、例えば、音速の補正をコマンドで修正できるようにしておけば、ファーム書き換えのISPピンソケットはいらないかもしれない。しかしそれも面倒だ。

 実装するDC-DCコンバーターを何にするかも迷うところだ。部品箱を久しぶりに整理すると、5コ以上のDC-DCコンバーター基板が出てきた。1V以下でLEDをつけるやつ(これは今回は使えない)やら、表面実装にこだわったFP6291のもの(2つもある)、昔のHT7750など、自作品だけで沢山ある。

急にオシロが欲しくなって衝動的に発注(6/21/2017)
  そのうち、オシロで半分つぶれかかったI2Cの波形(これで良くデータが通ると感心)を見ていて、突然、これまで我慢していたオシロに対する物欲が沸き起こった。 波形がお粗末なのはオシロのせいではないが、この物欲というやつは、「ときめき」と同じでどうも理由が明確ではない。Dsc01155

 数年前こちらに良くコメントを寄せてくれる、ばんとさんにオシロを勧めたとき、自分も新しいオシロが欲しくなったことがある。このときは、使う機会が少なかったので、やっとのことで我慢した。

 当研究所がオシロを買ったのは、もう9年も前の話である。帯域60MhzのOWON製(PDS6062T)で、当時は10万円近くした(¥79,800)。買ったときは、清水の舞台から飛び降りる気分だとブログにはある。

 オシロの効果は抜群で、PCMプレーヤーのバッファーアンダーランを一発で発見したり大活躍をしたこともあるが、単純なトリガーしか選べないことや、蓄積データ量が少ないので大したことは調べられず次第に使われることが少なくなった。

 まあアナログ工作は殆どやらないので、それほど大きな不満はない。ちょっと複雑になればロジアナを引っ張り出せば良い。 オシロは今度の工作のように、動きを確認するだけに使われていた。必要性を強く感じることはなかったのである。

 このあと、低価格帯のオシロは、さらに安くなって中華のオシロは帯域100Mhzが3万円台になった(ばんとさんに勧めたころ)。中華製も評判は悪くなさそうだったが、強いニーズがなかったことがあって、オシロ熱はそれほど高くならず、その後は余り調査していない。

 あらためて調べてみると驚いた。さらに低価格化が進んでいる。少し前までは高級オシロにしかなかったフォスファー機能(アナログオシロのように繰り返し波形を色分けしてくれる)のついたものが、10万以下で手に入る。

 調べている間に、狙いをつけたのが、SiglentというシンセンのメーカーのSDS1202X-Eというオシロである。帯域が200MHz、メモリが14 Megaポイント。フォスファー付きで、この-EというサフィックスはUART、I2C、SPIなどのレコードの解析もできるシリアルデコーダーが付いている最新バージョンである。Ws000023

 ひところなら確実に100万以上はした商品ランクである。価格が悩ましい。日本で買えば(アマゾンとか楽天)10万近くするのだが、Alibabaなどの中華サイトでは、$380、何と4万円そこそこで売っている。にわかには信じられない安さだ。

 今これがないと進めないようなプロジェクトはないが、欲しいという欲望に勝てなくなった。しかも5万円以下で、これまで想像もしていなかった高性能のオシロが手に入るのだ。ここ数年は、余り電子工作に金をかけていない。少しくらいは良いだろう。

 中華サイトの買い物はリスクが大きいが、日本のサイトの半額以下というのは強烈な魅力だ。何しろ所長は「破格の安値」というのに弱いのである。ウェブサイトの珍妙な日本語の広告画面を何度も見ては迷っていたが、抵抗できず、ついポチってしまった。相手は、AliExpressである。

DCDCコンバーターの電源でSR04が動かない(6/24/2017)
 注文はしたけれど、到着まで10日はかかりそうなので、SR04のブレークアウト基板制作を続けた。次の課題はDC-DCコンバーターのテストである。

 久しぶりに秋葉原で買い物をした。自作のDC-DCコンバーターは、殆どが9 V以上の昇圧コンバーターで、5Vに上げるコンバーターにするため、秋月電子で面実装の半固定抵抗を入手するためである。

 面実装の基板の修正はとても難しい。例の低温ハンダで部品をはずすのは簡単だが、この自作のDC-DCコンバーター基板(FP6291)は、最初のバージョンではんだ付けに大苦労した版だ(ブログ参照)。半固定の抵抗器を取り替えるだけに数時間かかった。

 何とかして取り換えた。電源を入れる。おやあ、無負荷では5Vになるが、LEDだけつけても3V近くまで下がる。オシロで見るとパルスだらけの出力で明らかにおかしい。実体顕微鏡で配線を子細にチェックする。Dsc01162

 すると、分圧抵抗のグランド側のハンダブリッジでつないだところが見事に切れているのを発見した。やれやれ、以前もこの現象に悩まされたことを思い出す。他のところで熱を加えているときにブリッジが解消されてしまうのである。

 これを直して無事、負荷をかけてもちゃんと5Vが出るようになった。300mA以上流してもOK。勇躍、SR04の電源に組み込む。SR04は無事動いた。

不愉快にも市販のDCDCコンバーターは完動(6/25/2017)
 ところが、何故か、センサーの計測距離が不正確になってしまった。どれだけ遠くを指しても、出てくる距離が30cm以上にならないのである。電圧は5Vのままで、オシロで見る限り波形も正常だ。理由はわからない。DC-DCコンバーターのパルス周波数と、超音波センサーのパルス(40khz)とが近いからだろうか。

 スペックによるとFP6291のPWMパルス周波数は、1Mhzと高いのでその影響はないはずだが、おかしなことには間違いない。修正の手間を考えると、もうひとつの自作のDCDCコンバーター(同一のFP6291)をさらに試す気力はもう残っていない。

 昔作ったHT7750もだめだった。距離はもう少しFP6291のより伸びるが、1m以上にはいかない。だいたいこいつはオシロで見ても、脈流でこういう電源には向いていない。本来の工作と違う脇道でこういうトラブルは、気分が滅入る。折角I2Cのレベルシフターまで入れて不良在庫を少し消化したというのに。

 しかし、少々のことではへこたれない当研究所の所長である。手持ちの市販(ストロベリーリナックス)のDC-DCコンバーター基板(LM2735)の予備があるのを思い出し、これを部品箱から探し出して実験してみた。

 何と悔しいことに、このコンバーターでは全く問題なく超音波センサーが動くのである。えー、なぜだろう。何故、自作のコンバーターでは動かないのだろう。不愉快なことだがこれが現実だ。Lm2735

 そもそもDCDCコンバーターをつくるのが目的ではなかった。へそ曲がりでは負けない所長だが、さすがに今度は、これ以上、これにかかわるのはやめることにした。全くの時間の無駄だ。

 だいたいこのストロベリーのコンバーター基板も予備品でこれまで部品箱の肥やしになっていたパーツである。ここで役に立っただけでも良しとせねばなるまい。ブレークアウト基板を早く作って人感センサーを作ろう。

新しいオシロ来たー(6/27/2017)
 オシロを注文したあと、注文先からは「入金は確認しました」や、「商品を配送しました」という意外にこまめなメールが届いていたが、思ったより早く、注文していたオシロが届いた(Siglent SDS1202X-E)。Dsc01158

 カード入金して2日で出荷の知らせがあり、到着は5日後である。たいしたものだ。初めての中華サイトでの買い物でどきどきしていたのだが、とりあえず一安心である。メールが届いていたので大丈夫とは思っていたが、やはり数万円台の買い物では緊張する。

 噂では、大陸からの荷物はべこべこになっている(荷扱いが極端に悪い)はずなのだが、結構、荷姿は崩れていない。ただし、段ボールを開けると、正式の梱包の段ボール箱が現れた。やはり二重になっていた。しっかりした間仕切りの発泡スチロールで機械は中央に浮いている。Dsc01159

 取り出す。現状の8インチに比べれば今度のオシロは7インチでやはり心持ち小さい。心がはやるので前と同じように居間で梱包を解き、プローブの校正をする。画面はかなり高解像度だ。

 我慢が出来ず、早速地下の工作ルームに持ち込んで現在のI2Cなどの波形を観測する。沢山機能はあるが、まだ使いこなせないので、これまで計測したものだけの再現である。

 おおー、測定範囲が広い。これまでのオシロは少しでも長い間観測しようと思っても、すぐに切れてしまい、全体をつかめない(こういうときはすぐロジアナに切り替え)のだが、今度は違う。何しろ記録量がこれまでの2倍以上あるのだ。(6M->14Mpt/s)。Dsc01161

 距離センサーのテスト機で、I2cをスタートさせ実際のアナログの応答トリガーがかえってくるところまでが一目で見られる。これはありがたい。画面が小さくなったことを感じさせない性能向上である。以前より価格は半分で性能はざっと3倍(帯域60Mhz ->200Mhz)。時代の進歩を実感する。

 フォスファー機能とか、シリアルのデコーダーとか盛りだくさんの機能があるのだが、とりあえずは満足である。追い追い調べていくことにしよう。久しぶりに自作のシグナルジェネレーターなどを埃をはらって登場させ色々テストする予定だ。Dsc01160

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

2017年4月16日 (日)

motionの動体検知はRaspi3の電源が安定しない

フィールドテストの開始(3/25/2017)
 適当なパラメーター(前記事参照)を設定して、いよいよmotionによる自宅前の道路の動体検知の監視を始めた。道に面したサンルームのブラインドにカメラのレンズが通るだけのの隙間をわずかに開けて、そこに三脚に固定したカメラを設置する。外から見ると、ブラインドに隙間が空いて何か不自然だけれど、実験なのでとりあえずはこのままに。

Dsc01104 RaspiはWiFiにしたので引き回すケーブルは電源ケーブルだけで良い。設置は楽になった。HDDは三脚の下に置いた菓子折りの空き箱にHUBと一緒に載せる。電源スイッチを入れてその場を離れる。地下の工作室に戻ってPCからSSHを開き、motionを起動する。

 よーし、これでmotionは、ストリーム画像を送りながら、動きがあった時だけ、動画(aviファイル)と静止画(jpegファイル)をSAMBAサーバーの所定のフォルダーに画像を残していくはずである。念のため、PCのブラウザーでストリーミングを確認する。うむ画像が出た。102017032517352505 小一時間、カメラをサンルームに置き、データを収集した。ファイル数200ばかり。容量にして80MBくらいが溜まった。これくらいなら一日放置しても大した量にはならないか。

 データの中身をチェックする。自動車は監視対象ではないが、動体検知するのは車のときが殆どである。カメラの位置は進行に対して90°なので自転車の追尾は結構難しい。この場所からでは流れ映像しか撮れない。

 歩行者は問題なさそうだ。動体検知画素数1000程度で十分捕捉している。それでもタバコを人家の庭にポイ捨てする不届き者の人相を完全に把握するのは難しそうだ。 Ws000017

 ファイルは動体検知をしたセッション単位にひとつづつ数が増えていく。現在は、イベント番号(検知セッションの中での連番)というのがファイル名の先頭に来るので、ソートがうまくいかない。ファイル名を工夫しないといけない。

監視カメラの仕様がなかなか決まらない(3/28/2017)
 フィールドテストは始まったが、本格的な運用に入るまでに解決しなければならないことがブラインドの不自然な隙間だけでなく、まだ沢山ある。

 現在、撮影は室内から窓ガラス越しにやっているが、本当は外に置きたいところだ。しかし、外に置くとなると、カメラの防水、防風、防塵などの対策がただちに大ごとになる。レンズを近づけてガラスの影響を少なくする場所があれば良いのだが、今のところ都合の良さそうな所は見つからない。

 また、三脚にカメラを固定し、付属物を横に置いているが、これももう少し工夫したい。掃除はしにくいし、機動的な移動はできない。それに、まだ猫に気づかれていないが、HDDは僅かだが音を出す。長時間放置した場合の音に敏感な猫の対策も考えておかないといけない。

 さらにカメラの運転仕様が悩ましい。吸い殻を捨てる不届き者の特定を当面の目標にしているから、長時間の監視が求められる。人通りの少ない早朝か深夜が考えられるので、もしかしたら赤外線カメラにする必要があるかもしれない。自動的な時間制御もあった方が良い。

 出来上がった映像のチェックがこれまた大変である。motionを使っているので、歩行者、自転車が通過するときだけの映像になっているはずだが、映像をチェックするPC側のビュワーの機能だけでなく、現在のファイル名を今よりもうすこし合理的なものにしたい。

 先述したように、現在のmotionの録画したファイル名の先頭は、ひとつの動き検知のなかの複数の動きの番号(イベントNo)で、ソートするときとても不便である(ここの1や2は余り意味をなさない)。これはmotion.confのファイル名設定で換えられそうだが。Dsc01110_

 世の中の監視カメラの整理はどうやっているのだろうか。やっぱりしらみつぶしに映像を見ていくしか能がないのか。悩ましい所である。

電源制御装置を入れるだけで電圧降下の警報マークが出る(3/29/2017)
 フィールドテストをしながら、Raspiを安定して動かす電源の検討をしている。Raspbianのデスクトップには、電力不足になると画面右上に警報の稲妻型のロゴが出る(4.65V以下)ことを知り、これで、たくさんあるこれまでのACアダプターの性能比較が楽になった。

 ブート時はCPUにロードがかかり手持ちのすべてのアダプターで一部に稲妻が出る。結構敏感である。しかも必ずしも容量の大きい(流せる最大電流)アダプターの方が安定しているとは言えない。秋月の5V 3Aより、セルフパワーHUBについていた容量表示が2.6Aの方が何故か稲妻の出方が少なかったりする。ただ、少々稲妻が出てもすぐRaspiがダウンするわけではない。

 電源ケーブルとして使っているUSBケーブルでも大きな違いがある。太いケーブルの方が相対的には良いが、これとて余り長いと細い短いケーブルに負ける。秋月電子のRaspi専門の商品棚にあった長さわずか10センチくらいのUSBケーブル(タイプA->マイクロB)がやはり最強だ。

 先だって作った自慢のRaspiの自動電源制御装置(スイッチ押下で電源が入り、シャットダウンで小電流になると電源OFF)は、レギュレーションを間違いなく悪化させる。これを経由させると稲妻が出る頻度が高くなり、システムが不安定になってしまうことがある。

 この電源制御装置は0.22Ωのシャント抵抗で電流を計測している。500mA流れても、0.1Vの低下にしかならないので影響は少ないはずだが、どうしてなのだろう。

 以前買った、USBソケット内にLCD電流計を入れたやつはもっと良くない。入れただけで電圧が下がり、正常に立ち上がらない。表示は4.7V以上だが、恐らく瞬間的な大電流のとき表示以上の電圧降下があるのだと思われる。Dsc01113

 オシロでこの瞬間的な電圧降下を測定したいと思うが、トリガーをどうかけて良いのかわからない。入力をACにして、高感度にし、トリガーをnormalやsingleにしてみるが、全く引っかからない。

 こうした瞬間的な降下を回避したいのだが、どうもうまく行かない。下手なインダクターは無用の直流の電圧降下があるし、コンデンサーも大容量のものが既に付いている。これ以上の追加は突入電流が心配だ。

 どうも、Raspiの電源コネクターになっているマイクロUSBのソケットを疑いたくなってきた。2A以上の電流が流れるというのに、あの接点の小ささは気になる。あまり結果は期待できないが、これも例のやり方に替えて試してみることにする。

電源をGPIOピン経由にしても改善せず(4/1/2017)

 それは、以前の無印Raspiで愛用していた、GPIOピン配列に一緒に設定されているVccピンに直接5Vを供給する方法である。無印RaspiはUSBからのパワー供給は、ポリスイッチが間に挟まっており、こいつが悪さをして電源が安定しなかった。

 このポリスイッチを無効にすることで安定化したのだが、最も簡便なのはそのあとにピンに出ているVccピンに電源を供給してしまうことである。ポリスイッチが有効に動くのは、raspi基板内でショートなどで電流が流れることで、それは通常考えられない。これがなくても余り問題にならないという判断である。

 今度のRaspi3は、電源供給用に特化したUSBマイクロソケットがついており、その先の配線はRaspi2までと変わることはない。しかし、マイクロUSBのような小さな接点で、2Aを越す電流を安定的に送れるとは思えない。不安定さの要因のひとつになっているのではないか。

 そこで、前の無印Raspi同様、GPIOピンのVccに電源を供給し、いくつかの同じテスト(ブラウザー2本立ち上げ、motion動作、自分でストリーム受信など)をやってみた。残念ながら、マイクロUSBからの給電に比べ大きく改善されることはなかった。

電源制御装置で奇妙なトラブルにはまる (4/3/2017)
 問題なさそうなケーブルやACアダプターを選んで、何とか自作の電源制御装置を入れても安定して電源が供給されるようになった。

 ただ、SAMBAサーバーに使っている2.5インチHDDの電源供給(USBから給電)は、ただでさえ逼迫しているRaspi3の電源事情を考えて、当初から、セルフパワーのHUBを追加している。しかし、これでは、監視カメラを動かすのに2台のACアダプターが必要になり、取り回しが悪い。

 そこでせめて、ひとつだけのACアダプターでRaspi本体と、HDDをドライブするセルフパワーのHUBの電源にしようとした。ただ、セルフパワーHUBのACアダプターの受け口は、当研究所標準の2.1ミリジャック(秋月電子の標準と同じ)と違うので少々の加工が必要である。

 ところがこのテストをしているうち、妙な挙動に悩まされることになった。電源制御装置にACアダプター端子を追加し(単に入力をパラにしただけ)テストした時のことである。ブートしてRaspiのデスクトップ画面が順調に立ち上がった途端、電源制御のリレーが動いて切れてしまった。

 はじめは過電流が流れてRaspiがリセットしたのかと思ったのだが、勿論そんな状況ではなく、正確にリレーが働いて電源を切っており、症状は再現する。つまり、これはRaspiの消費電流量がシャットダウン時とみなされるまで低下していることを意味する。これはおかしい。Raspiは電源が切れるまで、ブートメッセージを始め、正常な動きをしている。Dsc01109

なんとUSBセルフパワーHUBが犯人(4/5/2017)
 こういう状況を放置しておけないのが所長の習性である。何が原因なのだろう。突き止めるまでは先に進めなくなった。幸いこのTiny13の電源制御装置は、裏蓋を開けるだけでデバッグ用のUARTにアクセスできる。字化けが何故か多いが(未解明)、そのときの消費電流と測定カウント、インターバルなどを表示する。

 このUARTをつないでスタート時からの電流量をモニターして驚くべきことが分かった。何と、このHUBのときは、Raspiには通常の1/3の電流しか流れていない。Raspiは普通、立ち上がりの時はかなり電流が流れるが、デスクトップが出てしまえばRaspiは200mA前後に落ち着く。これが通常の1/3だとシャットダウン時に想定している最高電流80mAを下回る。で、制御装置はシャットダウンと判定したのだ。 Dsc01111

 しかし、電流量が減ったのが全く理解できない。ブートは通常通り行われており、問題はない。するとHUBの電源を共通のACアダプターからとっていることが、これまで違ったところなので、これが原因であることは明らかである。しかし、理屈が合わない。USBコネクターから電源が供給される?そんな馬鹿な。

 試しにHUBを取り替えて別のHUBにしてみた。ははは、この問題は全く解消した。本当だ。セルフパワーのUSB-HUBの中には、スレーブからでもマスターのUSBパワーの電源を戻してやることがあるのだ。

体制は整ったが、突然、工作意欲がなくなる(4/14/2017)
 妙な現象は、手持ちのセルフパワーHUBの特性であることがわかった。症状の出ない別のHUBに切り替え、Raspiの監視カメラの電源整備はとりあえず一段落である。

 三脚の上にカメラ付きのRaspi3を置き、そこから電源用と、HDD接続用のUSBケーブルを2本出す。三脚の下にHDDとセルフパワーHUBを配置し、そこからACアダプターへの電源ケーブルを引くというレイアウトである。Dsc01108

 これをサンルームに持ち込み、テスト開始と意気込んだところに、珍しく風邪を引いた。これがかなり酷く、熱は微熱なのだが咳が止まらないうえ、声がしゃがれて出なくなった。こんなに喉をやられたことは記憶にない。無精して医者に行くタイミングを逃し、家人からあきれられた。

 そんなことで、突然工作意欲が湧かなくなった。電源制御装置のモニターのUARTの字化けを直そうと、久しぶりにAtmelStudioを立ち上げたりしているのだが、次の一歩が出ない。実はこのあいだネットで評判になっているESP8266の発展版、ESP32も買ってきてあるのだが、これも手が付かない。

 これまでにやった工作らしい工作は、傘の骨の修理(東急ハンズで修理用パーツをゲット)。DVDレコーダーリモコンの修理(これはカラ割には成功したが赤外線LED点灯せず。アマゾンで買い直し)。このあいだてこずったRaspiのBlueToothのテスト(キーボードは簡単につながったが、タイムアウトがあって使いにくい)、と脈絡のないことばかりである。

 まあ、これは意欲が戻るのを待つしかない。ブログもこのままではまずいので、とりあえず、中身はないが、これまでの報告ということで。

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

2016年7月21日 (木)

赤外線学習リモコンはデータ再現で挫折したまま進まず

 キャプチャーした赤外線のデータ列をロジアナで確認し、学習リモコンの工作は峠を越したと考えたのは甘かった。あれ以来すっかり電子工作への意欲が湧かなくなって、気が付けばもう2か月近くが経とうとしている。

 深刻なスランプである。何とか先に進めようと、作業の前にこれからの作業項目をメモに列挙し、気力を奮い立たせてPCに向かう。開発環境を立ち上げ、メモの手順に従って開発する。

Dsc00524

 これまでなら、一旦作業が流れに乗ると自然に手が先に進んでいくものなのだが、最近は少し結果が出ると、何故かそれ以上のやる気を失い、ほかのことに気をとられてしまう。これが愚にもつかないゲームや、ウェブサーフィンだったりする。困ったものだ。

 責任を転嫁する気持ちは毛頭ないが、どうも最近は電子工作そのものも前に比べると盛り上がりに欠けているように感じる。所長が始めた8年前は、活発な活動をしている掲示板やブログサイトが沢山あって、大いに参考にさせてもらったものだ。

 ところが、現在はみな低調で閑古鳥が鳴いている掲示板が多い。電子工作関連の雑誌も、以前はFPGAや32ビットCPUの基板が盛んに付録につけられて、みんなでわくわくしながら動かしていたものだが、最近はこういう話も聞かない。

 実は、所長の電子工作が低調なのは理由があって、5月の末、体調を崩し病院通いをしていたせいもある。工作をする気持ちのゆとりがなく、一時は、狭心症の疑いまでかけられたのだが、幸い誤診だったようで、今は全く症状はない。

 この話はあとですることにして、趣味の電子工作全体が低調な原因には思い当たる節がある。個人的で一方的な仮説にすぎないが、この低調さは最近のArduinoの普及と大きな関わりがあるように思える。

Arduinoの功罪
 商売の邪魔をする気は全然ないのだが、Arduinoで電子工作の世界は大きく変わった。しかし反面、つまらなくなった。まずメリットの方はご存知のように次のようなものだ。

ハードウエアのI/Oインターフェースが統一されているので、初心者は、面倒なI/Oピンの初期化に気を遣わないですむ。誤配線や誤設定をする恐れが少ない。最近は機種を超えて共通なのでハードウエア設定はさらに楽になり失敗はほとんどなくなった。

各種のペリフェラル(UARTやI2C、SPI)の設定も、スケッチライブラリーが全部用意されているので、プログラムを書くのが大変楽になった。ほぼデータの中身だけを心配すればよい。

各種のシールド(増設するディバイス)とそのライブラリーが用意されているので、簡単に高度な機能を実現できる。

 経費的には、はるかに高額になったとはいえ、便利になったことは間違いない。所長もESP8266では大いに恩恵を受けた。その反面、この道はあらゆるテクノロジーの世界がこれまでに経験したことと全く同じ道である。

Ws000003

 便利になればなるほど、細部を知らないでも先に進めるので、技術を身につける機会を奪ってしまう。つまり情報が隠蔽化され、ブラックボックスになっていけば、必然として次の弊害が起きる。

組み立てて、それで動けば問題ないが、一旦、動かないとなると、どこから手を付けて良いのか全く見当がつかなくなる。故障や、ちょっとした不具合にも対応することが出来ない。

作った製品の改善や、改良は殆ど出来ない。製品の応用もできなくなる。いわゆる技術力は身につかない。

それでもこうした複雑になったしかけを短時間に理解し、その応用ができる技術者は一部に存在する。しかし以前にも増してその数は限られる。これにより技術者間の格差はさらに広がる。大多数の一般の人は作って動かしただけで終わってしまう。

 最近の電化製品は、一旦故障が起きると一般の電気店では殆ど修理不能で、自動車もそうだ。ボンネットの中は完全なブラックボックスで点火プラグひとつ素人が交換できない。その製品を使うことが目的ならそれでも良いが、電子工作というのは作る過程を楽しむ趣味でもある。

 従って、電子工作にすぐ飽きる人が増える。ちょっと見は楽そうなので一時的に参入者は増えるかもしれない。しかし長い目で見ていると、参加人口はどんどん減っていくという寸法である。これまで繰り返されてきた、知らずに自分で自分の首を絞めているという業界の悲劇がここでも起きているように思う。

サードオピニオンまで聞いて何とか安心(6/23/2016)
 それはさておき所長の病気の話である。ある朝、コーヒーを淹れようとミネラルウオーターの2リッターペットボトルを持って機嫌よく階段を上がっているとき、突然、息切れがして胸が苦しくなりその場に座り込んだ。息切れは間もなく解消したが動悸がおさまらず、その後はちょっとした運動をするだけで、すぐ息切れがする。

 近くの医院で心電図や血液検査をしてもらうが、特に異常はない。最初は熱中症だと言われた。しかし気温が30 度以下の室内では考えにくい。頻脈は心理的なことでも起きるというので最初にもらった薬は何と精神安定剤だった。

 数日経って息切れはだいぶ良くなったとはいえ、洗車をしただけで息が上がる。近所の医院の医者は大病院で精密検査をすることを勧めてくれた。最初に行った大病院では、心臓エコーなどの検査を受けた。しかし、ここでも特に異常なしと言われる。症状は殆ど改善していたが、原因がわからないのは不安だ。

 さらにまた別の大病院に行く。ここの医者は症状を聞いて、「これは狭心症しか考えられない」と宣言する。なんだ、やっぱり狭心症なのか、そういえば血液が高脂質だと注意されている。ニトロ舌下錠までもらって覚悟を決める。ただ念のため、造影剤を使った心臓CTスキャンを撮ることになった。

 近くの医者に報告する。「すっかり病人にされちゃったのね」と笑う。このとき、こちらは狭心症を見抜けなかったこれまで2人の医者は藪(やぶ)だと思っていたので内心は穏やかではない。

 心臓CTスキャンの結果が出た。見せられた自分の心臓の血管はプラモデルでつくったようにつるつるで動脈硬化のかけらもなかった。医者はあっさり狭心症の見立てを取り下げた。で、同じときに撮ったCTスキャンの肺臓にいくつか血栓のあとがみられるので、肺塞栓症、そう、いま流行のエコノミークラス症候群だろうということに落ち着いた。

 そうか、前の2人の医者は藪ではなかったのだ。医者の見立てというのは恐ろしい。CTスキャンがなければ、ずっと狭心症の薬を飲まされているところだった。1週間飲んでいた薬が、動脈から静脈に急に変わって、薬局の薬剤師が笑っていた。

 とはいえ狭心症より、肺塞栓症の方が始末が悪い。血栓が出来る要因がはっきりしないからだ(2月に海外旅行にでかけているが3か月も前の話)。ただ一過性なので今は全く問題ないというのが有り難い。それに心臓が思ったよりきれいだったので安心している。

2年ぶりの小学校の同窓会。今度は世界遺産の宇治上神社と平等院(5/20/2016)
 さらに、電子工作とは関係ない話題をもうひとつ。実は前記事をアップする直前、例の、京都の小学校の同窓会が2年ぶりに宇治で行われたので行ってきた。そのときの写真を少しご紹介しておこう。

Dsc004520001

 宇治は硬貨の裏にも彫刻され、世界遺産にもなっている平等院の鳳凰堂が有名だが、実は、それ以外にも世界遺産に指定されているところがある。それが、平等院の川向うの北東に位置する、宇治上(うじがみ)神社である(京都のお寺や神社がすべて世界遺産ということではなく、全部で17か所)。

 所長も行ったことがない。同窓会をその近くで行うというので、また日帰りで京都へ行ってきた。同窓会の前に、その神社に行ったのだが、何の変哲もない神社で完全に足をすくわれた(これは予想した通りでもあったが)。

Dsc004530002

 世界遺産に指定された理由は、国宝となっている日本で一番古い神社の本殿が残っていることらしい。しかし別に驚くような建物でもない。これだけで他には何にもない。実にあっけない世界遺産だった。まあ観光客が殆ど来ていなくて、のんびりと散策できたことは収穫だった。

 今度の同窓会は、この世界遺産と、遠方から珍しい同級生(何十年ぶり)が来るというのに釣られて来たのだが、まさに60年ぶりに会った同級生は、頭が薄くなっていたが、話をしているうちに完全に小学校時代の面影が再現し、とても感動した(相手があまり自分のことを覚えていなくて少し残念だったが)。

Dsc004570006

正しいサブキャリア―周波数を作る(6/2/2016)
 電子工作の話に戻ろう。工作そのものは、前回記事のあと少しやっただけで、その後は殆ど進展していない。もともとは、無線WiFiモジュールのESP8266で学習する赤外線リモコン遠隔制御装置を、それこそArduinoで作るつもりだった。

 ウェブにはいくつかのソースコード(スケッチ)が公開されている。ここここのソースを拝借すれば恐らく問題なく動くのだろうが、それだけでは何となく面白くない。赤外線リモコンは応用範囲が広いので、ハードなどの技術をマスターしておきたい。そこであえてマイコンのAVRで基本的なところから作りこんだ。それが、深みにはまっている。

 赤外線の学習リモコンというのは、既存の赤外線リモコンの送信データを、受信してそっくり記録し、あらためて必要に応じて、その赤外線データを送信するもので、前回のブログ記事の通り、データ受信と記録の機能は、Tiny861を使って(最初Tiny441で失敗)、開発に成功している。

 次は送信部である。赤外線のデータ規格はさまざまな種類があるので、汎用的にするため、ここでデコードすることはやめ、忠実にその長さに基づいて赤外線を発信する方法をとることにする。エラー率は高くなるが、とりあえずはこれに挑戦する。

 送信用の赤外線LEDはこれまで使ったことがない。まずはミニブレッドボードに、送信用赤外線LEDとFET(2SJ377)をつけて、赤外線LEDがon/offできるか確かめる。確認のため普通の発光LEDを並列につける。問題なく動いた。制限抵抗が300Ω程度でも1m位は受信するようだ。

Dsc00527

 次はソフトウエアである。これまでの受信部とこの送信部を少し大きめのブレッドボードに統合したあと、送信側のロジックを開発する。キャリアーパルスはPWMでなく、通常のGPIOをタイマーで駆動して、duty比1/3のサブキャリアーを作った。

 割り込みルーチンにこれを組み込み、ON/OFFはメインループのフラグで行う。タイマー割り込みはサブキャリアーの2倍(on/off)のタイミング13μsで発生させる。メインループのON/OFFは、最少でも500~600μs単位なのでこれで十分動くはずだ。

 動かしてみる。オシロでサブキャリアーの周波数を測定する。うーむ、30Khzを下回っている(およそ28Khz)ので受信モジュールが正しく動かない可能性がある(仕様上は30~38Khz)。

 遅れる原因をチャートを書いて調べる。キャリアーパルスの遅れは、タイマー割り込みが起きて割り込みルーチンに来るときの時間(オーバーヘッド)だけが問題で、割り込みルーチンの中の処理は関係しない。実測してみるとこのオーバーヘッドは、8Mhzのクロックで4μs内外のようだ。

 それを加味して、タイマーの時間を調整する。しかし、どうも計算通りにならない。思い切って値を減らす。対症療法だが、これでやっとサブキャリア―が30Khzを超えた。まずはこんなもので良いだろう。

送受信の分離にてまどる(6/8/2016)
 受信で得たパルスデータの配列(立ち上がりと立下りの間の時間1バイト)から赤外線パルスを作るのは簡単だ。送信の指示があれば配列をループに入れ、先頭から配列データに入っている待ち時間を計算してウエイトし、データの最後まで送信LEDのスイッチをon/off(exclusive OR)させるだけである。

 しかし、最初はうまくいかなかった。同じCPUに送受信ルーチンを入れ込んであるため、送信赤外線が出始めると、受信側が割り込みを開始して動いてしまう。送信パルスは間隔を単なるループ回数で決めているので、正確な間隔にならなくなる。

 受信側の割り込みを動かないようにすれば良いのだが、これが意外に面倒だった。どうしても、最初のパルス受信を止めることが出来ない。送信パルスの発生は、タイマーの割り込みルーチンで動いているので始終動いており、受信モジュールの割り込みを止めるステートメントの場所が難しいのだ。

Led1

 停止をするステートメントの前後を割り込み禁止にし、ペンディングの割り込みを事前にクリアするステップを追加してやっとのことで、受信を黙らせることに成功した。その後はロジアナで波形を見ながら少しづつ送信波形を記録したデータに近くなるよう調整していく。

 ロジアナがまたも大活躍である。これがなかったら全く手も足もでなかっただろう。ロジアナさまさまである。Tiny861の20ピンが大いに役立った。いくらでもプローブ点を作れる。5本で解析すれば、だいたいのことはわかる。

Dsc00526

 現在の我が家にあるリモコンは5種類以上ある。学習リモコンの最終ターゲットはエアコンだが、このデータ列は長大なので、とりあえずは電子ボリュームに使ったSONY仕様のリモコンを当面のターゲットにして調整する。簡単といっても、こいつもリピートとして同じ信号が必ず5本近く出るので、正確な信号を再現することは結構難しい。

やっとのことで3機種の再生に成功したが、本体が受け取らない(6/22/2016)
 徐々にではあるが、学習赤外線リモコン送信部がそれらしい赤外線データを再生し始めた。SONY仕様の12ビットの信号も、ロジアナで見る限り、10%内外の誤差でデータをだしているようだ。

 リピートの処理はリピートとリピートの間の40msの間隔でタイムアウトをとり、2番目以降のデータを無視することで正しいデータが得られるようになった。エアコンのリモコンに対象を移す。データは多いが、何とか512バイト内(Tiny861のSRAMサイズ)に納まっている。

 いよいよ、当面のターゲット、寝室の最近新しくしたリモコンデータである。おやあ、Tiny861がリセットする。ええー、こいつは512バイト以上なの? 測ってみた(数だけ勘定する)。何と何と、こいつは292イベント(146ビット)もあり、しかも念の入ったことに、10ms程度の休みのあと同じデータが繰り返されていて軽く配列データが512バイトを超えてしまう。

Led2

 仕方がない。リピートのタイムアウトを10msに縮めて最初のデータだけを記録することにする。さらにテストを続ける。今度はデータ列の最後のイベントの割り込みがペンディングになり、これが次のデータ列とみなされて本来のデータが消えてしまうトラブルに悩まされる。これは、割り込みリクエストのクリアをいたるところに入れて回避する。

 悪戦苦闘の結果、3つのリモコンそれぞれで、ほぼ原形通りの波形を出力するようになった(まだ実地テストはやっていない)。こんなに長い間かかるとは当初考えても見なかった。原因は、それぞれのリモコンが持っている、リピート信号を除去するのに手間取ったことが一番大きかった。もうちょっと、プログラムの構造を考え直す必要があるかも知れない。

再生したデータで本体動かず。意欲がわかない。完全なスランプ(7/4/2016)
 体調はすっかり戻った。週2回のジムでも、プールで300mが楽に泳げるようになった。ただ、電子工作への集中力が途切れている。送信部のデータがほぼ想定通り出たので、実機でのテストに入る。対象は、まずは電子ボリュームにしているSONY仕様の一番簡単なリモコンのテストだ。

 オーディオコーナーに設置してある電子ボリュームを工作机に移し、ケースを外してデバッグ用のUARTを取り出す。うまく動けば良いが、動かないときの用心である。苦労して設定し、いよいよテストに入る。

Dsc00525

 だめだ。全く動かない。UARTにすらメッセージが出ない。送信データのデコードがうまく出来ない。一番簡単なSONYフォーマットのデータを受け付けない。たかだか12ビットのデコードが出来ないのだから、100ビット以上あるエアコンのデコードなど思いもよらない。

 何が原因か。赤外線の出力をちゃんと受け取っていることは確認した。出力波形は、入力とほぼ同じになっている。少しづつ違うようだが、誤差は20%もないだろう(600usが500us程度)。ただ、このあたりは10 %以下でないと駄目なのかもしれない。

 こうなると意地になるのが常である。電子ボリュームのソフトをいじって中身のデータを出せるような体制に入る。しかし、この機器のCPUはTiny2313で、SRAMが128バイトしかない。ちょっと詳しいデータを出そうとすると、スタックのオーバーフローで簡単に暴走してしまう。

 このあたりで集中力が切れた。このままでは泥沼である。体制をもういちど見直して最初から仕切り直しをしたほうが結局効率が高そうだ。しかし、電子工作への意欲が落ちているのでなかなか次の一歩が進めず、いたずらに時間が経つばかりである。

Windows10インストールで最初の犠牲者(7/12/2016)

 そんなことで別のことに興味が移ってしまった。Windows10である。今さらの感もあるが、今月末に無償アップグレード期限が切れるというので、渋々入れることにした。Windows7で何とか動いていたMSのFlight Simulator(FS 2004)が心配だが、まあそれはあとで考えることにして、これまでさんざん無視していたWindows10移行のボタンを押す。2時間近くかかった。

 ソフトは大体無事だったが、いくつかのハードがらみのアプリに問題が出た。Epsonのスキャナーは何とか、このサイトの情報で助かる。LAP-Cのロジアナはバージョンアップの情報があったのでうまくいくと思ったが、以前のファイルが残っていて正常に動かすのにてこずった。

 AtmelStudioや、Win95時代の定番のエディターや、ターミナルは無事だった。もちろんChaNさんのAVRSPも問題なし。開発環境はほぼ整った。やれやれ。

 FS2004は遂に動かなくなった。そもそもCD-ROMを入れないと動かないソフトは全滅のようだ(セキュリティの関係らしい)。OSそのものは確かに軽くなった。もっともこれは、Win10とともにメモリを増強したことが原因かも知れない(AtmelStudioがメモリ喰らいで、メモリを2Gから4Gにした)。

 大所が動いて、細かいところのテストに入る。意外なところがダメだった。サンワのUSB BlueToothドングルは、現在ほとんど使っていないが、こいつが動かなくなった。サイトを見るとなんと「Win10はサポートしていない」というではないか。最初の犠牲者だ。

 こいつは、仕事の帰り、ヨドバシに寄ってWin10対応のものを買いなおした。なんと、¥1000少々。気が抜ける価格だ。ウェブ上では、BlueToothの世界も沢山のバージョンがあり、色々な話が渦巻いているようだ。まあ、最近のボードは、このあたりはすべて内蔵だから、ドングルに関心が薄れたのかもしれない。

Dsc00530

 ヨドバシ秋葉原店は、膨大な売り場面積だが、BlueToothのドングルは5種類くらいしか売っていなかった。動かないという苦情が多いせいなのかもしれない。

 ともあれ、Windows10は今のところ順調に稼働している。ブログの紙数も増えてきたようなのでとりあえず活動報告をここで一区切りすることにする。

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

2016年6月 1日 (水)

落穂ひろいの電子工作(続き)赤外線学習リモコンで遊ぶ

遂にパワーダウンスリープの不具合が解消された(5/8/2016)
 機械式自動巻時計のゼンマイを巻く自動巻機(ややこしい)の不具合の話を前の記事に書いた。結局、原因解明ができず途中であきらめたのだが、記事の最後に「閃いた」というコメントを残しておいた。

 「閃いた」のは以前、似たような状況でAVRのマイコンに、ある機能を組み込んだことを思い出したことである。それは電子ボリュームの赤外線リモコンを作ったとき、パワーダウン時のEEPROM書き込みの誤動作をさけるフューズビットの設定、BOD(Brown Out Detect)機能である。09p6017508 BODとはVccが低電圧になったとき、CPUが誤動作しないよう内部でリセットする機能で、デフォルトでは設定されていない。ウェブ上でこんな記事を見つけたことも、BODが気になるきっかけになった。

 この記事は、スリープから目覚めるときにはBODを設定しておいた方が良いという内容で、直接現在の不具合とは関係ない。ただ今度の不具合は、CPU内部の不可思議な動き(電源断のときの電圧降下の遅さ/速さで症状が違う)に関連がありそうで、何となく臭う。

 こじつければ、電源が切れた後、パワーダウンスリープからVccが徐々に下がっていくとき、何らかの予期しない動きがあって今の状態になると考えれば、Vccが下がると同時にリセットがかかる方が望ましいことには違いない。

 ということで半信半疑だったが、藁をもつかむ思いで、件(くだん)のTiny2313にBODを設定してみることにした。フューズビットを見てみると、現在の状況では未設定である。何の確証もないが、物は試しである。4.3Vでリセットがかかるようにする。

 おおお、何ということだ。これでパワーダウンスリープで電源を抜いても、問題なく初期状態でCPUは動き始めたのである。いつも必ずトラブルが起きていた、ACアダプターのACコード側の抜き差しでも、全く症状は起きない。

 実際に運用してみた。見事、1週間問題なく動いた。やれやれ、何だったのだろう。全く根拠はないが、BOD設定をフューズビットに設定するだけで直ってしまった(その後も、順調に稼働中5/31記)。

すごい、DS3231の月差は1.2秒(5/10/1216)
 久しぶりにWiFiモジュールのESP8266を動かす。最後に触ったのは、I2CリアルタイマークロックRTC(DS3231)の動作テストである。このRTCはバッテリーバックアップがついているので、精度を調べるために大分前に正確な時刻を設定して放置してあった(4/1設定)。

 UARTをつないで、ESP8266に電源を入れる。現状のプログラムはUART上に5秒ごとに時刻を表示するようになっている。スマホや手持ちの電波時計の正確な時刻と見比べる。ふむふむ、なんと、殆ど誤差がない。こいつはすごい。

 このあいだ調べたデータシートのスペックによれば、月差で4秒近辺ということだが、今の時刻は2秒もずれていない。これまでに40数日間動いているのだ。多めだが2秒としてこれを365日12ヶ月で月差を換算すると1.2秒である。大したものである。08p6017503 まあ、最近はGPSが正確な時間をくれるようだが、こんなスタンドアロンのしかも廉価なチップがこの精度なのは偉い。この製品も、以前の超音波距離センサーと同様、オリジナルをコピーした中華製のようだが、こうした電子部品が普及することはアマチュアにとっては有り難いことである。

 長い目で見れば、先行開発にチャレンジする人(や会社)を減らすことになって産業全体では悪い影響を及ぼすのかもしれないが、ジェネリック薬品と同じような位置づけと考えれば、そう心配することもないのではないか(トップメーカーの囲い込みを防げる)と勝手な理屈をこねる。

AitendoでUSBプラグを買い、Tiny24で遊ぶ(5/11/2016)

 AVRのTiny13は安いし小さいので重宝している。しかし使えるI/Oピンとフラッシュサイズが少ないのが難点である。これまでのソフト資産を生かしたまま、ちょっと機能を拡張したくても次の適当な製品がない。

 Tiny85は、USIがつき、フラッシュも大きくなるが、なにせ8ピンなのでI/Oピンの制約は変わらない。といって、Tiny2313や、Tiny861は20ピンで急に大きくなりすぎる。データシートなどを調べると、このあいだには、14ピンの24/44シリーズがあるらしいが、日本の市場には出ていないと思っていた。

 それがAitendoのサイトを見ていたら、SOPのTiny24とTiny44が売られているのを発見した(Tiny24/44にはDIP版がない)。たまたまUSBのAタイプオスコネクター(ジャック)を探していて、いきつけの秋月や千石に気に入ったものがなくて、Aitendoで良さそうなものを見つけたところである。04p5127492

 ちょうど良い機会なので、久しぶりに直営ショップへでかけることにした。ここは秋葉原というより上野に近い。地下鉄日比谷線の仲御徒町の駅から歩いて5分かからない。おやあ、1階に店が見える。始め、全部がここへ移ったのか勘違いしたが、どうも狭すぎる。店員に聞いたら3Fにもあるという(ちょっと日本語が覚束ない女性店員が答えて)、そちらに回る。

 3Fのメインの売り場は前と同じ場所にあった。1Fの店はキット製品だけの売り場らしい。相変わらず結構な客の入りだ。膨大な品数だが、女性店員は的確に陳列場所に案内してくれる。Tiny24/44はすぐ見つかった。2つづつ買う。値段もリーズナブルだ(¥120と¥200)05p5217494

 帰ってきて、早速ブレッドボード上で使えるように、手持ちのSOPの変換基板を取り出したのだが、こいつが、やたらとごつく大きすぎる。長さが700mil(7ピン)なのは仕方がないが、幅は明らかに広すぎる(600mil)。20ピンの2313や、x61より大きく見えるのでは洒落にならない。

 というので、今までのテーマ(学習赤外線ユニット)そっちのけで、自分で変換基板を作り始めた。動きだした手が止まらない。切り出した汎用基板に耐熱絶縁シートを張って、その上に接着剤で表面実装チップを固定し、0.2ミリのUEW線で配線する。

07p5217501  前から憧れていたChaNさんの得意技である。作ってみると意外にしっかりしていて美しい。幅は、100milしか狭くならなかったが、完全な自己満足の世界である。興に乗って2つ(Tiny24と44)も作ってしまった。

赤外線LEDの制御にTiny24とFETを持ち出す(5/15/2016)
 前から考えているテーマはESP8266とスマホを使った赤外線リモコンの遠隔操作である。既成のリモコン信号を学習して、スマホから操作できる。いくつかの作例があり、ソースコードも公開されている。簡単にできそうだ。ESP8266の適当なアプリとして、部品も大分前に揃えてあった。

 しかし、部品を目の前にして、急に気分が変わった。このままブレッドボードに部品を差し、ソースをArduino IDEにコピペして動かすだけでは何か物足りない気がする。赤外線リモコンは、前に受信側は自作したが、送信側はまだ作ったことはない。

 ウェブの情報によれば、何やら送信用の赤外線LEDは、離れたところから動作させるには、1A近い電流量が必要になるらしい。マイコンのI/Oピンの最大電流は数十mAなので、当然なんらかのドライバーが必要になる。

 そういうことも含めて、すべてお仕着せのスペックで作るのが惜しくなった。ちょうどSOPのTiny24がブレッドボードで使えるように変換基板を作ったところだ。赤外線リモコンをこれで作りたくなった。

 赤外線LEDの送信側のハード制作は初めてで、それに慣れておこうという魂胆もある。トランジスターで動かしている例が多いが、ここは久しぶりにFETで制御してみることにした。改めてネットでFETのおさらいをする。1A程度のスイッチングなら手持ちの小さなFET (2SJ327)で十分だ。

 まずFETの点灯テストから始める。念のため、可視光線のLEDを並列につなぐ。受信側はセンサーの出力をオシロで確認する。点灯する。あれえ、反応がない。オシロを良く見ると、小さなパルスは入っている。

 念のため、エアコンや、電子ボリューム用の汎用リモコン(ソニー仕様)などを当ててみる。問題なく連続パルスが出ている。それなのに何故出ない? 暫くして、その理由がわかった。はっはっは、情けない話だが、サブキャリア―(35Khz前後)が必要なことをここで始めて理解した。

 だから「赤外線受信素子」ではなく、「赤外線受信モジュール」なのだ。サブキャリアーを発生させるしかけが必要である。まだ先の話だと思っていたが、あわててTiny24の変換基板をブレッドボードに載せ、35Khzのサブキャリアー発生装置を作り始めた(照れ隠しもある)。

 Tiny24/44のデータシートを改めて子細に眺める。タイマーや、ADコンバーターなどのペリフェラルは、殆どx61に近い装備で2313のようなUARTはついておらず、例のUSIが代わりにある。タイマー割り込みを使って、35Khz 1/3デューティのパルスを作る。

 特に迷うことなく、赤外線のサブキャリアー発生装置が完成した。早速、テストに入る。想定した周波数より少し低いが(30khz)パルスが出た。受信モジュールに向けてみる。問題なくタクトスイッチで入り切りする出力が、受信モジュールの変化と同期した。

 このあたりの赤外線リモコンのフォーマットについては、何といってもChaNさんのサイトが一番わかりやすくておすすめである。ただ、今度の学習リモコンは、各種のリモコンを汎用的に使いたいので、ここでの中身のフォーマットは関係ない。出来るだけ、原波形を忠実に再現することが重要だ。

SRAMが256バイトでは記録できない。いっそのことMega88にするか(5/23/2016)

 次は、赤外線データ列の記録である。赤外線パルス列の受信は、以前電子ボリュームの時に実装しているので、ソースコードをそっくり持ち込み、テストする。あっさり動いた。しかし、エアコンのデータ受信で頓挫した。

 エアコン(三菱)の送信データ列が多すぎて、Tiny24/44では入りきらないのである。配列が溢れて暴走する。データ蓄積を止めて回数だけで調べる。274イベントもあった。Tiny44のSRAMは256バイトでスタックを考えれば到底入らない。

 困った。何とかならないか。EEPROMにしまいながらとか、色々頭を捻ったが、最少で500μs単位で発生する赤外線データの蓄積を、ミリセカンドオーダーの記録装置でやろうということに、そもそも無理がある。

 最終ゴールはESP8266なので、テストベンチに凝るのも本末転倒である。潔く、換装を決意する。SRAMの大きさは、折角換装するなら1Kバイトくらいは欲しい。すると、Mega88あたりか。Tiny861では不足だろう。始め、Megaにするつもりでデータシートを見ていたが、861でもSRAMが512バイトあることを発見した。

 少し、迷ったが、Tinyシリーズの中の移植の方が、Megaシリーズへの移植より楽な気がして、SRAMの量に不安は残ったが、Tiny861に移すことにした(これが、えらいトラブルの元になるとはこの時点では露知らず)。

Tiny861の罠(わな) コンペアマッチとキャプチャー機能が排他的とは(5/25/2016)
 Tiny24/44とTinyx61のタイマーの構成はちょうど逆で、受信の時に使うインプットキャプチャー(邦版データシートでは、捕獲入力)機能は、Tiny24/44のタイマー1から、Tiny861のタイマー0に変わっている。

 それ以外は大きな違いはなく、順調に移植が終わった。コンパイルする。おやあ、インプットキャプチャーしたときの値を収容するICR0(Tiny24/44ではICR1)レジスターがヘッダーファイルにないので未定義エラーになる。

 何かおかしい。それと、通信のタイムアウト用に設定したタイマー0のコンペアマッチの割り込みルーチンが動いていないようだ。UARTで設定したOCR0Aレジスターの値を表示させてみると、0になっている(未定義エラーはとりあえずコメント化して回避)。

 暫く頭を抱えていた。データシートがどうも不審なのである。日本語版では、ICR0レジスターが存在するかのような説明(本項では捕獲入力レジスタはICR0と呼ばれますが、これは比較レジスタへの参照です)があるが、これでは何のことかわからない。

 念のため原文を引くと、Even though the Input Capture register is called ICR0 in this section, it is refering to the Output Compare Register(s).
で、どうもコンペアマッチレジスターが実体で、捕獲入力のレジスターは仮想的な感じだ。

 さらに、データシートを調べていって、決定的な表を見つけた。

表11-2. 動作種別(ページ48)

番号 ICEN0 TCW0 CTC0     動作種別 TOP値 OCR0x更新時 TOV0設定時
--------------------------------------------------------------
0    0   0    0  標準8ビット動作             $FF    即時  MAX($FF)
1      0       0        1    8ビット比較一致
                             タイマ/カウンタ解除(CTC)動作  OCR0A  即時   MAX($FF)
2       0      1        x    16ビット動作                    $FFFF    即時   MAX($FFFF)
3       1      0        x     8ビット捕獲入力動作        $FF       即時   MAX($FF)
4       1      1        x    16ビット捕獲入力動作        $FFFF   即時   MAX($FFFF)

 なんのことはない。これではっきりした。動作種別があって、もともとTinyx61のタイマー0は、インプットキャプチャーか、コンペアマッチにしかならないのだ。Tinyx61はTiny24/44に較べると古い設計のようで、インプットキャプチャー機能が独立していない。

 まあ、データシートを読み込まなかった自分が悪いのだけれど、何とも後味の悪い解決だ。データシートにちゃんと書いていない。OCR0Aレジスターは、インプットキャプチャーをenableにすると、コンペアマッチレジスターにならないのだ。

 いかにも両方出来るように書いてある。しかも、インプットキャプチャーのレジスター定義(ICR0)がデータシートにあるのに、ヘッダーファイルにない。混乱する。捕獲入力の値はOCR0AとOCR0Bレジスターに16ビット分が、TCNT0LとTCNT0Hから移されるというのオチである。

 インプットキャプチャーとコンペアマッチ機能は排他的だと、ひとこと書いてくれれば、何もここまで迷うことはなかったのにと八つ当たりである。いずれにしても、データシートのとおり、OCR0Aなどを使って、初期の目的は、Tiny861でもやっと実現した。274イベントのエアコン波形もめでたく記録された。

ロジアナの波形を頼りにプログラムの改修。至福の時(5/28/2016)
 めでたく全部のデータが記録されたので、中身の検証に入る。ここからは、オシロやUARTでは無理で、ロジアナの登板である。赤外線受信モジュールのふるまいは、正確にロジアナで捉えられている。

 それに加えて、マイコン内の割り込みルーチンや、データの処理部分にプローブ(GPIOピン)を設定し、調べ始める。20ピンのTiny861なので気楽に設定できる。

 うーむ、採集された値は、だいぶ原データと違う値だ。受信モジュールの割り込みから、本来のデータ収集をする時点がばらばらなので。誤差が大きい。これは、割り込み時点ではフラグをだすだけで処理をメインに持ってきているので、そのあいだに別の割り込みが入ったりして違ってくるのだろう。この方式では駄目だ。Ws000007

 これはやっぱり、割り込みルーチンの中で処理を全部済ませる必要がある。どうせなのでソースコードをつらつら眺め、コードの短縮化を図る。元のプログラムは律儀にピン(キャプチャーピン)の状態を忠実に調べてから、割り込みの区別(立下りか、立ち上がり)を換えているが、考えてみれば、これは必要ない(単にスイッチするだけで良い)。

 さらに、赤外線データのひとかたまりのデータの最初とそれ以降を区別するフラグを設けていたが、これも考えてみればいらない。最初につかんだデータは使わなければ良いだけだ。ただ、これによりタイムアウトだけが最後まで解決できなかった。データを受信したという印がなければタイムアウトを起こせない。 結局、このデータが来始めたことを知らせるフラグを復活させ、「データが来始めてタイムアウトするときだけ」真のタイムアウトとし、他のタイムアウトは無視するという逆転の発想で解決した。Ws000006

 こうして、割り込みプログラムの誤差はどんどん小さくなり、最終的には、当初200μs以上誤差のあったキャプチャーは、すべての遅れを5μsまで下げることが出来た。これは痛快だった。Arduinoを使っている限りでは、味わえない醍醐味である(シールドの設計者が独占している)。

 ロジアナの画面に、綺麗に揃ったパルス列を並べて至福の時を過ごす。UARTのデータもきっちり5%以下のAnalyz_remocon誤差で記録されている(0.33~0.31の範囲なので、2/32 = 6.25%)。あとは、この値に基づいて赤外線LEDを制御するだけである。紙数が増えてきたので、このあたりで報告しておこう。

Ws000004_2

 

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

2016年5月 9日 (月)

落穂ひろいの電子工作とRaspiの自動電源制御装置の改良

 Raspi3は簡単に動いた。しかし、もともと目的なしに衝動買いしたアイテムである。適当なアプリケーションはまだ思いつかない。画像処理は高速で、ネットサーフィンもそれほどストレスなく楽しめる。これをサブマシンのPCにしても良いのだが、今、特にそれが必要だということでもない。

 ということで、今まで懸案だったが、手をだしていなかった細々した周辺の工作やトラブルシューティングにいそしんでいた。そのうちひょんなことから新しいテーマが見つかり、連休はそれに夢中になっていた。この話はあとで詳しくするとして、その前のいくつかの作業についてご報告しておこう。

LM380革命アンプのケース入れ(4/15/2016)

 現在、当研究所のPCデスクには、4年前に作ったアナログオーディオチップLM380を使ったステレオアンプが、お菓子の空きプラケースに入って載っている。ケースのサイズが小さすぎ、スピーカー端子がはみ出してしまったため、未完成のままだ。

Dsc004420012  このあと作ったカナデンのデジタルアンプがちゃんとしたケースに入っているのに(といってもタカチの安物だが)比べると、少々扱いが雑で前から気にはなっていたが、そのままになっていた。 

 机の上に置いたままにしているのは、たまにスピーカーコードを切り替えて、こちらで聴くときがあるからだ。透明感のあるすっきりした音で、気分が乗らないときはこのアンプでバロック(それも初期)を聞くと、カマデンより疲れない気がする。

 このアンプは革命アンプと言われ、この制作記事は、今も当ブログで結構アクセスの多い記事のひとつだ。手が空いたので、折角だからこれをまともなケースに入れてやることにした。手を動かしていないと落ち着かない性分になっている。

 どんなケースにするのか、あれこれ迷ったが、結局、カマデンと同型(SW-125)のケースに落ち着いた。うーむ、創造力が落ちているなあ。まあ、形を統一するというのも環境を美しくみせるコツのひとつだと無理やり理屈をつける。

Dsc004210002  こんどは、カマデンのとき失敗した送風孔の位置を正確に開ける工夫をしてみよう。まず、1.2ミリ程度のドリルで下穴をあけ、錐やアートワークナイフで微調整する。そのあと2回くらいドリル穴を換えて所定の大きさ(3ミリ)にする。この結果、完全ではないが、前に較べれば格段に揃った穴があいた。

 基板の固定方法では苦労した。アンプ基板はケースのことを全く考えずにレイアウトしてあるので、可変抵抗器や、入力ジャックが外に出るようにしたら、ケースの側板と基板が干渉して、ケースがはまらなくなってしまった。

 本来なら基板の実装を変えるところだが、無精して、可変抵抗器の軸をパネルに固定することにした。こうすると今度は基板の固定が非常に難しくなる。正確に穴あけをしないと基板固定ポストの接着がすぐ外れるし、開け方を忘れて無理にはずそうとするとポストは簡単に破壊されてしまう。

Dsc004430013  基板の固定は、このままでは可変抵抗器の軸だけなので、フォンジャックを差し込むときはぐらぐらするし、いずれは可変抵抗器は壊れるだろう。どうしたら合理的な固定法があるか頭を捻った。

 色々考えた挙句、ケースには可変抵抗の軸だけで固定し、裏蓋をはめたあと、裏蓋から基板を釣る形で固定した。これでフォンジャックを差し込んでもぐらぐらしなくなった。

 こういう実装方法を考えるのは、実はとても楽しい。参考にする情報もないし基準もないので自己満足そのものだが、うまく行った時の快感はソフトでしつこいバグを見つけた時くらい大きいものがある。Dsc004260004

沢山の実用品の修理。腕時計の自動巻き機の修理にはまる(4/21/2016)
 これまで作った数多くの電子工作品が年を経て次々に故障を始めている。プリンターのLAN電源制御1号機がまた故障した。こいつはモジュラージャックの終端抵抗が内部で断線していることを、一年前、長い間かかってやっと突き止めたものだ。

 件(くだん)の抵抗器はリード線を強く押えたところ復帰したので横着して交換せず、そのまま動かしていたのだがやっぱり再発した。この交換は結構面倒なのでそのままになっている(プリンターの遠隔制御が必要なくなったこともある)。

 メトロノームの正確な時間間隔を測定するリズムキャプチャーも最近ノイズが出てうまく動かなくなった。電池を交換したが症状は変わらない。どうも電圧不足ではなさそうだ。今急にこれが必要ということもない(保有するメトロノームの補正は済んでいる)ので、これも手がついていない。

 そのうち、ここ4年近く毎日動いていた腕時計の自動巻き機もおかしくなった。ソフトパワースイッチを装備し、スイッチの長押しでスタート、さらに長押しでパワーが切れるようになっている。毎日、定期的に動かすため、昔FMのエアーチェックに使っていたタイマーで電源が入るようになっている。

 電源が入った時はソフトパワースイッチでなくても動くようにしてある。一日2回動かしているのだが、このところ時計の時刻が大幅に遅れることが多くなった。電源が入っても動かないときがあるようだ。

 試しに、タイマーではなく単に電源を入れてみる。ちゃんと動く。タイマーでスタートさせてみる。今度は動かない。ふーむ、接触不良か。重い腰を上げて、工作テーブルに持ち込みUARTを付けて様子を見た。すると問題なく動く。いつもの場所に戻す。動かない。何か馬鹿にされている感じだ。

 この装置のUARTはISPケーブルを使ったChaNさんのUARTを改良したものだ。どうもこいつを接続しているときはエラーが起きない。調べるうち現象がだんだん見えてきた。整理すると次のようになる。

Dsc004270005  パワーダウンモードでスリープしているときに電源が切られると、そのあと電源を入れても復帰しないことが多いということがわかった。タイマーがONになっている時間は、この装置の1セットの運転時間より長く、必ずパワーダウンモードでスリープに入る。UARTをつないでいるときは全くトラブルは起きない。

 これまで順調に動いていたのが何故こういう現象になるのかが謎である。接触不良ではない。片手間で調べられなくなった。すこし本腰を入れることにする。ISPケーブルがつながっているのは、MOSI、MISOなどのピンでこれらが全体に影響が出てくるとは考えにくい。あとは、VccとGNDそれにRSTだが、やはり、RST(リセットピン)が一番臭い。

 オシロに接続する。パワーダウンスリープに入ってもRSTはHighのままではある。ここまでは当然だ。しかし、電源コネクターをはずしても、RSTは下がらない。何と、これはどういうことだ。

 早速ウェブに助けを求める。スリープでは、すべてのピンの状態を保持すると書いてある。しかし、電源を切ってもRSTを含めたピンが続くとはどこにも書いていない。この電力はどこから来ている?わけがわからない。

 スリープでなく通常に動いているときに電源を切れば、すべてのピン(RSTを含めて)はあっさりLowレベルに落ちる。ところがスリープ状態では、電源をはずしても、信じられないことにRSTはHighのままなのだ。

AVRのパワーダウンスリープはVccまで保持される!(4/24/2016)
 あわててAVRのデータシートを見るが、そんなことはどこにも書いていない。I/Oピンが保持されるとはあるが、リセットピンまでがそうだとはどこにも書いていない。そのうち、もっと思いがけないことが分かった。そもそもVccが下がっていないのである。オシロを2現象にしてみて初めて分かった。

 確かに、このシステムには、モーターの突発的な駆動電流の影響を考慮して、Vccには100μFとインダクターのフィルターが入っているが、パワーダウンスリープでないときは、電源を切ると、一気にVccは下がるのに、パワーダウンスリープではなかなか下がらない。

 それではと、このコンデンサーを接続からはずしてみた。驚いたことに症状に変わりがない。パワーダウンモードでないときは一気に下がるし、ISPケーブルを差した場合はどちらも簡単に0にもどるのに、パワーダウンスリープ中での電源断では下がらないのだ。

 信じられない。とにかく、この影響でおかしくなっていることは明らかだ。Vccとリセットが0に戻らないので、再度電源を入れると、CPUは不安定な動きになる(暴走状態)。 

 試しに、10KΩでVccピンをシャントすると、あっさり落ちる。しかし、これではパワーダウンスリープ中も、この電流は流れ続け、なんのためのソフトパワースイッチかわからなくなる。なんとかならないか。

 しかもこの問題がなぜ顕在化せずにここまできたのかというのも謎である。少なくとも、ここ半年前までは、全く順調に動いていた。最初の長期動作テストでは、UARTを入れて調べているので、この問題がわからなかったのは当然だが、最近起きはじめたというのが、どうも解せない。

パワーダウンスリープ中の電源断は想定外のことなのか(4/28/2016)

 さらに、もっとおかしいことがわかった。パワーダウンスリープのとき、ACアダプターのジャックをはずして、再度、電源を入れ直すと正常に復帰することが多いのだが、ACアダプターをつけたまま、AC側で電源を切ると(現行タイマーの使用状態)、ほぼ確実にAVRはハングアップする。これは一体どういうことか。

 不思議なことに、ISPケーブルをつけたままでは、この症状は起きない。オシロで見ている限りでは、Vcc、RSTピンの電圧は、2分もすれば、0Vまで低下している。タイマー運転は1日に2回だけ。パワーオンリセットには十分な低電位だと思うのだが、ハングアップが起きているようだ。

 それにしても、経年変化でこういうことが起きている。パワーダウンスリープにしたまま電源を切ってしまうと、どういう動作になるかというのは、調べた限りウェブ上に情報は見つからなかった。

 確かに、ソフトパワースイッチの前提は電池駆動で電源は常時ONであることが前提だ。OFFになることは想定していない。従って、ここでの追及はどうも、CPU内部の話に行き着きそうで、余り深く詮索することは無理なような感じがしてきた。

 完全に暗礁に乗り上げた。こればっかりやっているわけにも行かない、移りたい次のテーマが見つかっている。残念だが、これは少し棚上げにしよう(少し閃いていることがあるが)。

Raspiの電源制御装置2号機の準備(5/1/2016)
 Raspi3周辺でやりたいことが見つかっている。それは以前、初代のRasPiで作った電源制御装置である。スイッチを押すだけで電源が入り、shutdownすると電流量の減少を検知してリレーで電源を切る。一般のPC と同じ操作イメージである。

Dsc004300008  ただ、問題なのは以前のプログラムではshutdown時の電流量が決めうちなので、ペリフェラルをつないだりすると(例えばHDD)、うまくshutdownと認識してくれない。個別にコンパイルし直さなければならない。これを何とかしたい。これが汎用化されれば使いみちはぐっと広がる。

 初代のRaspiに較べ、RasPi3は2.5Aが最大電流なので、前の2Aのリレーでは不安である。もう一台作ることにする。部品箱から手持ちのリレーを探す。たまたまあった3Aは少し大きく、これまでのケースには入らない。

 今度はUSBソケットを入れる予定だが、手持ちの少し大きいケース(タカチSW55)では何か間抜けな感じだ。ということで久しぶりに秋葉原に行って部品を調達することにした。

久しぶりのAVRの開発とケース工作にはまる(5/3/2016)
 連休中の秋月は大混雑していた、RasPi3が店頭に平積みで山のように並んでいた。値段は前と同じ¥6200で、どこよりも安い。早まってよそで買ってしまったことを少し後悔する。

 それはともかく秋月で見つけた3Aのリレーは前と同じ大きさで、余り小型化に寄与しない。諦めきれずに千石本店の2Fに行く。さすが千石だ。沢山のリレーがあった。値段は、秋月の4倍以上するが、スイッチング最大電流は2Aで最大通電電流3Aの国産オムロンのものが見つかった。

Dsc004290006  しかも、こちらの方が格段に小さい。これだけ小さくなれば、USBソケットを入れても前と同じケースに入るかもしれない。4倍といっても単価は¥400台だ。迷わず買い込んだ。リレーがこんなに高くても、この装置の部品代の総額は¥1000以下で押えられるはずだ。

 ただ、本当にこれまでのケースに入るか心配なので、これまでの小さいもの(タカチSW-40)に加えて、これより少し大きく、今までのものより小さいSW-50というのも念のため買っておいた(¥120)。

 帰ってきて部品合わせをしてみると、これが大正解だった。今度の装置はUSBのAタイプのジャックを入れることにしたのでSW-40はとても入らない。SW-40の1.5倍の大きさのこのSW-50がぴったりだった。

  小さなケースの工作は久しぶりである。楽しい。アートワークを念入りにやる。この前のときは、しっかり誤配線をした。ピンとピンの間隔が少ししかないので間違いやすい。回路図は前と全く同じにする(ソフトをこの前の無印Raspi用と共用したいため)。

 ケースの固定でまた遊ぶ。この前のものは2.6ミリの小さな固定ネジを4つも使っていたが、今度は裏蓋は単に蓋にするだけで、ケース上蓋に全てを実装することにした。

 考えているだけでは、先に進まないので、基板を切りだして、実際にソケットやプッシュスイッチを仮止めして、ケースと現物合わせをしながら入るかどうか試してみる。対象が小さいので自由度が極度に制限されるが、これが楽しみの要因になっている。箱庭、盆栽と同じような気分である。

Dsc004330007  ケースに少しづつ穴をあけ、部品がうまく入るか何度も調整を重ねて先に進める。USBソケットが出る穴を少し大きめに広げると、ちょっと見栄えが悪くなるが、きれいに入ることが分かった。ケースはABS樹脂なので加工が容易なのが助かる。

配線は間違っていなかったがTiny13を2回も逆ざし、一個失う(5/5/2016)
  ハードの実装は見通しがついた。次はソフトの方である。大分前から考えている(ソフト開発は紙と鉛筆さえあれば、いつどこでも出来る)。ターゲットはTiny13なので沢山ロジックは詰め込めないが、通電中の電流値をEEPROMに蓄積し、これが1/3や、1/2になったときshutdownと判定するロジックで良いはずだ。ただ、1KB以内に収めたい。Tiny85でも良いが少し勿体ない。

 最終的に決まったロジックは以下の通りである。EEPROMは使う必要がなかった。まず、Raspiの消費電流をシステムが立ち上がった一定の時間の後から計測を始め、この平均値から一定量以下の電流値をシャットダウン時の電流とみなして、この値で待機する。

 このロジックの根拠は、沢山のペリフェラルがあっても、シャットダウンのときとアクティブなときの間の電流差は一定という考え方に基づいている。比率でシャットダウン電流を推測するより汎用性があるはずだ。

 擬似コードでは、簡単に「一定時間待ったあと電流の平均値をとる」と書いたが、実際のコーディングはどうしたら良いのだろう。 プログラムは考えたようには動かない、書いた通りにしか動かない。まあ、あまり深刻に考えてみても仕方がない。コーディングしてみよう。

 書き始めると思ったより簡単に実現できた。もともとこのシステムは電源を入れた後、定期的(0.5秒毎)にADコンバーターを動かして電流値を測定している。この回数を記録しておいて、一定の期間の電流値をしまっておくだけである。それまでは、強制終了以外の電源断は行わない。途中で止めれば、最初からやり直すだけである。

Dsc004350010  さあ、出来た。考えたようにコンピューターは動いてくれるのか、ドキドキの瞬間である。

無印Raspiの2機とRaspi3で完動(5/7/2016)

 始めは、慎重にセメント抵抗を負荷にしてテストを始める。おやあ、頼りのUARTが出ない。同じ配線なのに、おかしい、何か虫が知らせたので、すぐ電源を切り、部品を触る。アッチッチ、CPUがやけどしそうに熱い。これはいけない誤配線だ。

 8ピンのCPUの配線を前回に続いて間違えるとは情けない。基板を裏返して最初から配線チェックをする。間違っていない。うーむ、どうしてだ。まさか、CPUを逆差ししているのでは、はい、逆になっていました

 あの熱さでは、息が絶えているか心配だったが、幸い、Tiny13はけなげに生き返ってレスポンスを返し、ファームの書き込みも無事に終わった。祈る気持ちで再度電源ON。よーし、ボタンを押すと、SCKを使ったUARTからメッセージが出て、1秒ごとの電流値を表示し始めた。(実はこのあと実装でまた逆差しし、ひとつをお釈迦にしたことは秘密)。

Dsc004390011  秋月でついでに面白がって買ってあったUSBメーター(積算値つき)をつけて、本番のRaspi3に接続する。1分後から計測を始める。30秒の平均値を出し、それより200mA低い場合はshutdownとみなすロジックにした。USBメーターは0.27Aを示し、shutdown時は0.04Aなので、これでぴったりマシンの電源が切れた。

 次は問題のSAMBAサーバーにしている無印Raspiのテストである。このRaspiにはハブ経由で2.5インチHDDがついている。HDDだけで0.2Aは常時流れる。最初作った電源制御装置は、この待機電流にそなえるため、コンパイルしなおして初期値を設定した。

 新しい制御装置に切り替えて、つまりRaspi3の設定のままで、テストする。何事もなく立ち上がった。shutdownである。こいつは、GPIOピンを見てshutdownコマンドを送る機能がついているので、所定のスイッチを長押しする。LEDの点滅が激しくなり、shutdown処理に入った。

 少し長い間、高負荷の電流が流れた後、「チッ」と小さな音がして、無事電源は切れた。よーし、それでは、もうひとつの無印Raspiはどうだ。こいつは今動かしていないが、ウェブカメラのサーバーになっている。

 こいつも問題なく、スイッチひと押しで電源ON、shutdownコマンドで電源OFFが実現した。うーむ、今度は売り物になるかもしれないな。今までのものは機械にあわせてコンパイルしなおす手間が必要だったので、みんなに使ってもらうことを躊躇っていたのだが、これなら問題ない。

こちらにTiny13による電源制御装置2号機のソース一式をAtmelStudio7のフォルダーの形でzipにかためたものを置きます。回路図は前の1号機と全く同じで、ソフトは共用できます。

「AutoPwr13a.zip」をダウンロード


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

2015年10月31日 (土)

Tiny85のI2Cスレーブライブラリーのソースコード公開

 いま流行(はやり)の電子工作というのならArduinoなのだろうけど、こちらは今やイギリスの半導体メーカーに買収されてしまったAtmelの8ピンマイコンでソフトI2Cを自作している。こんな遊び方は、時代錯誤になりつつあると思うが、これが当人には結構面白く、ハマっている。

 I2Cは必要ラインが少なくてすみ(2線。グランドを入れて3線)、バス接続が出来るのでピン数の少ないマイコンでは定番の通信インターフェースである。専用のハードではなく普通のI/Oピン(GPIO)を使ってソフトウエアでこのI2Cを実現したのものをソフトI2Cと呼んでいる。

 ただ、GPIOによるI2Cインターフェースのソフトは、マスター側がほとんどで、スレーブ側の制作例は珍しい。マイコンがマスターになって、スレーブであるI2C機器を制御するというのが一般的だからだ。スレーブをソフトで作るというのは今度のように、I2Cのない周辺機器をI2C化するときくらいに限られる。

01pa307348  前記事までに、I2Cスレーブソフトは、目標のTiny85で一応動いたのだが、これは当面の目的である超音波距離測定ユニットHC-SR04を動かす部分の機能だけで、汎用的な用途にはまだ不安がある(連続データの送受信など)。

 前回、ソースコードを公開しなかったのは、せっかくここまで動いたのだから、もう少し、色々なところで使えるように機能を拡大してからと考えたためである。 追加の開発は楽に出来ると思っていたのだが、実は結構てこずった。

 ああでもない、こうでもない、と試行錯誤の結果、何とか安定して動くスレーブインターフェースの開発に成功した。もうソースコードを公開しても恥ずかしくないレベルに達したと思う。誰かが使ってくれると嬉しい。

I2Cスレーブはユーザーインターフェースが難しい(10/10/2015)
 I2Cインターフェースのスレーブ側は基本的には完全な受け身で自らは何も動き出さない。マスター側のトリガーをひたすら待ち続ける。スレーブのメインプログラムは無限ループでマスターからの信号を待ち、通信が始まったら、マスターの出すクロックの指示をすべて守らなければならない。

 こういうときは、マスターからの信号は割り込みで処理するのが一般的である。マスターからのデータはひとつも落とせないからである。このためにスレーブ側のメインプログラム(対象機器の制御、データの受け渡し)は、I2Cとのやりとりの合い間に動くバックグラウンドタスクとして、非同期で動かす必要がある。

 こうした方法の定番というのを分かりやすく解説している参考書やウェブの記事を、これまで見たことがない。どういうやりかたで作るのが良いのかいつも悩む。このあたりのロジックや、アルゴリズムは、マルチタスクを制御するOS(オペレーティングシステム)のしかけそのものなので、市販の参考書はそれを意識して、たいてい仰々しい書き方になっている。実務的にとても理解しにくい(初めて読む人にはわけがわからないだろう)。

 最近はOSをやさしく紹介する本がいくつか出ているが、実際のソースコードまで落としたものは少ないようだ。目的がOSを理解させることで、具体的にソフトを動かして何かの用を足すことを目的にしていないからである。

 前記事までのソフトI2Cスレーブのメインプログラムは、あくまでもHC-SR04を動かすために特化しており、このままでは他の用途に使いにくいし、汎用的に使うにはまだ機能が不足している。ちょうど良い機会なので、他にも応用が出来るような構造にし、併せて解説も少し足し、これから同じようなことに挑戦される方の参考になることを狙うことにした(誰もいないか)。

 現在のライブラリの形式は、I2Cインターフェースそのものはi2c_slave.cというソースファイル1本に集中させ(ヘッダーファイルは、i2c_slave.h)、アプリケーションに依存するコマンド解釈などの機器制御とデータの受け渡しは、メインプログラムi2c_SR04_85.cにまとめてある。

02pa307350  従って、違う機器(LEDや、液晶表示装置、温度センサーなど)をI2C化するときは、このメインプログラムだけを目的に合わせて変更すれば良いようになっている。前にも触れたように、このあたりは定式化したやりかたがない(もちろん、知らないだけという可能性もある)ので、がた老AVR研究所なりの方法論で話を進めることをご了承願いたい。

 やり方は次の通りである。まず、使いそうな機能をいくつか想定して、実際にそれを実装する。このしくみを詳しく説明すれば、メインプログラムと、割り込み駆動のI2Cルーチンとの間の動きが明確になり、他への応用が容易になるのではないかという狙いである。

連続データの送受信が非同期で出来れば文句がないだろう(10/14/2015)

 どんな機能が役立つのかは、このI2Cスレーブを使う具体的な例を考えて、それを基に決める。色々検討したが、やっぱり今度のように非I2C機器をI2C化することが一番多いのではないかという結論になった。

 LCDなどの表示装置は既にI2C駆動のものも多いが、パラレル駆動のLCDや、LEDマトリックス、グラフィックLCDなどは、必要なI/Oピンを少なくできるのでI2C化するメリットは多い。ただ、これらの表示装置は、マスターからスレーブへの出力が殆どなので、I2Cとしてはそう難しくない。さらに、全体の処理速度を早くするために、多バイトのデータが一気に送れる機能があれば、もう文句はないだろう。

 一方、EEPROMやRTC(リアルタイマークロック)などの入力ディバイスは、スレーブからマスターへのデータ転送が必要になる。こういうディバイスには、マスターからコマンドを受け、すぐにリピートスタートで求められたデータをスレーブからマスターへ送り出す機能も必要になるだろう(この機能はこれまでの記事の通り開発済み)。

こうしたことから、汎用的なモデル機能を以下のようにまとめた。

(1) UARTコンソールのように、マスターから一定の長さのテキストを送り、スレーブ側で蓄積し、コマンドでそのデータを送り返す機能。

(2) スレーブ側に何らかのデータを用意し、マスターからのコマンドに応じたデータ値を1シーケンスでマスター側に送り返す機能。

(3) マスターからのコマンドによって、スレーブ側に接続した機器を制御する機能。これは(2)のバリエーションで、今回は、超音波距離センサーなどの起動トリガーコマンドがそれにあたる。

連続データのマスター書き込み(送信)は簡単に片付いた(10/15/2015)

 まず、(1)の擬似UART的な機能の送信の部分である。マスター側のコンソールから連続したデータ列をリターンキー(\r)を終端文字として一気にスレーブに送り、それをバッファーに一旦貯めた後、別のコマンドで一気にエコーバックさせる。

 これまでの開発で完動したのは、HC-SR04での、マスターからの1バイト送信と2バイト受信だけなので、今度は、スレーブの受信リングバッファーがオーバーフローしないように、スレーブのメインプログラムと割り込みルーチンがマルチタスク的に動く必要がある。

 メインプログラムで、割り込みルーチンのリングバッファーのポインターを常に調べ、割り込みルーチンでデータが入って、ポインターが進めば、すかさずデータを本体の配列に収容する。UARTなどでいつもやっている方式と同じである。

 マスター側のドライバーにコマンドを新設し、;(セミコロン)のあとの文字列が一気に送られるようなコードを加える。コーディングは簡単にすんだ。テストである。よーし、スレーブ側のデバッグ用のコンソールに送ったデータが綺麗に並んだ。これは問題なく動いた。

Tiny85console
次のマスター連続受信(スレーブ送出)が難しい(10/16/2015)
(1)のもう一つの機能、マスター連続読み込み(受信)である。マスターからのコマンドによって、配列などに貯められたデータを一気にスレーブ側から、マスターに送り返す。スレーブ側は待つだけで、駆動するのはマスター側のクロックであり、スレーブはそれに従ってデータを載せて行く。

 ここで問題が発生した。書き込みのときは、コンソールのキーボードから打ちこまれた終端文字のリターンキー(\r)文字を見てマスターがストップコンディションを発行し、スレーブ側はこれを検知する機能があるので(前々記事参照)、問題なく通信が終了する。

 しかし、マスター読み込みの終了は、最終文字のACK/NACKビットでマスターがNACKをセットし、スレーブに返すことになっている。マスターが、送られてきた最終文字(リターンキー)のACK/NACKビットに、NACKをセットすることは時間的に不可能なので、マスターはリターンキーであることを知ったあと、ストップコンディションを挿入することになる。

 うーむ、困った。スレーブ側にはマスター読み込み時のストップコンディション検知機能がまだ実装されていない。固定量のデータならマスターが最終文字にNACKをつけるので正常に止められるが、このままでは、可変量の連続読み込みの送信終了は受け取れないことになる。どうしよう。

 ここまで来て、引き下がるわけにはいかない。乗りかかった船である。マスター読み込みのステートマシンに、ストップコンディションを検知するロジックを追加した。コードそのものは、マスター書き込みのところと同じなので簡単に出来た。ただ、フラッシュサイズは3Kバイトを超えた。

 しかし、これがどうやってもまともに動かないのだ。ストップコンディションを検知できなくて、すべての通信でタイムアウトしてしまう。ロジックアナライザーを再び引っ張り出して、ステートマシンをプローブして、原因がわかった。懸念していた通り、処理が次のクロック(SCL)パルスに食い込んでいる波形を発見した。クロックが8Mhzでは、今の50khzのI2Cが通らない。

 結局、マスター読み込み(スレーブ送信)でのストップコンディション検出はあきらめる。となると何か回避策を考えなければならない。良い方法を思いついた。

 リターンキーを受信したら、とにかくマスターはもう一文字受信し、この文字にマスターがNACKビットをつける。こうすると、スレーブに通信終了を知らせることが出来る。マスターはこの文字を捨てればよい。ちょっと姑息だけれどなかなか洒落た方法だ。

 スレーブ側の、NACKによる終了はこれまで正常に動いている。上機嫌で自信満々テストに臨んだ。ところが、これでも通信は正常に終わらない。つねにタイムアウトしてしまう。ロジアナで見ても正常な波形だ。もう調べるところがない。完全に暗礁に乗り上げてしまった。

旧友会が2回(10/18/2015)

 息抜きに、ここで、ちょっと電子工作以外の話題をご紹介する。同窓会の話題である。これまで、時々、話してきた小学校や高校の同窓会ではなく、珍しい古い友人からのお誘いが偶然に、続けて2つもあり、久しぶりに飲み会をやった。

 ひとつは、40年前、地方に転勤した時に一緒に仕事をした会社仲間の旧友会で、もうひとつは、同じ会社ではなく、20年前に仕事で親しくなった取引先の友人の同窓会である。どちらも10年くらい前までは頻繁に会っていたが、このところご無沙汰だった。

 それぞれ、出席者の殆どはもう現役を離れている。まず、会うなり「病気と、孫と、髪の毛の話は禁止」という宣言が出て大笑いした。良く見るとみんな相当な禿頭だ。まあ、それはともかく、昔話というのはいつになっても楽しいものだ。結論から言えば、どちらもとても楽しかった。

 会社の旧友会には実は余り顔を出したことがない。現役の頃の上下関係をいつまでも引きずる人間が少しでもいると周囲の雰囲気が悪くなり気分よく話が出来なくなるからだ。今回は幹事が、人を選んでくれたようで全く違和感なく昔話を楽しむことが出来た。

 こうした旧友会は、自分の人生を遠くから見るような解放感がある。この年になると、現役時代の熱い感情的な部分が削ぎ落とされて、自らを、良くも悪くも客観的にみている自分を発見する。今さら何が出来るわけでもない。達観した見方が出来るのだ。

 2つの会合とも、久しぶりに酒が進み、帰りが大変だった。まあ、何とか人の迷惑にならずに帰宅できたが、この年で深酒はほどほどにしておいた方が良い。自戒、自戒である。

マスター連続受信(スレーブ送り出し)終了条件の謎(10/21/2015)
 電子工作の話に戻ろう。いやあ、今回も解決までが長かったが、苦労の甲斐あって、これまで不安定な動きをしていたマスター読み込みは、完全にNO ERRORで動作するようになった。

 今回の不具合は、前のバグのように、お馬鹿なミスが原因ではなくて、複雑な要因で起きていたバグだったが、少しづつ事実を積み上げ、思い付いた仮説を検証しながら、最終的にバグの原因を解明できたので、すこぶる機嫌が良い。迷宮入り寸前の難事件を見事に解決した名探偵の気分である。

 マスターからの連続書き込みは簡単に成功したのに、マスターが連続して読み込む方は、どうも調子が悪い。マスター読み込みは、スレーブがデータを送った後、マスターからNACK/ACKビットが返ってくるので通信の終了はストップコンディションが出なくても通信終了になるはずなのに、現状は殆どの通信がタイムアウトになってしまう。

 気に入らないのが、すべてがうまくいかないのではなく、時々正常に終わるときがあることだ。何かのタイミングで起きたり止まったりするというのが、一番厄介なトラブルである。ステートマシンにプローブ(SR04のトリガーピンを流用)を入れて動きをロジアナで確かめる。

 確かに、NACK/ACKビットを調べるステップで、マスターはNACK(1)を返し、そこをステートマシンが通過していることは間違いない。それならタイムアウトフラグはここでクリアされ正常終了するはずだが、そうなっていない。

 そうだとすると問題はそのあとだ。一連の通信が終わったあと、割り込みルーチンはステートマシンを初期状態に戻し、割り込みをクロック(SCL)からデータ変化(SDA)に替えて、次のスタートコンディションを待つ。このあたりがうまくいっていない可能性が高い。

 しかし、マスターは、NACKを返した後、ストップコンディションを発行している。ロジアナにもはっきりした波形が出ている。たとえ、NACKでリセットできなくても、ここでストップコンディションによって割り込みルーチンは初期状態に戻り、リセットされるはずだ。それなのにタイムアウトになる。二重におかしい。

遂にマスター連続受信に成功。原因はNACK処理ではなかった(10/25/2015)

 謎は深まるばかりだ。そこで、今度は、ステートマシンではなくて、スタート/ストップコンディションを受ける初期状態のデータ(SDA)の割り込みにプローブをかけてみた。本当にリセットされてこの割り込みを受けているか確認するためである。

 確認したからと言って何か成算があるわけではないが物は試しである。半信半疑でロジアナを動かす。問題の通信終了のシーケンスを拡大する。おやあ、ACK/NACKビットを受けるステートマシンの直後に、スタート/ストップコンディションを受ける割り込みが2つも発生しているではないか。

Tiny85stop  先に触れたストップコンディションの時に発生するのは想定通りだが、その前の割り込みは何なのだ。あっあっあー、わかったぞ。マスターがストップコンディションを出すための準備に、SDAをLowにする準備の部分を拾ってスタートコンディションにしてしまっている!

 NACKのリセットのあと初期状態に戻るのが早い割に、実際にSDAの割り込み処理に来るオーバーヘッドが長すぎ(17μsもある)、次のSCLが立ち上がってしまってスタートコンディションと誤認してしまったのだ。

 しかも、一旦、スタートコンディションと認知してしまえば、割り込みはSDAからクロック(SCL)に移り、このあといくらストップコンディションが来ても無視される。時々動くのは、SCLの立ち上がりの前に割り込みルーチンに来るときがあるからだ。このときは問題なく動く。よーし、間違いない。すべては氷解した。

 原因はわかった。しかし、SDAの割り込み遅れを早くすることは出来ない。そもそもは、ACK/NACKビットのSCLの立ち上がり中にリセットしてSDA割り込みを待ち受けること自体が違反だ。ここはSCLが下がって次のステージに入ってから、スタートストップコンディションを待ち受ける体制にするべきなのだ。

I2cslave_85  ACK/NACKビットのステートマシンのところに、SCLが次のブロックに行くまで待つプロセスを入れて、これまでのタイムアウトは完全に解消された。連続データは勿論、(2)のリピートスタート処理も全く問題なく動く。

 いやあ素晴らしい。仮説に基づき、ロジアナで少しづつ事実を追いながら原因を突き止めた。「デバッグは外へ、外へ」という格言どおり、原因は意外なところに潜んでいたのである。

ソースコードの公開。readmeもつけた(10/30/2015)
 紙数が増えてきたので、(2)や、(3)の機能の説明は、添付するソースコードのフォルダーの中にあるreadme.txtにまとめて書いたので、そこを参照頂きたい。回路図も念のため掲載しておく。

 冒頭でも述べたが、このソースコードはSR04というセンサーユニットをI2Cで動かすための機能と、連続データの入出力などのテスト機能が入った、汎用的なモデル機能をデモするプログラムで余り実用的なものではない。

 このソースを参考に、ご自分の用途にあったI2Cスレーブのプログラムを開発されたい。そういう意味では、余計な機能や冗長なコードがまだ沢山残っており、余り自慢できるものではないが、少しでも参考になればと恥を忍んで公開することにする。

以下に、2つのファームウエアのフォルダーとreadme.txtなどをzipでかためたファイルを置きます。同じファイル名でも、以前に公開したファイルと内容は全く異なっていますのでご注意ください。  

「I2CslaveSet.zip」をダウンロード

上記のライブラリーは改訂されています。なるべくこれを使わず、新しい方をお使いください(新しいリンク先)

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

2015年10月 9日 (金)

Tiny85のI2Cスレーブライブラリー完成。今度もドジなミスで大騒ぎ

Tiny85への換装を考える(9/17/2015)
 Tiny861でI2Cのスレーブソフトが順調に動いたので、本来の目標、8ピンAVRへ換装する準備を始めた。超音波距離センサーHC-SR04が5Vなので、小さなブレークアウト基板に、DC-DCコンバーターと、8ピンAVR(Tiny85を予定)を載せ、EdisonやRasPiのI2Cで動かそうという計画である。

 同種のプロセッサーなのですぐ動くとは思うが、ピン数が少なく外部発振子は使えないので、クロックはこれまでの16Mhzではなく内蔵のCR発振の8Mhzになってしまう。動くかどうかは、やってみないとわからない。不安なのは、デバッグ用のISP-UARTが使えなくなることだ。動作確認が難しくなる。

 ただ、これから使うTiny85はフラッシュサイズが8KBもあるので、機能的にはまだ沢山実装できる余地がある。未開発のスレーブ送信(マスター受信)でのストップコンディション検知や、マスター受信のあとのリピートスタート機能も組み込もうとすれば楽勝だ。

01pa077329  いずれにしてもピン数が絶対的に足らない。ISPでプログラムすると完全に自由なピンは、わずか2本(GND、Vcc、RST、MISO、MOSI、SCKの残り)しかない。プログラムしたあとMISOなどが使えるとしても、全部で5本である。HR04のドライブに2本(エコーとトリガー)、I2Cに2本(SCL、SDA)使うとすると、残り1本しかデバッグ用に残されていない。

 パラレルにすれば、リセットピン(RST)が使え(Dragonも持っている)、1本増えるが、手慣れたISPからパラレルプログラミングにするのも難儀なことだ。というので、苦肉の策として、ISP-UARTの送信(MISO)だけをデバッグ用に残すことにした。ぎりぎりのリソース運用である(これが苦労の原因になるとは露知らず)。

 ここで訂正とお詫びである。前記事などで、8ピンAVRシリーズにはUSI(汎用シリアルインターフェース)がないと言っていたが、良く調べると、ないのは旧型の15や、最近の13などで、25,45,85には、ちゃんとUSIがついていた(ChaNさんのAtmelの紹介の表にあるIICは誤り)。失礼しました。とはいえ今さらUSIに戻るわけにもいかない。GPIOによるI2C化を進める。

秋月とAitendoで同じ超音波距離測定センサーを入手する(9/19/2015)
  このところご無沙汰だった秋葉原を久しぶりに訪れた。秋月電子の店内がすっかり模様替えしている。マルツと同じように部品棚が店内両側の高いところまで立ち並ぶ形式である。マルツと違って棚の奥に人が歩けるくらいのスペースが空いていて店員の補給路になっている。

 今日の目的は、秋月が同じ超音波距離測定センサー(HC-SR04)を、Parallaxのオリジナル品(¥3000近い。最近見たら¥3980に値上げ)と並行して売っているのを知ったのと、Aitendoにも同一品が出ているようなので、ついでに2つとも買ってしまおうというものだ。

 秋月のあと、足を伸ばしてAitendoの直営店に向かう。ここは秋葉原というより御徒町に近い。人気の少ないオフィス街を歩いて、エレベーターに乗り3階に着くと、意外な光景が広がっていた。

 土曜ということもあるが、店内が客で溢れているのだ。驚いたことにベビーカーが2台もはいっていて家族連れまでいる。自分のようなお年寄りから、おたくっぽいリュック姿の太目の若者まで、まさしく老若男女が真剣な目つきで部品を選んでいる。 02pa077338

 前にも書いたが、いかにも中国人らしい若い女性店員は意外にも商品知識が豊富で、SR04の展示場所を迷うことなく案内してくれた。面白そうなものが沢山あったが、広い店内(秋月より明らかに広い)と人に少し圧倒されてしまいSR04だけで帰ってきた。それにしても電子工作の裾野が広がっているようで喜ばしい。

3種のSR04の比較テストでは意外な結果が出た(9/20/2015)
 超音波距離測定センサーHC-SR04が、はからずも3種類そろった。せっかくなので、3つの比較テストをした。結果は、
Aitendoで買ったもの>アマゾンで以前買ったもの>秋月電子で買ったもの
の順で、機能に大きな差が出た(値段はすべて¥400近辺)。

 秋月電子のSR04はスイッチサイエンスが告知した通りの不具合品で、一定の期間の距離測定では問題ないが、一旦、3mを超す距離を測定しようとすると、echoパルスがHighのままとなり、triggerパルスを出しても元に戻らない。電源を切って再投入する必要がある。

 アマゾンで買ったものは、3mを超すとエコーパルスがHighのままになるが、トリガーをかけると復帰する。一方、Aitendoのものは、距離が長くてもエコーパルスがHighのままになることはなく必ず復帰する(パルスはある距離を超えると一定の長さになる)。

 不思議なことに秋月のものでも物理的なショックを与えると、正常に戻る。アマゾンで買ったものと、秋月のものとは基板のパターンは、スイッチサイエンスの言う駄目なロットと同じように見えるが、良く調べてみると微妙なところに違いがある。

 例えば、秋月の製品は、クリスタルのところの小容量のコンデンサーが省かれており(パターンもない)、パスコンもいくつか省略されている。Aitendoのものはシルク印刷の状況から見るとスイッチサイエンスのいう正常な旧製品と同じように見える。

 しかし、買ってきたものが、それぞれひとつだけなので、すべての商品が上記のようになると断定は出来ない。たまたま所長の買ってきたものが、そうだったというだけである。誤解のないように。まあ、実用に使うなら秋月のオリジナルのParallax社のものが間違いないだろう(高価だが)。もっとも秋月のものでもFETか何かでタイムアウトをとりリセットすれば使えないわけではない。

プリンターを買い換えて、旧型をリサイクルセンターへ葬る(9/21/2015)
 珍しく仕事が入って、プリンターを使う機会が増えた。10年近く前に買ったカラーレーザー(コニカミノルタ 2530DL)は、印刷機能はまだ十分働くのに、最近は紙送りが不調で、最初の一枚か二枚を必ず失敗する。

 だましだまし使っていたのだが、遂にエラーが復帰せず、3枚以上の印刷が不能になった(必ず3枚目で紙送りエラーになる)。使い始めてからの年数を正確に調べてみた。8年と11ヶ月、およそ9年である。微妙な年数だ。ウェブで調べると、同程度のプリンターなら1万円台で入手可能だ。ドラムがそろそろ寿命だし、修理に出しても、軽くこれ以上の修理代金をとられる可能性は高い。

 大分前から迷っていたのだが、結局新しいプリンターに更新する決意を固めた。買うことは造作がないが、困るのは古いプリンターの処分である。20kg近い重量があり、地下から1階に上げるだけでも大仕事である。

 それに、まだ十分動く(恐らく紙送りのセンサーあたりを交換するだけ)のに粗大ゴミに出すのはあまりにも忍びない。地球環境にやさしくない。ウェブで探してみると沢山の廃棄処理業者のサイトが出てきた。送料だけで無料で引き取ってくれるらしい。

 直接持ち込めば梱包もいらないという、ある業者のコピーに惹かれて東村山にあるリサイクルセンターに車で持ち込むことにする。 あと始末に困っていたが助かった。ただ20キロ近い箱を運ぶのは、地下から玄関を出て車に入れるだけで一大事業だった。海外旅行に使ったカートが思わぬところで役に立った。何とか腰を痛めずに車のトランクに入れる。

 自宅から小一時間で現場の処分場に着く。雑木林に囲まれた倉庫のようなところで愛想の良いおねえちゃんが迎えてくれる。あらかじめかけた電話も親切だった。レーザープリンターのほかに、自作のデスクトップPC、長女のこわれたノートパソコン3点も一緒に引き取って貰った。

 すべて無料である。身元を証明するものは不要(無料だからか)で、控えに住所氏名を書くだけである。部品どりが沢山行われることを祈って現場を後にした。合掌。

Nec5750c_2  新しいレーザープリンターは正価が8万近くするが、何故かネットで1万前後で売られているNECの5750Cを選んだ。DTP屋さんが、べた褒めしているサイトが検索上位にランクし、思わずポチッとしてしまった。値段は肩の力の抜けるこれまでの1/3の¥13,500。2日ほどで届いた。

 早速テストする。何の問題もなく動いた。前のコニカミノルタに較べると少し大きいが静かだし、早い。画質は確かに良くなった。文字も綺麗だ。もっとも、この間には10年近い年月が流れている。これぐらいの進歩は当たり前なのだろう。

久しぶりの家族旅行。世界遺産の白川郷へ(9/27/2015)
03p9257251_2

 次も、電子工作ではない話である。長女夫婦が岐阜に転勤になったので、家族と一緒に車で岐阜に遊びに行った。暫くぶりの長距離ドライブである。また第二東名を飛ばす。かなりの雨だったが、第二東名の路面からは全く水しぶきがあがらない。高速走行での雨は路面に溜まった水がハイドロプレーニング現象などを起こすので神経を遣うのだが、その心配もなく実に快適だった。

 岐阜に着いて少し早めの夕食の後、長女たちの案内で鵜飼を初めて鑑賞した。鵜匠たちが宮内庁職員だったとはこれまで知らなかった。格調が高いのである。ただ鵜飼そのものは、雨で川が増水して流れが速かったせいか、あっという間に通り過ぎ、ちょっと物足らなかった。

02p9277313_3 04p9277312_2

 鵜飼の写真を載せたが、すべて手ブレとピンボケでまともな写真にはならない。そりゃそうだ。動く舟の上から、篝火だけの光源では無理だ。ストロボもよほど強力でなければ効かない(恐らく禁止しているだろう)。雰囲気だけでも感じていただきたい。

 次の日は明治村を何十年ぶりかで再訪問し、最終日は世界遺産の白川郷まで足を伸ばした。このあたりは、40年近く前に、自動車(オンボロ自家用車)で通ったことがある。もちろん白川郷までは行けず、深い谷筋を延々と辿ってやっとのことで通り抜けた記憶がよみがえる。 01p9277326_2

 しかし、今は岐阜から白川郷まで自動車専用道路だけで行けるのだ。スイスアルプスにあるような山間(やまあい)に雄大な曲線を描くインターチェンジを通り、10キロを越す長大トンネルを抜けて目的地に着く。道路網の進歩には驚くばかりである。まさしく隔世の感である。

 初めて訪れた世界遺産の白川郷は、外人観光客であふれかえっていた。コスモスと稲穂が合掌造りの民家に良く映えていた。紅葉や積雪時も美しいだろう。ただ残念なのは合掌造りの家が着実に減っていることだ。昔の写真と較べると良くわかる。まあ、ここは完全な保護区ではないので無理と言えば無理な話だが。

Tiny85のI2Cがうまく動かない(10/2/2015)
 旅行から帰って、電子工作を再開する。Tiny85への換装は仕様をまとめただけで実際の作業は始めていない。小さなブレッドボードにTiny85を載せてテストボードを追加する。861から85 へのソフトの変更は、クロック変更によるタイマー設定の変更、GPIOピンの再設定ぐらいである。テスト用のUARTは送信部分だけ残し、受信側は省略する。

I2c_85full  大した作業ではない。ほどなく完成して、早速テストに入る。CRクロックなのでUARTの速度を少し落とす(38400 -> 19200)。UARTは無事Welcomeメッセージを出した。しかしI2Cの方は、どうも安定しない。マスター書き込みは何とか動いているが、読み込みが全くだめだ。

 デバッグ用のUARTメッセージだけでは原因がつかめない。得意のロジアナへのプローブは一本たりとも使えない。読み込みのステートマシン部にカウンターを設けて、UARTで動作を確認していくが、いくつもの不審な動きを見せて安定しない。

 まず、マスター受信バッファーとデータ配列の順番がおかしい。データはSR04の距離データを使っているのだが、1バイトずれている(これはいつのまにか直ってしまった)。それに、マスター受信のビットの送り込み回数が本来の24回(3バイト)のはずが、もう1バイト多い32回になっている(あとになってみれば、それは現状を正しく表現していたのだが、このときはわからない)。

 I2Cそのものの波形をロジアナでとってみると奇妙なことばかりだ。想定もしないところにストップコンディションが発生して通信が中断されているし、データはもともと全く狂っている。しかし化け方に規則性があるのが悔しい。ロジックで間違っていることは明らかだ。

今度も馬鹿馬鹿しいミスで、1週間を無駄にした(10/6/2015)
 ソースを追っかけては、メモ用紙にSCL、SDAのチャートを描き、動作を検証する。しかし間違っているところを見つけられない。第一、861では何の問題なく動いていたのだ(クロックは1/2になっているが)。Tiny861からTiny85への移植だけで、こんなにトラブルになる理由がわからない。

 何度か、ステートメントを換えて(SCLクロックを割り込みではなくwaitで待つなど)、動かしてみたが改善されない。クロック遅れで起きるのなら、状態が時々変わりそうなものだが、データの化け方は一定している。これが悔しい。

 いい加減、嫌気がさして(大きな目標があるわけでもない)、そろそろTiny85でスレーブを作るをもう止めようと思い始めた。それでも最後に、プログラムの動きを探るプローブ点を一つだけ作って、動きを確認し、それでもだめなら潔くTiny85を諦めることにする。

 マスター読み込みルーチンの動きだけでも調べれば何かがわかるだろう。テスト用にSR04のトリガーピンを使っても当面問題はなさそうだ(ユニットが勝手に動くだけ)。というので最後の手段、トリガーピンのGPIOにデバッグ用のプローブステートメントを当て、テストしてみた。

I2c_85lowintpt  これが大当たりだったのである。ロジアナの画面には目を疑う波形が現れた。何ということだ。最初のSCLの立下りのあと、複数の割り込みが入っている波形がでてきたのだ。何だ、何だ、これは何だ。ロジアナに記録されないSCLの動きがあるのか。暫く考えて、いや違う、もっととんでもないことに気が付いた。

 なに、SCLの割り込み設定をやっているか?あ、あ、あっ、861から移植するとき、UARTの受信ピンに合わせて削除したままなのではないか(861の外部割込み設定は共通)。その通りだった。外部割込み設定を未定義のビット0、0「Low割り込み」のまま動かしている。

 それにしてもなぜこれに気が付かなかったのだろう。マスター書き込みは、1バイトだけで間隔が狭いので、「Low割り込み」でも問題なく動いたのだ。一方、マスター読み込みは、多バイトで、マスターは1バイトづつ関数で送るので、バイトとバイトの間に少し間が開く。で、ここで複数回の割り込みが起きてトラブルになっていた。受信回数が想定より多いのは、このせいだったのである。あああ、もう少し深く考えれば、この状況を解明できたかもしれない。

 外部割込みの設定を(0,0)ではなく立下りの(1.0)にして、Tiny85は何ごともなかったようにI2Cのマスター読み込みを実現した。何度やってもエラーは全く起きない。タイムアウトもない。ああ、良かった。あきらめずに頑張って本当に良かった。このまま挫折していたら電子工作そのものの熱も冷めるところだった。

Pa097340  やれやれ、今度のドタバタ劇も、幕を開ければ、実にくだらないミスだった。しかし、こういう解決は、変な話だが妙にすがすがしい。これまでの暗雲が、すっかり晴れて、人生が明るくなる。これまで暗かった周りの世界が一変し、ものみなすべてが自分に対して好意を持ってくれるかのような変化だ。これだから電子工作はやめられない。

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

2015年9月14日 (月)

Tiny861のGPIOによるソフトI2Cスレーブソースの公開

 久しぶりにプログラミングに熱中していた。AVRのGPIOだけで動くI2Cスレーブインターフェースのライブラリ開発である。前の記事で、曲りなりにもデータの送受信が出来たことはお伝えしたが、安定して動作するまでには、やはり相当な時間が必要だった。

 ソフトI2Cスレーブを作ろうと思いついたきっかけは、前記事のとおり超音波距離測定ユニットHC-SR04の出力インターフェースをI2Cにするためである。超廉価な中華コピー品のSR04のインターフェースはアナログで、トリガーをかけると、距離に応じた長さのパルスを返してくる。しかも電源が5Vなので、EdisonやRasPiとは相性が余り良くない。P9147220

 で、ミニ基板にDC-DCコンバーターと、I2C変換用の8ピンAVRあたりを載せたブレークアウト基板を作れば面白かろうと始めたのだが、これがえらく難しい。巷(ちまた)にGPIOだけでI2Cのスレーブインターフェースを実現した制作例が極めて少ない理由が良くわかった。

 難しい理由はI2C通信の特徴であるスタート/ストップコンディションの認識である。マスター側は作る方だから楽だが、スレーブ側でこれを検知するのはとても厄介だ。プログラムを割り込み駆動にしなければならないため、よほどCPUクロックを早くしないと、2本(データとクロック)の割り込みをとりこぼしてしまう(あとから来たものが無視されるか遅れで正しい判断ができない)。

 I2Cスレーブと言えば7年前、AVRのTinyシリーズについているハードの通信インターフェースUSI(Universal Serial Interface)を使ってライブラリを作成し公開したことがあるが、USIには、もとからスタート/ストップコンディションを検知する特別なハードがついているのでこの難しさはない。

 今度の最終ターゲットであるTinyの8ピンシリーズには、そもそもUSIがない。出来ないとなると無性に作りたくなる性格で、今度もかなり強引なテクニックを駆使して(前記事参照)、GPIOだけでI2Cのスレーブインターフェースをでっちあげた。

 さらに、一工夫してリピートスタートコンディションも受け取れるようにした。まだテストが十分ではないので、胸を張れる状況ではないが、今のところ問題なく動いている。テストバージョンとしてソースコードをとりあえず公開することにする。

 さて、これがどういう風に出来上がったのか。例によっていつものドタバタ劇をご紹介する。

データが化ける。ロジアナでは正確なのに(8/25/2015)
 テストベンチはブレッドボード上である。Tiny861が2台載っており、一台は超音波距離測定ユニットHC-SR04がつながり、こちらがスレーブである。I2Cインタフェースの相手方の861はマスターで、両方ともテスト用のUARTで実行処理の制御と結果の表示をする。

P9157222  テストは、双方のUARTコンソールにコマンドを入れてはメッセージを確認し、ロジックアナライザーで波形を調べる。そのくりかえしである。前回記事までに、1バイトのマスターからの送信(コマンドのつもり)と、2バイトのスレーブからマスターへのデータ読み込み(データ送出のつもり)は、単独では成功している。

 スレーブ側のソースはライブラリを意識して、I2Cのインターフェースすべてをソースファイルひとつ(i2c_slave.c)とヘッダーファイル(i2c_slave.h)につめこんだ。メインであるi2c_HR04_861.cに組み込んだのは、SR04のドライブ部分だけでI2Cスレーブ機能とはすべて関数経由でやりとりする。データは直接渡さない(外部参照もさせない)。

 I2Cのスレーブ側は、すべて割り込みによって始まる。通信が始まってからは、クロック(SCL)のエッジを追っていけば良いのだが、通信シーケンスの最初を示すスタートコンディションは、SCLがHighのときにデータ(SDA)がHighからLowに下がるという決まりになっている(送受信中はSCLがHighのときにSDAが変化してはいけない)。これが厄介である。

 前の記事にあるように、これをSCLとSDAの双方とも割り込みで受けようとすると、割り込みのオーバーヘッドが大きく、よほどI2Cそのもののクロックを遅くしない限りスタートコンディションを把握できない(I2Cの転送速度は100kbpsが目標)。I2c_writeok

 そこで今回は、最初、SDAの割り込みだけを待ち構え、SDAがHighからLowになったとき、SCLを調べてスタートコンディションを判定し、そのあとすぐSDA側の割り込みを止め、SCLの割り込を有効にして、このあとのデータシーケンスをSCLのエッジで受け取るという裏ワザに近いロジックを考え付いた。これで何とか多バイトの送受信に成功した。

 しかし、最初は良いが暫くするとデータの中味がおかしくなる。それに、マスター書き込みのあとのマスターからのストップコンディションを認知していないので、通信はタイムアウトで終わるしかない。こんな状況ではまだとても実用になるレベルではない。さらなる作りこみが必要である。

 不思議なことに、字化けはロジアナで見る限りマスターは常に正しい値を送っているのに、スレーブが違った文字として受け取っていることである。もっとも、I2Cはピンの入力方向設定(HiZ)とプルアップ抵抗でHigh(1)となり、ピンの出力方向設定でLow(0)になるという微妙な仕掛けで0、1を表現しているので、このロジアナの示すデータが本当にスレーブ側のピンの状態を示しているのかは自信がない。

UARTとかぶっていた。これは解決。次はストップコンディション(8/27/2015)
 何度もテストを繰り返すうち、不具合に種類が2つあることがわかった。ひとつは先のデータ化けだが、もうひとつは通信エラーである。タイムアウトのおかげでプログラムはハングしないで戻るが、通信そのものがおかしくなっている。

 こちらの方は、ロジアナのプローブをスレーブのテスト用UARTの前後に入れてみて原因が判明した。時間的には十分離れていると思っていたUART出力部が、I2Cの最後の方と被っていたのだ。このUARTはソフトUARTで送信のときは割り込みを禁止している。これが割り込みで動くスレーブシーケンスの中に入ると目茶目茶になるのは当たり前のことだ。

 究極の解決ではないが、適当な待ち時間をデバッグ用のUART出力の前に入れて衝突を回避した。これで通信エラーは全くなくなった。データ化けは根が深そうなので、もうひとつの課題、ストップコンディションの認識が出来ないか、ロジアナの波形やウェブの情報を元に頭をひねる。

 現在は、受信も送信も、マスターから送られたストップコンディションを認知せず、通信終了はタイムアウトに頼っている。実用的にはSR04の距離測定の最小間隔は、人間相手なら0.5秒前後、ロボットに使っても0.1秒程度(そもそもSR04の測定時間が30ms近く必要)なので、100ms程度のタイムアウト(テストのため現在は1秒)で問題ないのだが、ライブラリとして公開するためには、何とかストップコンディション認知を実現させたい。

ストップコンディションのキャプチャーに成功(8/28/2015)

 ロジアナの波形を目を皿のようにして分析しているうち、ストップコンディションが出される場所はノーマルなときは必ず決まっていることに気付いた。1ブロックのデータの送受信が終わって、ACK/NACKを採取(または発行)するビットのあと、次の最初のデータ(第一ビット)のSCLパルスの部分しかストップコンディションは発行されない。

 もちろん、本式のハードのI2Cはデータストリームの途中でも、スタート/ストップコンディションを拾えるようになっているのだろうが、ソフトI2Cにここまでを要求するのは酷だろう。ストップコンディションが出てくる場所が限定されているなら実装は可能だ。

 つまり、データをマスターから1ビットづつ受け取るステートマシンのステップで、第一ビットのSCLがHighの段階でデータをとったあと、割り込みを抜けずにSDAの変化をそのままループで調べ続ける。SCLが下がるところまで調べて、割り込みルーチンを抜ける。

 SDAに変化がないときは、ペンディングになっていた立下りの割り込みがすぐここで入って通常通りのデータ処理が続く。SDAが変わっていたら、これがストップコンディションである。処理を中断して通信終了処理をする。I2c_slaveok_2

 うむ、我ながら良くできた。動く予感がする。いそいそとステートマシンのマスターデータ書き込みの部分にコードを加える。たいしたコード量ではない。何度もロジックを確かめて、テストに入る。

 マスター側のPCコンソールからデータを送る。スレーブに送られたデータがPCのスレーブ側のUARTに表示される。 これまでは、このあと必ずタイムアウトのメッセージが出ていたのだが今度はどうだ。おーし、いくら待ってもメッセージは出て来ない。良いぞ。何度も確かめて、タイムアウトしないことを確認する。

 データはまだ化けてしまうが、送信のストップコンディションの認知には成功したようだ。思っていたロジックが絵に描いたようにうまく動いたときは、どんな小さなものでも格別に嬉しいものだ。何度もコマンドを入れては子供のように喜ぶ。

16Mhzにクロックを上げると安定するが、改善せず(8/29/2015)

 字化けの問題である。不思議なことに、マスター読み込み(スレーブ送信)の方はほとんどないのだが、マスター書き込みは正しいのは最初だけで、そのあとは殆ど字が化ける。書き込み宣言のアドレス読み込みはエラーとなったことがないので、おかしいのは、データ書き込みのステートマシンのところであることは明らかだ(ビットハンドリングは全く同じロジックである)。

 ライブラリを意識しているので、I2Cのデータは、すべてバッファーに貯め非同期でメインとやりとりするようになっている。このあたりがあやしい。I2Cの送受信シーケンスのミスというより、バッファーのハンドリングがうまく行っていない可能性が高い。

 ということで、バッファーの中味をダンプするコマンドを追加して、送られたデータの中味を検証した。しかし問題はなかった。多数バイトのバッファーでも正確に、データを入れ込んで最後でまた最初に戻る。データの汚れは、これ以前に起きている。バッファーの中を誰かが汚しているわけでもなさそうだ。

 マスター受信の方はほぼ完全である。NACKがとれないのが問題として残るが、データは問題ない。しかし送信で相変わらずデータが汚れる。ロジアナでは全く問題ないのに何回かやるとデータが化けてくる。化け方が気に入らない。何かビットが増えて行くような感じである。

 そうなると原因は、I2Cのデータを読み込むビットハンドリングに疑いがかかる。前から気になっていたのだが、SCLの割り込みから実際に割り込みルーチンに制御がわたるのは、8Mhzのクロックで早くても5.4μsかかっている。

 I2Cの現在のクロックはおよそ60kbpsで、SCLが0の区間は、8μs。次のSCLの立ち上がりに近くちょっと不安である。もしかすると、次のSCLクロックにはいってしまってエラーになっている可能性がある。

 というので、意を決して、スレーブのCPUクロックを上げることにした。8Mhzから倍の16Mhzにしてみる。ロジアナで見ると、割り込みのオーバーヘッドは、半分の2.7μsまで下がり、波形がずいぶんすっきりした。ack/nackの判定ビットの処理も余裕である。しかし事態は改善しない。マスター受信は問題ないが、マスター書き込みはゴミが出る。頭が痛い。

最後はやっぱりドジなミス。I2Cスレーブとりあえず完成(8/31/2015)
 この1週間頭を悩ませていた不具合は、解決してみたらどうしてこれまで気が付かなかったのだろうという、またもお馬鹿な不具合だった。同じような文章をこれで何度書いたことか。

 ここに書くのもお恥ずかしい、単なるバッファーのクリア忘れである。データはビット単位に送られてくるので、1ビット単位のORで受ける。1バイト受ければ、バッファーの次のバイトに移る。これを使い増ししたら、次の回からは、前のデータにORがかかってデータは化けるというわけである。

 ははは、情けなくて笑うしかない。タイミングとデータライン(SDA)のHiZ化、ACK/NACKのときのSDAの値など微妙なところを探し回っていたが、問題は全く別の基本的なところだった。クロックなど上げなくても良かったのだ。

 変数の初期化忘れなど初心者がやるミスである。バッファー経由なので、ビットを受けるところは毎回新しいデータで始めているとばかり思っていた。ソースコードをよく見れば、ORを受けるところがバッファーの配列であることにすぐ気が付くはずなのに、思い込みと言うのは恐ろしい。

 送信がうまく行くように見えたときは、同じデータを送っていたからである。ああ、何というお粗末。これを直して、データの汚れは全くなくなった。やっと一歩前進である。肩の荷が下りた。あとは、マスター受信をタイムアウトでなく、まともなストップコンディションで、通信を終了することだ。

遂に送受信ともOK。GPIOによるAVRのスレーブインターフェース完成(9/1/2015)
  やった、やりました。久しぶりの勝利の美酒。マスター読み込みが最後までトラブっていたが、本日、遂に、タイムアウトを起こさず、一連のデータ送信(スレーブから)が問題なく終了した。I2c_readok

 マスター読み込みは、通信の終わりにマスターからNACKビットが来るのでストップコンディションを調べる必要もない(マスターは送っているが)はずなのだが、このNACKを認めず、常にタイムアウトになっていた。

 送信のエラーがとれて余裕が出来たので、ロジアナのプローブをさらに追加し後処理のプロセスに入れ、受信のシーケンスを仔細に追った。その結果、意外なところが原因であることが分かった。いやいやロジアナさまさまである。

 実は、NACKを認めていなかったのではなく、プログラムはNACKを見てとっくに通信を終了させていたのだが、次のストップコンディションの発行をスタートコンディションと勘違いして、この通信のタイムアウトが発生していた。これがタイムアウトの正体だった。

 間違っていたのは、スレーブ側ではなく、何と送り側(マスター)のストップコンディション発行の仕方だった。ストップコンディションの前に準備するSDAとSCLの変化のタイミングがロジアナを見ると少し短すぎる。このためSDAの変化の把握が割り込みで遅れ、SCLがHighになったところで認識されるのでスタートコンディションになってしまっていたのだ。

 うーむ、これは現在のロジックでは解決できない。暫く、頭を抱えていたが、SCLの変化を少し遅らせればこれは回避できることに気が付いた。 マスターでのロジックにwaitを加え試してみる。めでたくスレーブ受信のタイムアウトはなくなった。

 あわてて、おおもとのNXP社の正式仕様を調べる。P48に、スタート/ストップコンディションのSDAとSCLの変化は半クロック(100kbpsで4μs)空けることというスペックを見つけた。良かった。マスターの修正はスペック通りだった。いやあ気分が良い。

 だいぶ、I2Cに自信がついてきた。特に、最初良くわからなかった、データラインのChaNさんの方式(入力方向にしてラインHigh、出力方向にしてLow)が完全に理解できたのは大きい。I2Cの基本の部分である、プルアップされたライン上で複数のディバイスの間で通信するテクニックである(ワイヤードORというのだそうだ)。

 これまでは見よう見まねでI2Cマスターなどを書いていたが、こんな複雑な(面白い)しかけがあったということがわかっただけでも(いまさらながら)、こういう自作ならではの収穫である。Arduinoなどのラッパー製品を使っているだけではまず出来ない経験だろうと胸を張る(単なる負け惜しみに近いが)。

 お約束のソースコードの公開は整理してからと考えたが、少し気が変わった。このテストステートメントてんこ盛りの形のままの方が、かえって参考になるような気もする。何に苦労したかが一目瞭然で情報量は多い。整形した完成品のソースより参考になると思う。

最後のシーケンスの連続化でまたてこずる。しかし遂に完成(9/5/2015)
 とはいうものの、もう少し動かして動作を確認しておいた方が良いだろう。当初予定したSR04とI2Cの送受信の組み合わせも動かしておきたい。これが動けば大威張りだ。自信を持ってソース公開に踏み切れる。

 マスター側からコマンドを送って、SR04の測定をスタートさせ、得られたデータを送り返させるシーケンスである。これが当初の目的である。I2Cを使ったSR04の制御の第一歩だ。ところが、これがまた難航したのである。 I2cuartng

 送信、受信とも個別では全く問題なく動作する。ロジアナで見ても、綺麗な波形が想定通りに出ている。今度は、これの組み合わせだが、やることは同じだ。簡単に動くだろう。マスター側のプログラムに手を入れて、通信シーケンスを出すコマンドを作って動かした。

 これがまた全く動かない。やれやれどこが悪いのか。ロジアナで波形を見る。ありゃりゃあ、書き込みが終わった後の読み込みのシーケンスがでたらめである。そもそも最初のスタートコンディションを全く拾っていない。これは何か別のスレーブでの動作が邪魔していることは明らかである。すぐ原因に思い当った。最大の容疑者はUARTだ。ここのUARTはソフトUARTなので文字送信中は割り込みを禁止している。

I2cuartok  ロジアナに、送信関数の割り込み禁止部分にGPIOピンをあてて、波形をとってみたら一目瞭然だった。考えてみたら至極当然のことなのだが、マスター側で待ちを予想してwaitをとっていたのだが圧倒的に少なすぎた。今度もロジアナのお世話に大変なった。いやあ、こいつは無敵だ。

リピートスタートコンディションの認知も出来た(9/12/2015)
 最後に残ったリピートスタートコンディションの実装である。EEPROMのI2Cのように、コマンドを送ってストップコンディションを発行せず、再びスタートコンディション(リピートスタートコンディション)を出して、データ読み込みに切替え、1シーケンスでデータを受け取る機能である。

 今度のSR04のシーケンスでは使いにくい(測定に要する時間が長すぎて1シーケンスにしにくい)が、内部のディバイスの状況を伝えるときには便利で実装しておきたい。それに、ストップコンディションを実装しているとき、ここに少し手を加えれば、リピートスタートコンディションもすぐ作れそうな感触だった。

 久しぶりの仕事があって電子工作に手が出ない日が続いていたが、一段落したので早速、リピートスタートコンディションの実装にとりかかる。かねて考えていた通り、マスター送信のストップコンディション検知部にコードを追加する。if文にelseを加えるだけである。

 ほどなく出来上がった。こいつはテストが厄介で、送り側のプログラムにも手を入れる必要があるが、乗りかかった船である。黙々とこちらも準備する。マスター書き込み宣言で1バイト送った後、連続してスタートコンディションを発行し、マスター読み込みのシーケンスを送り込むコマンドである。

 スレーブ側バッファーに残っているSR04の距離データを呼び出すコマンドである。スレーブ側は、多重処理になるのでスレーブ側のテスト用のUART出力は厳禁だ。慎重にwaitステートメントを入れてUARTをずらす(これがないとやっぱり不安だ)。

 案の定、頻々とエラーが起きる。うぬー、この _delay_us()のマクロは、ある程度以上の待ちになるとおかしくなって、ちゃんと遅れてくれないようだ。ウェブを見るがどうも要領を得ない。_delay_msなどに切り替えて凌ぐ。I2crepeatok

 ロジアナで波形を見ながら徐々にデータを正確にしていく。最後に残ったのが、リピートスタートをしたシーケンスのあとに、必ずマスター書き込みデータが化ける不具合だった。リピートスタートは、データの第一ビットを読んだあと初期化されるので、バッファーにデータが残る可能性があるのだが、それがどうして汚れるのか理屈がつかない(必ずというのが気に入らない)。

 こうなったら対症療法になるけれど、シーケンスに入る前に必ずバッファーをクリアしてから始めることにした。よーし、直った。これで想定した機能はすべて揃ったことになる(マスター読み込みのあとのリピートスタートコンディションと、ストップコンディションは未実装だが)。I2cslave_861 完成まで1ヶ月を要したが、GPIOだけによるI2Cスレーブインターフェースが完成した。ベータバージョンだけれど、とりあえずソースコードを公開することにする。回路図も掲載した。スレーブの861の空いているI/Oピンは、殆どがロジアナのプローブに使われている。

以下にスレーブ側のソース一式(プロジェクト名がSR04でなくHR04になっています。プロジェクト名を変える方法がわからないのでそのまま。ご了承ください)と、マスター側のプロジェクトをAtmelStudioのフォルダーの形でかためたものを置きます。ソースコードにはあえてロジアナのプローブステップを沢山残しています。ご参考まで

「I2C_HR04_861.zip」をダウンロード

「I2C_861.zip」をダウンロード


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

より以前の記事一覧

その他のカテゴリー

ARM | AVR | EAGLE | Edison | ESP32 | esp8266 | FPGA | FreeRTOS | Node | Processing | Raspberry | STM8S | Xbee | 電子工作