PICでGPS関連小物を作る

Initial 02-Oct-2000
Last update 10-Oct-2000


始めに

PICと言うMicrochip社製の1チップマイクロコントローラがあります。非力でハードウェアの制約が厳しく、ソフト屋の観点から見ると汚いというより理不尽に近い命令体系でなんでこんなもの(失礼!)に人気があるのか不思議で仕方が無かったのですが、ある日、西の方から4800->9600シリアルレートコンバータを至急作って欲しいと言われたときにH8では鶏に牛刀だなぁということでPICで書いて見ました。

 さらに「低価格化のために内蔵RC発振でできないか」という無理難題が降って来てこんな非力なCPUでは不可能と答えたのですが、ふっと、出来るかもしれないと思ったのが運の尽きで数十時間を注ぎ込み一時はやっぱり駄目という結論に傾きかけて初の見込み違いになるかと思ったのですがなんとか出来てしまいました。

 と、理不尽と思われた命令体系と制約もそれを元にハードウェアを推定すれば何が出来ないか分かるのでそれほど困らないことが分かり、逆にパズルのルールのような面白くするための制約に見えてきました。ちなみに知り合いのハード屋さんがPICの命令体系から内部を推定して同等動作のハードウェアを作るというのを新人の課題に出したら面白いかもと言ってました。きっとびっくりするくらい簡単..CPUというより時計に近いのではないかとも。

 パズルとしてはなかなのめり込めたPICのプログラミングですがさすがにすぐに食傷気味になってしまい、この後はKodak DC290で撮影方向を移し込むためにDinsmore 1490センサを使った方位をRS232Cで出力する小物用のコードを書いただけでほっぽらかしになっていました。

 H8に比べて低価格、パッケージが小さいというメリットも似たような大きさ、価格ではるかにまともなAVRが出回った今、考慮に値しないし実を言うと二度とPICを使うことは無いと思っていたのですがある日、老舗のコンパイラ屋さんHI-TECH Softwareが16F84限定のPIC-C Liteをフリーで公開したのを見かけたのがきっかけでもう一度はまってしまいました。

 そもそもスタックもないようなCには到底向いていないアーキテクチャ、1K wordのROM、68バイトのRAMでは到底、実用にならないと思いながらちょっとコードを書いてコンパイルしてみると案の定、簡単に溢れてしまいました。さもありなんと思いながらサンプルを眺めて見るとほとんどが私が試したコードよりはるかに大規模で、半信半疑でコンパイルしてみるとちゃんと収まる。

これはちょっと悔しいのでいろいろ試しているうちにこれでなんとか実用になるものが書けるのではないかと思っていたところへ、あるところこういうことがあったのをきっかけにNME->IPSコンバータを書いてみました。そのあと、こういうこともあり、結構、使い込んだのでせっかく学んだPIC-C Lite用のテクニックがこのまま消えてしまうのも惜しいということでこのページを書くことにしまた。
これで、二度とこの本質的で無いところに多大な労力を費やされるCPUを使わないように封印してしまおうと思っています。^-^;


[準備編]

以下のファイルを用意します。

1) MPLAB 5.11.02 Microchipから。
(MPL51102.exe 10,448,631バイト)
これ以前のバージョン、5.11.00では.pjtファイルの再読み込みでエラーになります。

