SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|

2005-04-03(Sun) わーい、プロッタがプロッた!!

  がばっ!! と、起き抜けに工作開始である。実は夢の中である事実に気づいてしまったのだ。コレはもしかすると祝氏からのお告げだったのであろうか? それは「PICのクロックの精度は大丈夫なのかいな?」というコトである。

  オイラは新たにPICで開発を始める際、手始めにてきとーなポートを利用してLEDをチカチカさせるコードを動かすトコロから始める。その中でチカチカする間隔を作り出すのが、オイラがPICでプログラムを始めた頃にあみだした「秘伝の0.1秒×n-αループルーチン」だ。このルーチンは実に簡単にキリのいい時間を作り出すスグれモノなのであるが、今回nに10を指定して1秒間隔でチカチカしたにもかかわらず、微妙に速かった……いや、微妙でなく明らかに速かったのを思い出したのだ。デジタル時計の秒きざみとLEDの点滅が、ズンズンとズレていくのである。

  PICにはオシレータ内蔵のタイプが多く存在し、この機能の利用を選択すると外部に水晶を取り付ける必要がなくなる。PICの種類によって選択できるクロック速度は異なるが、今回のPIC16F648Aは4MHzの内蔵オシレータ搭載だ。これを使うと、水晶が取り付けられるハズだった2つのピンはその呪縛から解き放たれ、I/Oポートとして使えるようになるのだ。特別な理由がない限り、これを利用しないテはないのである。

  しかしながら問題もある。内蔵オシレータはいわゆるRC発信回路(抵抗とコンデンサで組まれた発信回路)で構成されており、果てしなく正確な時を刻む水晶に比べて精度がイマイチという特性があるのである。そして、どうやら今回用いるPIC16F648Aはかなり速めの発振を行う個体らしいのである。

  「クロックが速ければ、処理が速くてええやん、ナチュラルオーバークロックやん」と思えばさにあらず。今回はPIC内蔵のシリアル通信(USART)機能を用いるのであるから、ボーレートまで速くなってしまうのは困りモノなのである。マニュアルの推奨設定値によれば「CPU動作クロック4MHzで通信速度9600bpsを望む場合、高速モード(BRGH=1)でSPBRGに25を設定すべし」とあったのだが、そもそも4MHzが正確でないならばこの値も変わってくるのである。あな恐ろしいや。そーいや昨日、PIC→PCへのUSB経由の通信が成功したと書いたものの、思い返せばデータがときどき化けて受信されていたのもコレが原因っぽい。

  理由がわかったトコロで対処である。「秘伝の0.1秒×n-αループルーチン」を利用し、4MHzのCPUがキッカリと10秒間隔でLED点滅を繰り返すコードを書き込み、その時間をストップウォッチで計測、実際のCPUクロックを逆算してしまえばいいのである。

  LEDの消灯→点灯のタイミングは約20秒に1回であるが、ストップウォッチを押すのは人間である。誤差を軽減するために数サイクルを計測するコトにした。結果は以下の通りである。

実測秒数サイクル数理論値で20秒の実測秒数
18.77sx118.77s
56.18sx318.727s
112.39sx618.732s
168.46sx918.718s
281.23sx1518.749s
281.15sx1518.743s

  見事に速い。20秒あたり1.2秒以上速い。この結果を踏まえ、今回使用するPICの実クロックを求め、さらに設定するべきSPBRGを求めよう。


20.00s / 18.74s = 1.0672倍
4MHz * 1.0672倍 = 4.2688MHz
BaudRate = Fosc / (16 * (x + 1))
x = ((Fosc / BaudRate) / 16) - 1
x = 26.79 ≒ 27

  というワケで、SPBRGには推奨値の25ではなく、27を利用しなければならないコトが判明した。ちなみに、PICの仕様書を見ると、電源電圧5Vで通常の温度条件下では誤差は±2%と書いてある。±2%でも上記の校正作業は行うに越したコトはないと思うが、今回の+7%って……このPIC不良なんじゃねーか!?

  で、対策コードを書き込んで動かしてみるが、まだ動かん……いいかげんメゲる寸前である。オシロで出力波形をモニタしながら……って、波形が出てねーじゃん!! そーか、Rubyのputcがバファリングしてしまっているんだ。おーちゃくしないで1バイトずつ出しなさいッ!! 「serial.sync = 1」を指定してどうだッ!!

  画像の説明

  「動いた!!」

  うわー、懐かしいカチャカチャ感だ。このプロッタの動きや音!! かなり面白いのでゼヒこのムービーで体感していただきたい。ちょっと画質が悪いが、その雰囲気は伝わるハズだ。というワケで、これにて「ハ号作戦」の完遂である。今回のI/Fの完成は祝氏からのお告げのおかげである(と信じて疑わない)。命日から一日遅れてしまいはしたが、このI/Fの完成を祝氏に捧げさせていただく。

  画像の説明 画像の説明

  さて、完成したらパッケージングである。バラしは極力避けようと思っていたが、必要に迫られて、すっかりバラすことになってしまった。例の供締め予定箇所に基板をあてがってみたトコロ、意外と余裕がないことが判明したのだ。基板の端は既存のコンデンサと干渉するため、ギジギジとニッパでカジり取ってなんとかなったが、高さ方向はUSBのBコネクタの高さギリギリであり、現在のように基板をピンヘッダで結合する方式では裏ブタが閉まりそうもない感じである。どうやらピンヘッダとPICを直ハンダしないと解決が難しそうだ。

  画像の説明

  で、とりあえずUSBコネクタの外側に当たる部分のケースに穴を空ける。いきなりタコって、すぐ隣に余計な穴を開けてしまったが、その後、正しい場所にキレイに穴を空けることに成功した。なかなかの仕上がりではないだろうか。

  さて、今後の工作の予定であるが、ケース内の実装スペースの問題でピンヘッダとPICを直ハンダしなければならず、その後のPICの書き換えが不可能になるため、まずコードの不具合を全滅する必要がある。それと電源。やはりUSBバスパワーでの動作は期待できそうにないので、これもどーにかする必要がある。これ以上ケースに穴を空けるのは避けたいが……明日は明日の風が吹く。今日はここまで。