この取組みでは、実験的なこと、かつ、金をかけないという課題もあり、制御用のCPUは、PIC16F1823という14ピンのDIP-ICを利用している。秋月電子でばら売りでも¥90で手に入るので使いやすい。安くても、内部クロック32MHz動作ができて、10ビットのAD変換は8チャンネル、パワコンやモータを制御するためのPWMまで持つ、機能的に盛りだくさんの優れもの。
私がマイコンをいじり始めた30年前にはとても考えられない。しかも、2年ほど前まではフリーの開発環境ではアセンブラしか使えなかったのが、C言語開発環境が開放され、デバッガを含めた開発環境まで無償で提供されている。至れりつくせり。
今回のチップは、AD変換の終了フラグが立たない時があるというバグ付ではあるが、ソフト的な解決法は確立されている方法で回避できた。盛りだくさんの機能をわずか14本の足で、外部とやりとりしなければならず、個々の機能は、特定の足に割当てられており、回路の最適化が設計者の腕の見せ所。
プログラムが機能拡充し、完成度が上がってきたが、高機能なMPPTや、定期的なキャリブレーション機能も盛り込みたい。しかし、そのためにはメモリ不足になってしまう。
これまでは、90%位で収っていたが、電圧測定の移動平均、MPPT機能、定期的なキャリブレーションと贅沢に機能を盛込んだところ、わずか2Kのメモリ空間はあふれてしまった。
アセンブラで書き直せば入るかもしれないが、Z80等と違いRISC系チップは命令が少なく書くのに手間がかかる。Cになじんだ身には辛い。
Cのプログラムをスリム化し、命令とメモリ消費量の関係を確認しながら、メモリ消費圧縮を進めることにした。
液晶ディスプレイ表示にC言語標準のprintf関数を使っている。「%04d」とフォーマットを指定すると簡単に表示形式を設定できる。しかし、こいつがくせ者。%sで文字列表示すると、メモリを大量消費する現象を発見。即座に却下。文字列は固定文字列のみを表示するように変更。
それでもメモリが足りない。20%ほど消費するprintf自体を泣く泣くあきらめる。数字を文字列に表示させるstdlib.hのitoa関数を利用してみたが、これもメモリ消費が多く却下。結局、自作に。
桁数を狙い撃ちしてやれば難しくないし、左をスペースパディングすれば、表示位置も揃う。試行錯誤し、シンプルになったのが、こちら。最初は、10進数表示を試したが、除算がメモリを20%以上消費する。10進除算の自作も考えたがメモリ消費は抑えられないと思い、16進表示で我慢することに。その結果、完成したのが、以下のプログラム。
// 左スペースパディング付き整数→文字列(16進4桁)変換
// 除算(/1000,/100など)はメモリを20%以上消費するため使えずシフト演算にした
// 呼び出し側で必要な桁数を得る場合は、(buf+1)などでアクセスすればよい
void utoa_zero_padding(unsigned short int num, unsigned char keta, unsigned char* buf){
*(buf+(keta–))=’