2) Freeware PIC-Lite Compiler HI-TECH Softwareから
コンパイラ本体
piclite.exe (1,379,310バイト http://www.htsoft.com/products/piclite/piclite.exe)
マニュアル
picmlite.exe (1,003,519バイト http://www.htsoft.com/products/piclite/picmlite.zip)

製品版のデモ。
demosrc.zip (28,771バイトhttp://www.htsoft.com/products/pic/demosrc.zip
この中のiserial.cを元にgetchar,putcharが作れます。
(割り込みを使わないserial.cで済む場合もあると思います。)

3) MPLAB日本語マニュアル マイクロチップテクノロジージャパンから。
 tut340j.pdf (405,460バイト)

インストール
MPLAB日本語マニュアルに従ってMPLABをインストールし、
「Hi-tech PIC Cによるプロジェクトの作成」の項を参考にPICLをMPLABで使えるようにします。

 これで最新のVC++には及びませんがソースコードデバッグの出来る統合環境が手に入った訳です。

[Writer]

出来上がったプログラムをPICに書き込むにはWriterが必要です。秋月のものがポピュラーだと思いますが、一個や二個のために数千円するWriterを購入するのは割に合いません。あちこちでPCのパラレルポートを使うWriterが公開されているのでサーチエンジンで"PIC"と"Writer"などをキーワードに検索してみてください。16F84(A)に限ればその名も"NOPPP No Parts PIC Programmer"という本当に簡単なWriterも公開されています。


その1 Doubler
摘要 PIC12C509,MPLABアセンブラ
秋月のPIC18ユニバーサルボードに12C509(秋月で1個150円、10個1,200円)を挿して使っています。この写真は変換用に一段ソケットを入れていますが最新の版ではそのまま挿せます。12C509はOne Timeで書き直しはできないので注意してください。
電源の006Pがちょっと無粋ですね。GPSもDC290も3線なので信号線から十分な電力が取れません。コンパクトな5セルのNiMHでもあると良いのですが。
機能 4800bpsで受信したコードを9600bpsで送信する。
特徴 ・外部オシレータなし。内蔵RC発振のみで入力の4800bpsに同期することで精度を維持しています。
・2400しかも受信のみが限界と言われる非力な12C509で4800受信、9600送信をやってのけています。
・ボタンスイッチを押すことで次の行の先頭の一文字を"#"に置き換えます。これにより受信側でボタンが押されたことが分かります。
・入力4800/9600自動切換えを行います。
・一定時間入力が無いとsleepします。入力が入ると自動的に起き上がります。
・入出力独立に極性が設定できます。
用途 NMEAフォーマットは4800bpsと決まっています。9600bpsでないと受信できないKodak Dc290でNMEAのデータが使えます。またIrPhyを使うことでノートPC,PDAに赤外線でデータを送れます。
制約 内部はbit列で動いています。あくまで受信に同期した動作のため勝手に送信することはできません。
改良 Trを使った簡易回路か、シャットダウン機能を持ったRS232Cバッファを使うことで電源SW要らずにする。
相手がPCの時、信号線から電源を取る。
その他 半田鍍金さんがいけない。
ちなみにPIC12C509は電源ピンを合わせると16F84用のソケットに挿して使えます。逆向きになるのがちょっと気になりますが。

その2 Compass
摘要 PIC16F84,MPLABアセンブラ
Dinsmore 1490方位センサ
秋月PIC18ユニバーサルボード+A基板で製作
機能 9600bps $HCHDMセンテンスで方位を送信する
特徴
用途 Kodak DC290で撮影方向を画像に写しこむために作りました。
そのためのScriptはここ
制約 Dinsmore1490センサは分解能45度、つまり8方位です。
改良 DC290で使う場合は一定間隔で出力するのが簡単だったのですがこのセンサは電力を食うので、読み込む時だけ電源を供給するとか、相手からコマンドが来たときだけ起動して結果を送信するとか、液晶表示にしてセンサの値が変わったときだけ起動、それ以外はsleepして節電というのが良さそうです。節電してもLCD表示は変わりません。

その3 xserial.c(cdoubler)
摘要 PIC16F84, Hi-Tech PIC-C Lite
秋月PIC18ユニバーサルボードで作成
機能 割り込み制御シリアル送受信ルーチン
特徴 送信、受信独立に速度を設定できる。
送信、受信とも独立にリングバッファ有り/無しが指定できる
送信ルーチンのみ、受信ルーチンのみの指定可。
受信極性指定可
送信側は正、反転同時出力
シリアルに加えてIrPhy出力指定可、正、反転同時出力
用途 Hi-Tech PIC-C Liteでいろいろ作る為の基本シリアル入出力ルーチンです。
制約 出力シリアル、正/反転/IrPhy正/反転は同一のポートにのみ割り当て可。
ポートの入出力の設定だけは他を設定すれば自動にはなっていない。
改良 思いつきません
関連 短期集中? Hi-techPIC-C Liteを使う[doublerを作ってみる]

その4 C compass
摘要 PIC16F84, Hi-Tech PIC-C Lite,Dinsmore 1490センサ
秋月PIC18ユニバーサルボード+A基板で製作(その2
と同じ)
その他 その2をCで書いただけです。

その5 stf2ips
摘要 PIC16F84, Hi-Tech PIC-C Lite
秋月PIC18ユニバーサルボード+PIC18キャリーボードキットで作成
機能 4800bpsで受信したGarmin STFフォーマットデータをSONY IPSフォーマット(9600bps)で出力する。
LCD表示、IrPhy出力有り。
特徴 Garmin STFの速度ベクタから速度と進行方向を算出します。ちなみに方位を出すためのatan2,速度を求めるためのsqrtどちらもPIC-C Liteのライブラリにありますがどちらかひとつを使っただけでも1Kしかない16F84のメモリが溢れてしまいます。もし組み込めたとしても速度的に厳しく取り落としが心配。そこでかって非力なCPU用に開発され、乗算よりも早くatanが求まるというCORDICアルゴリズムを使って求めています
1.1秒入力が無いと自動的にsleepします。
LCDに緯度/経度/高度/速度を表示します。
IrPhyを用いてケーブルレスでPDA,ノートPCにデータを送信できます。
Diを一個足しだけですがPCとRS232で接続する場合は信号線から電源が取れます。
用途 eTrexなどのNMEAが2秒に一回の機種だと一秒一回のSTFの方がナビゲーションに有利。
Garmin STFは仕様によると測地系の設定にかかわらず常にWGS84でGPSIII+などはその通りなのですがeTrex系は設定した測地系に変わります。さすがに測地系変換を16F84で行うのは無理なので仕様違反の功名というところでしょうか。
制約 STFにはもともと無いので衛星情報はありません。
改良 その1に書いたのと同じく節電。

PCと接続することになるので信号線から電源が取れ(比較的)巨大な電池が不要なので小型化してシェルに組み込むと良さそうですね。
秋月のPIC18ユニバーサルボードもかなり小さいですがフラットパッケージにすればもっと小さくなります。
左はRS232Cバッファ、右は16F84A。いづれも秋月で売っています。なぜかバッファは200円とDIPより安く、かわら版ではDIPより高いことになっているPICのフラット版もDIPと同じ値段です。
その他 LCD表示まで付けたのは宮崎さんがいけない。^-^;
参考 re;PCMCIAタイプのシリアルカード
制約はあるもののGPSはIrPhyで繋いだほうがPDAの専用ケーブルを買うより安くつくという話。
STF->IPSの改造
LCDサポートを加えることになったきっかけの話。

その6 nme2ips
摘要 PIC16F84, Hi-Tech PIC-C Lite、秋月PIC18ユニバーサルボード+キャリーボードで作成
液晶表示の先頭のnが小文字なので測位していないことがわかります。それでもコンパスなので方位情報は取れています。eTrex summitのコンパスの方位が109度、液晶表示が102度なのは磁針偏差(最後に測位した位置で約7度)を補正しているため。
紫のLEDはIrPhy送信用の赤外発光ダイオード。衛星情報がないのでちょっと変ですが時刻、位置は正しく転送されています。Presario213をさらに50cm離しても問題ありません。Presario213で動いているのはPentaさんのIPS Monitorです。

この写真はPCの232Cポートから電源を取って動作中。

Presario213の横に見えているのはKodak DC290の純正シリアルケーブル用コネクタ。

DC290を外部レリーズ有効にしておけばボード上の黄色のボタンでDC290のシャッターが切れます。
ボードを起こしてフラットパッケージで作れば電池とLCDを除いて小指くらいで収まるのですが..
機能 4800bpsで受信したNMEAフォーマットデータをSONY IPSフォーマット(9600bps)で出力する。
4800bpsで受信したデータを9600bpsで出力するDoubler機能も持ち、切り替えて使用できる。
Buttonを押したまま電源を投入するとDoubler/nme2ips機能がトグルで切り替わります。一度切り替えると再度切り替え操作をしない限りそのモードで起動します。
LCD表示、IrPhy出力有り。
特徴 Dinsmore 1490センサがある場合はその出力で$GPRMCの進行方向を置き換える。
eTrex summitのように$HCHDGセンテンスがある場合は$GPRMCの進行方向を$HCHDGの値で置き換える。測位している場合は真方位、していない場合は磁針偏差がわからないので磁方位。
ボタンを押すと直接接続された232Cバッファ経由でDC290のリモートレリーズ端子をonにする。
また先頭の一文字を'$'に置き換える。
$PGRMMセンテンスの測地系を出力に反映します。と言ってもWGS84なら'A',Tokyoなら'B'をフォーマット識別コードとして出すだけで測地系変換をしてくれる訳ではありません。
2.2秒入力が無いと自動的にsleepします。
Diを一個足しただけですがPCとRS232で接続する場合は信号線から電源が取れます。
用途 Kodak DC290とGarmin eTrex summitの組み合わせとこのスクリプトで撮影方向を含むGPSデータが写しこみ、書き込みできます。
ナビゲーション用途にも使えますが、Garmin'Meのようにあらゆるセンテンスからデータを取るようなことをしていないので2秒に一回になってしまうためstf2ipsの方が向いています。なお、eTrex系列は総てのセンテンスからデータを取っても2秒に一回のままです。
制約 メモリが決定的に不足しているので衛星情報は省略されます。
ハードウェアの制約上、LCDとDinsmore 1490センサは同時に使えません。$HCHDGは使えます。
改良 もはやメモリがありません。
LCDと共存しないという条件なら特定機種専用で衛星情報を出すとか、一秒一回にするとかできるかも知れませんが。
節電対策はしたいですね。

その7 予定なので名前はまだない。GPSIFD付き画像作成用データロガーというところ
摘要 PIC16F84,Hi-Tech PIC-C Lite
秋月PIC計測アダプタキット+χ?
機能 ボタンを押した時点での時刻と位置情報をEEPROMに書き込み、同時にデジタルカメラのシャッターを切る。
対応できるのはDC20とDC290..他は持ってないし、シャッターの切り方もしくは切ったことを知る方法がわからない。
特徴
用途 一般のデジタルカメラでもこれを使えば後でexififdを用いることで位置情報付きexifが得られる。
制約
改良

その8 予定なので名前はまだない。徒歩用差分形式ロガーというところ
摘要 PIC16F84,Hi-Tech PIC-C Lite
秋月PIC計測アダプタキット
機能 緯度/経度/高度(?)を差分形式にして1データ3バイト程度で収める。256Kbit(32KByte)で5-6時間は行くか?
予備のEEPROMを用意すれば..^-^;
特徴
用途
制約
改良

[ダウンロード]

PIC-GPS関連ソースコード/バイナリ picgdgt1.zip 45K
回路図 T.B.D
部品表 T.B.D
PCBパターン D.T.K.N (誰か 作って くれないか なぁ。)
#ちなみにT.B.Dは「とっても ぼく できない」の略という説有り。


[MPLAB使い方編]

プロジェクトの作り方

ピンアサインを変えたい、設定を変えてアセンブルしたい、ちょっと改造/修正したいときに。

Projectメニュー -> new projectを選択
  ディレクトリとファイル名を入力して"OK"。
  Edit Projectダイアログ
  Language Tool Suiteプルダウンメニュー
   HI-TECHを選択。警告が出た時は気にせずOK。
    Project Filesから.hexを選択。
      Node Propertiesボタンを押す。
        Generate Debug Infをon。値は"MPLAB"。
        Local OptimizationsをOn。
        Global OptimizationsをOn。
    Include Search PathをOn。DATAは"..\xserial"。
        Map fileをOn。
        Assembler List FileをOn。
   Add Nodeボタンを押す。
    ソースコードを選択してOK。
    Project Filesから.hexを選択。
  Build Nodeボタンを押す。
  正常にコンパイルが終了したらOKしてEdit Projectダイアログを閉じる。


MPLAB Tips MPLABの変数ダンプ、コードなどの各Windowはシンボルを使うモードに切り替えられます。デフォルトでそうしておいてくれると良いのに。
各ピンに信号を与えるにはクロックと各ピンの状態を記述した.stiファイルで行います。
結果はトレースバッファをファイルに書き出して用意しておいた後処理プログラムにかけると楽です。

[PIC-C Lite使い方編]


[他でも応用が利くtips]
局所変数を使う
変数の初期化はコードで行う。(一般的)
ライブラリは使わない(一般的)
定数計算、特にx10などは加算とシフトで行い乗算を使わない。実は上記のどのひとつを取っても乗除算ライブラリを呼んでいません。

[他に応用の利かないtips]
型を見直す。signedよりunsignedの方が小さい。(PICの制約)
サブルーチンはなるべく使わない(PICの制約)
サブルーチンの引数は少なければ少ないほど良い。見易さと反するがすべてグローバルにして一切、受け渡さない方が良い。(PICの制約)
bit型を活用する。制約もあるので注意。(PICの制約
スイッチ文は避ける。(PICの制約)
while( ) { }ではなくなるべくdo { } while( )を使う。(PICの制約)
文字列リテラル、定数テーブルをなるべく使わない。EEPROMから読み出すか出来れば1バイトに収める。(PICの制約)
複雑な式は分かち書きする。(コンパイラの制約。普通はある程度まとめた方が最適化が利きやすい)
自動的な型変換に注意。 word += charはword+wordになる。キャストすればword+charになってコードが縮む。



To be continue -> AVR or Tiny H8 or H8/3048F



[Return to home]|[GPSとH8(電子工作)の掲示板]