周波数カウンターと秋月FGキットの合体
最後のひとふんばり(11/04/08)
ソフトの開発は実装に向けて一段落したけれど、実はまだ心残りなことがある。秋月のファンクションジェネレーター(FG)は、ファンクションという通り、一応、正弦波だけでなく、方形波と三角波をジャンパーピンを切り替えて出すことが出来る。始めはTiny2313でソフト的に切り替え、LCDにその状態が表示されるとスマートだなと思っていたが、メモリはもう2Kぎりぎりまで使ってしまい、とてもその余裕はない。ディップスイッチにして外からいじれるようにしようか。いや正弦波だけであとは変えなくても構わないか。でも折角ある機能だし何とかできないかと色々考えていた。
現在のバイト数は、1926バイト。残り100バイト少々では外部スイッチの実装はとても無理だと考えていたとき、ふと気がついた。周波数を測っているとき、スイッチの割り込みなど入ったら計測は少なくともレシプロカルでは目茶目茶になってしまう。むしろ、このプログラムでは外部割込みは使ってはいけないのだ。あ、そうか。割り込みなんて使う必要はない。レシプロカル方式のように、単純に、ピンの入力を監視しているだけでスイッチの替わりになるではないか。スイッチの反応は遅くなるが(周波数計測の合間だけ反応)、チャタリングを気にする必要もない。
思いついたら、すぐ体が動くタイプである。2日間の研修講師の仕事がいよいよ明日にせまっているのも何のその、ひとつのピンを見ながら2つあるジャンパーピンの設定を順次に実現していくコードを書き始めた。プッシュスイッチを押すたびに、2本の出力ピンの状態がサイクリックに変わっていく。始めは状態遷移図などと大層に考えていたが、書いてみたら、if elseを3個並べるだけでコードは完成した。
コードサイズはぎりぎりの2040バイト。うーむ、LCDに表示するためにはこれではもう無理だな。まあ、とりあえず動くだけ動かしてみよう。考えたロジックが正しいか確認するのは動かすのが一番だ。
と、やっぱりこれが動かない。スイッチを押してテスト用のLEDがつくところまでは良いのだが、想定どおりの動きをしない。LEDはこのあいだ面白半分に買ってみた2色出るLEDだ。千石電商の2Fで¥40で売っていた。2本アノードピンが出ていて赤と緑が点灯できる。あれこれいじる。状況は変わらない。同時につけばオレンジになるはずだが、オレンジどころが赤しかつかない。
もしやと思って、このLEDを単独で点灯させてみる。ひゃー、こいつは一旦赤がつくと、緑をONにしても緑はつかないのだ。緑がついているとき赤をONすると緑が消えて赤になってしまう。オレンジが出るわけがない(このあと共通のカソードに制限抵抗を入れて点けようとしていたことに気づいた。アノード側に抵抗をいれてオレンジが出るのを確認した。LEDさんごめんなさい)。
あわてて、緑用の別のLEDをブレッドボードに追加して実験再開。しかし、緑はついたがやっぱり想定どおりではない。サイクリックにLEDが点灯しない。こんな簡単なロジックでどうして動かないんだろう。何度もコードをチェックする。間違いはない。10ステップかそこらのコードで振り回されている自分に段々腹が立ってくる。そろそろ焼きがまわったか。
ロジアナまで持ち出す。外見は変化がないが、実は瞬間的な動きをしているのかもしれない。しかし、何も問題ない。見えている状況と変わりはない。調べることがなくなって、気分を鎮めるため少し休む。デバッグで頭に血が昇ったらおしまいである。気持ちを落ち着かせて考えてみると、AVRを始めた頃、ピンとポートの違いがわからず大騒ぎしたことを思い出した。今度は大丈夫か。基本に立ち返ってもう一度このあたりから点検することにする。
LED(将来はジャンパーピン)をドライブするピンはDDRで出力方向に指定し、その状態はPINに入力をかけて値を得ている。正しく値を得ているようだ。おや、ピンへの出力をピンに対して行っているぞ(PIN = 1<<PD2)。ふむ、ちょっとおかしいけれどLEDはこれでちゃんと点いている。では、PIN = 0<<PD2はどうだ。ややや、これは0にならない。これはどういうことだ。
要するに、PINに1を書き込むとそのピンは1になるが、0を書き込んでも0にはならない。そもそもPINに出力することに意味がない。PORTに対して書き込まないと状態は変わらない。最初のLED点灯がたまたまPINへの出力で動いたために基本的な間違いに気がつくのが遅れたのだ。
骨身を削ってコードを押し込む(11/06/08)
間違えて設定していたPINをPORTに換えて、めでたくスイッチは想定どおりサイクリックにLEDをドライブするようになった。計測の合間でしかスイッチのPINの状態を見られないので、スイッチを少し長く押しておく必要があるが、まあ、しょっちゅう動かすスイッチではないので問題ないだろう。
問題なのは、LEDでなく最終目的のLCDへの表示である。LCD関数の呼び出しだけで数十バイト、最低3ヶ所必要なので、60バイト以上のメモリのスリム化が必要である。既に削れるところは削ってしまった。もう削るところはない。ダイエットした人間にさらに痩せろと言っているようなものである。
しかし、この作業はなつかしい。昔は、メモリが小さかったので散々この作業をやった記憶がよみがえる。昔を思い出しながらソースコードを調べなおす。調べれば出てくるものである。保守性を上げるため、一旦ワークエリアにデータを揃えてから次のステップに移るところや、LCDの表示の順番、データ初期化の場所を換えてステートメントを減らせるところ、わかりやすく65535を掛け算しているところを16ビットシフトに変えるなど、2バイト、4 バイトと、それこそ爪に火をともすような節約作業を続ける。
カウンターの初期化などは下手に省略すると暴走したりするのでいちいちコンパイルしなおして確認しながらの作業である。4バイトコードの処理はうまくやると大幅なメモリの節約が出来るので苦労の甲斐がある。SRAMを節約できるフラッシュから直接データを取り出す関数は、必ずしもメモリを普通のSRAMにおく関数よりフラッシュを喰うとは限らない。かえって減ったりする。まさしく試行錯誤である。まあ、これはこれなりに面白い。ただしコードは読みにくくなって保守性は間違いなく悪くなるが、これは仕方がない。
数時間の努力の結果、サイズはそれでも100バイト近く縮めることが出来た。やれば出来るものである。これでLCDにも出せそうだ。LCD出力を組み込んでコンパイルしてみた。やったやった。2Kバイトを割る1988バイトだ。動かしてみる。おお、2行目にSIN(正弦)、SQR(方形)、TRI(三角)の波形表示がサイクリックに出た。小数点表示も出せたし、これでソフトの実装は満足できる状況になった。残るはハード工作である。
昨日、研修が早めに終わったので秋葉に寄り、秋月で低電圧版でない20Mhz動作保証の標準電圧版のTiny2313を念のため買い(¥100)、千石でハード実装に欲しかったLCD固定用の長めのスペーサー(25ミリ)を手に入れた。くやしいことに千石で、このあいだ買ったサンハヤトの実装部品取り外しセットが買った値段より¥300 も安く売られているのを見つける(¥4200)。ここはミニルータを郊外のDIY店より安く売っていたりして油断がならない。
帰宅して、ケースの位置あわせをする。このあいだ作った両電源の位置は全く合わず、ちょっとがっかり。もういちど作り直す必要がでてきた。しかし、買ってきたスペーサーはぴったり製図どおり高さが合い、心配した強度も十分だ。これでハード実装の不安材料はなくなった。順調に作業は進んでいる。
ケースの工作と微調整(11/8/08)
この前買ったタカチのケース(YM150)の工作を始めている。これまでのケースはすべてプラスチックで気楽に穴を開けられたが、今度はアルミとは言え、金属製のケースである。ただ、厚さは1ミリなので、今のミニルータで何とかなるだろうと考えている。しかし、これもやってみなければわからない。工作が楽になるように、慎重に手順とレイアウトを考える。
最も厄介なLCDは、基板の上に長めのスペーサーを立て、追加する汎用基板の上で、片側を固定し、残りの側は、スペーサーをLCD側のみ固定して基板の上に置くことにする。片側は秋月のFGキットの基板の上なので下手に穴を開けることが出来ないからである。
このあたりは現物合わせで工作していくしかない。確定しているところから線引きを始める。まず、周波数を切り替えるロータリースイッチとFGキットのコンデンサーピンを可能な限り近づける配置を選ぶ。これで側面パネルとFG基板の位置が決まる。周波数変更用のVR2つと、波形選択のプッシュスイッチをレイアウトし、電源スイッチは側面のパネルにスペースが出来たので当初予定の後面から前に持ってくることにする。
ここらあたりが決まると、あとは現物合わせで工作ができそうである。今日の土曜は雨でテニスが流れたので、お昼すぎから、いよいよアルミ板の工作にとりかかった。ケースは側面にのりしろがついているので、簡単に万力や工作台で固定できない。冶具と呼ぶには大げさすぎるが、かまぼこ板2枚をケースの奥行き分だけの長さに切って、ケースに入れて補強し、ドリルスタンドに立てて固定し、スイッチの穴あけを開始した。
ミニルータでも意外に簡単に穴が開いた。ほっとする。調子に乗って、電源スイッチ用の方形の穴を、ミニルーターのカッターで切ってみた。おお、これは楽だ。最初はドリルの穴を連続してあけてニッパーか何かで切り取る予定だったが、これなら板が歪む心配もなくあけられる。
しかし、このスイッチの穴は折角綺麗に開いたのに、やすりがけのときに誤った方向に削りすぎてしまい(ストッパーの付いているほうを削りすぎ)、しっかり固定できない穴になってしまった。やれやれ、調子に乗るといけない。この前のマイク穴といい、イーサネットマイコンのときの放熱孔といい、調子よくいった後がいつも失敗する。まあ、あとでボンドで固定してしまえば良いのだが。
何とか側面パネルの穴あけが終わったので、仮組み立てをしてみる。いやいや久しぶりのアルミ板工作にしてはうまくいった。残る大物の穴あけ工作は、上蓋のLCDの表示パネルの窓と、BNC出力の穴、DCアダプターの入り口の3つである。こういうのに比べれば、基板の固定穴を開けることや、配線は楽なものである。
ソフトのほうは、1/4のプリスケーラーを常時動かすために、直接計測のインターバルタイマーの修正をする。直接計測が16ビットのカウンター(タイマー1)を使っているので、8ビットタイマーで切りの良い時間を作る必要がある。これまで0.1秒を100回ばかりのオーバーフローで作っていたが、1/4分周で同じ分解能をだすためには0.4秒にしなければならない。フラッシュがもうないので、16ビットの変数は使いたくない。8ビットの変数で、今までのルーチンをさらに4回くりかえすロジックを加える。ついでにもう少し精度を上げることにする。
というのは、Tiny2313のクロック用にこのあいだ秋月で少しまともな20Mhzの水晶発振器(発信子でなくVccで出力される部品)を買ってきて調べてみたら、どうも1Mhzで数百サイクル近く低いことを発見した。誤差にすると数百ppm。オシロの周波数表示は4桁までで、そこまでは合っているが、桁上がりの様子をみていると、この水晶とオシロの方が正しいようだ。
数百ppmの誤差は、クロックに使っている発振子の誤差なのか、ソフトのバグなのか微妙なところだ。ただ、オーバーフロー割込みが0.4秒だと500回近く起きるので、ここでの遅れはばかにならない。タイマーは割込みが起きた後も動いているので、端数を設定するときは、ここでの遅れを勘定に入れておかないと全体が短くなってしまう。とりあえず、この水晶発信器の周波数に合わせることにする。試行錯誤の結果、端数を1つ増やしてループさせ、最後に1tick(3.2μs)加えると、5Mhzでピッタリ10hz内外におさまった。いやあ気分が良い。6桁まで0が並ぶ表示を見て一人ご機嫌になる。
| 固定リンク
「電子工作」カテゴリの記事
- 生存証明2(2022.10.19)
- 生存証明(2022.01.23)
- パソコン連動テーブルタップの修理を諦めて自作(2021.02.16)
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- 研究所活動は停滞したままでCCDカメラ顕微鏡導入など(2019.02.08)
コメント
いつもコメントありがとうございます。データシートをあわてて読み直したら、入出力ポートの最初の説明に、「ピンの交互切り替え」として、しっかり出ていますね。何かに使えそうですが、私には混乱の元でした。とにかく「データシートは穴があくまで読め」という格言が身にしみます。
投稿: がた老 | 2008年11月11日 (火) 11時02分
あまり使用する機会はありませんが、PINに1を書くと
ポートはトグル(反転)動作します。
AT90S2313では無かった機能です。
投稿: kuga | 2008年11月10日 (月) 04時51分