PIC18Fを使うというタイトルで4回にわたって実験結果を紹介してきました。
実は、実験といっても、一応、温室の換気扇のコントローラを作るという目標を持っていた訳です。
その為には、まず温度を計測しなければなりません。
そこで、温度を計ってコントローラとして出力を制御出来るようにします。
今回、A/D変換を使用し、A/D変換の開始をソフトウエアで呼んでいます。
ところが、CCP割り込みでハード的にA/D変換が開始されている事がわかりました。
今回、のプログラムで動作に関する支障はありませんので、ソースはそのままにしておきます。
詳細は[PIC18Fを使う(2)]に補足しておきました。
安価で直線性が良いといったらダイオードが思い浮かびます。
ただし、素子や動作点により、値がばらつくので、校正作業が必要になってきます。
最近は、IC温度センサーが進歩していますが、アマチュアには入手が大変です。
また、3線のトランジスタ型が多く、そのままセンサーとして使うには、形状に、やや難があります。
そこで、計測用サーミスタを使うことにします。
計測用サーミスタはセンサーとして使い易く封止されたものがあり、2線式です。
大きなメリットは、温度に対する抵抗値の誤差が1%以内ですので、校正作業を省いても、そこそこの精度で温度計測が
可能だという事です。
ただし、値段はIC温度センサーなどより高くなると思います。
2種類のサーミスタのうち、下側が今回使用した103ATです。
綺麗にモールドしてあるので、センサーとして、そのまま使えそうです。
時定数が75秒と大きいのですが、温度計測には問題無いと思います。
上側の小さなサーミスタは103ETです。
小型で応答性が良いのが特徴ですが、小さすぎて扱いにくいです。
また、熱放散定数が小さいので、自己発熱が問題になりそうです。
温度と抵抗値の関係は103ATと似ていて、25℃では両方とも10KΩです。
左がA/D変換器の入力部の接続部です。
10KΩの直列抵抗1個でリニアライズしています。
この10KΩという値は測定温度範囲と使用するサーミスタの温度−抵抗値の関係から計算する式が存在します。
実際、計算してみると10KΩに近い値になります。
計算値と全く同じ値にする必要は無いですが、近い程、直線性が良くなります。
サーミスタの抵抗が25℃で10KΩですので、25℃中心に温度を計るという程度に考えれば良いと思います。
ただ、抵抗の値は計算に使うので、実際の値と合致している必要があります。
A/D変換器の入力にはリーク電流があるので、本当はバッファアンプを間に入れれば良いのかもしれませんが
簡単にするため、直接、接続しています。
サーミスタの温度−抵抗値の関係はリニアでは無いので、抵抗1本で直線近似するわけですが、温度範囲を広く取りすぎ
ない事がポイントです。
経験的に、温度範囲を50℃以内にすれば±1℃以内の精度で温度を測れると理解しています。
今回は−5℃〜45℃の50℃の範囲で直線化してみました
具体的にはエクセルの関数から直線の傾きと切片を求めています。
データを表示する。
この表ではX軸に計測電圧を取り、Y軸に10倍の温度値(0.1℃単位の整数)を取っています。
結局、
温度=807−221×計測電圧 と近似しました。
A/D変換は10mS間隔で32回行い、これを加算して平均を取っています。
温度=807−221×5×(32回のA/Dの合計値)÷1024÷32となります。
実際の計算は
温度=807−((1105×(32回のA/Dの合計値))>>15)
上記の式で行っています。
計算は4バイト長の整数演算ですが、負担の大きい割り算はシフト演算に置き換えました。
温度を求める計算で500uS近くかかっています。(/8MHz)
A/D変換のリファレンス電圧は5Vですので、電源電圧を正確に5Vに合わせる必要があります。
総合的に±1℃以内で計れると思います。
左が今回のプロジェクトの内容です。
adconv.cが追加されました。
led.cが無くなり、output.cが追加されました。
num_set.cはオンとオフの差温(ヒステリシス)も設定出来るように変更されました。
その他、若干、修正されたファイルがあります。
ファームウエアのダウンロード (ZIP圧縮されています。)
コンパイラのバージョンにより、プロジェクトに若干の変更が必要になります。
これらは前回と変わっていません。
A/D変換の部分が書かれています。
A/D変換に関しては多分、組み込み関数があると思いますが、使い方を憶えるより、レジスタ操作をした方が
早いと思い、レジスタ操作にしています。
使い方は難しくないですが、アクイジョンタイムやA/Dクロックの設定を間違えると不安定な動作となって
悩むことになります。
10mS毎に32回、値を加算し、平均を取っています。
具体的な計算は前述「具体的なA/D変換」の項目を参照してください。
320mSに1回、温度値を更新しています。
設定値入力中でも、A/D変換は常に10mSに1回、行われています。
スタックオーバーフローのチェックを入れたこと、ウオッチドッグタイマの周期を変更した程度です。
今回からウオッチドッグタイマーを使用したのですが、コンフィギュレーションではディセーブルにし、
プログラムでオンしています。
余裕?で起動メッセージを入れました。
2行目は意味の無いメッセージですが、私のホームページのアドレスの一部です。
メインルーチンの最初の方でウオッチドッグタイマーをオンしています。
ウオッチドッグタイマーはソフトウエアでオンオフ出来ますが、この場合はコンフィギュレーションの設定を
ディセーブルにしておかなければなりません。
ウオッチドッグを入れるとデバッガが使えなくなるので、デバッグ終了後にプログラマとして書き込みます。
時間設定は30秒程度で、強制的に動作させて結果を確認しています。
ウオッチドッグのクリアはアセンブラの命令で、Cからは操作できませんが、組み込み関数が用意されています。
メインルーチンの全体的な流れは変わっていませんが、ポーリングする項目でA/Dと出力制御が追加になり、
LEDが無くなりました。
数値入力する項目が「設定値」と「ヒステリシス」の2種類になりました。
ヒステリシスとはオンとオフの温度差の意味で、例えば25℃でオンした場合、ヒステリシスを1℃に設定すると
24℃未満でオフします。
あとから考えると「ヒステリシス」より「オフセット」にしたほうが判りやすかったかもしれません。
私の場合、コンパレータで使う「ヒステリシス」に馴染みが深く、「オフセット」というと、寸法差をイメージ
してしまいます。
いずれにせよ、出力のハンチングを防ぐ為に入れます。
設定値は10℃から40℃まで、1℃単位で設定出来ます。
ヒステリシスは0.1℃から5.0℃まで0.1℃単位で設定出来ます。
温度表示画面でMODEキーを長押しすると設定値入力画面になります。
温度表示画面でENTキーを長押しするとヒステリシス入力画面になります。
これらの入力画面ではUPキー、DOWNキーで数値を増減します。
押し続けると数値をスキャンし、長押しで増速します。
数値設定後、ENTキーを長押しすると数値を書き換え、同時にEEPROMも書き直し、温度表示画面に
戻ります。
MODEキーを押すと処理を放棄して温度表示画面に戻ります。
編集中の数値も放棄され、以前の値に戻ります。
数値入力画面を1分間、放置すると、温度表示画面に戻ります。
EEPROMに書き込まれた値は電源投入時にバッファに読み込まれ、もし範囲外であったら初期値に書き直されます。
初期値は設定値が25℃、ヒステリシス値が1.0℃としてあります。
ここでは、通常の温度表示画面と出力を1秒に1回、更新します。
数値入力中は温度表示画面は出せませんが、出力はバックグラウンドで1秒に1回、通常通り更新されています。
温度表示画面は1行目が現在の温度、2行目が入力済みの設定値です。
温度表示画面ではヒステリシス値は表示されていませんので、確認したい場合は仮にヒステリシス入力画面を出し、
何もしないで抜けます。
出力は2点有り、1点は制御出力で、1点はLED表示に使います。
2点の動作は、現在は全く同じですが、例えばLEDのみ点滅するようなことも出来ます。
処理が増えているので、変数や関数のプロトタイプ宣言が増えています。
使用するタイマーも増えているのでタイマー番号の定義も増えています。
今回、使用したメモリの量です。
これは、最後にデバッガーを外した状態の数値で、デバッガーを使えば、もう少し増えると思います。
現在のところ、C18評価用バージョンは、まだ最適化が効く状態ですので、60日過ぎたら、もう少し増えている
かもしれません。
どれくらいの数値になるか興味があります。
PIC18F1320は256バイトのRAMを持っていますが、C18でスタティック変数として使えるのは僅かです。
デホルトのデータセグメントはバンク0の後半128バイトに有ります。
このうち半分をソフトウエアスタックが使用し、引数等は、ここに確保されます。
ICD2をデバッガーとして使えば、さらに10バイト程、使用します。
実験では、結局48バイトしかスタティック変数は確保出来ませんでした。
今回、ソフトウエアタイマーを8個、確保しましたが(内6個使用)1個につき4バイトのバッファを使用します。
ここで32バイト使えば全体ではメモリオーバーになってしまいます。
そこで、この32バイトはバンク0の前半(アクセスバンク)に確保しています。
手順は
・データセグメントをアクセスバンクに変更する。
・near属性で変数を確保する。
・データセグメントをデホルトに戻す。
以上です。
尚、アクセスバンクは標準関数が演算バッファとして使用しているようですので、全部使える訳ではありません。
ここら辺はコンパイル後のマップファイルを覗けば、何となく想像できます。
RAMが足りないときはアクセスバンクに確保すれば良いという手は書籍等で説明されていた訳ではなく、思いつきで
やったことですので、何か問題があるかもしれませんが、コンパイラやリンカでワーニングも出ないし、動作も問題無い
ようです。
追補) 60日経過後、再コンパイルしたところ、メモリ使用量は全く同じでした。
後は、速度に対する最適化ですが、古いHexファイルを消去してしまった為、Hexレベルの比較が出来ません。
メモリ使用量が変わっていないので、こちらも変化していないような気がするのですが、どうでしょうか?
電源投入直後にスタートメッセージを表示しようとしたのですが、最初、表示が出なくて悩みました。
液晶表示ルーチンは既に実績があり、問題無いはずです。
いろいろ試しているうちに、液晶の初期化直後は表示が出ない事が判りました。
結局、数十mSのディレー時間を入れることで表示が出るようになりました。
初期化後だけの話ですので、実用上はこれで全く問題ありませんが、原因は判っていません。
本来、こういう物なのか、不良品なのか、使い方に問題があるのか・・・・・
支障が無いので、そのままになっています。
今回、書籍付録のCDに収録されていたMPLAB V7.60を使いました。
いろいろ機能が増え、一般のCPUの開発環境に近くなりました。
エディタも日本語のコメントが入れられるようになり、強調表示等で、かなり美しくなっています。
ただ、日本語のコメントを使うと、強調表示が乱れる場合があります。
また、他のエディタで作成したソースを取り込むとタブの位置が時々ずれます。(タブ数の設定は同じですが)
若干、気になりますが動作上は問題ありません。
それ程複雑な内容ではありませんが、全てが18PINのIC1個に収まってしまうのは感激です。
クロック用の水晶さえ付いていません。
消費電流は5mA程度ですが、出力がオンするとフォトカプラとLEDを駆動するため15mA程度になります。
ちょっと前は、この程度の制御も大変でした。
例えば、8085、8255,8253、ROM、RAM(設定値を保存するためバックアップ)、外付けA/D、
サンプルホールド、液晶表示器が無いので表示はLED、1A程度の電源となります。
そこそこの大きさのCPUボードになってしまいます。
Cコンパイラも無く、ソフトの作成もデバッグも大変でした。
良い時代になりました。
MPLABIDE、C18、ICD2、PIC18F、いずれも、今回、初めて使うので、最初は戸惑いましたが、
慣れれば快適です。
PIC18F1320は18PINで400円(秋月)と結構、高価ですが、16Fシリーズより強力で使い易いです。
参考書は相変わらず16Fシリーズをアセンブラで説明したものが多いですが、18Fシリーズの方が説明し易いと
思われます。
もっとも、アセンブラならR8C/M16あたりの方が、ずっと素直で判りやすいと思いますが。
C18コンパイラは普通に考えて普通に使える普通のコンパイラといった感じです。
CCSCコンパイラは深く考えないで簡単に組み込み関数を使うといった感じのコンパイラでした。
PIC18Fを使うという題名で換気扇コントローラに挑戦してきましたが、今回で終了します。
基本的な動作は確認しましたが、まだバグが残っている可能性はあります。
電源部、出力でリレーかSSRを駆動する部分、ケースの加工、まだ作業は残っています。
最終的に完成させるかは、未定です。
今回、「動作中に設定値が入力可能」とい条件で製作した為、結構、複雑なソフトになりました。
オフラインで設定値を入力して良いなら、もう少し簡単になります。
2009年10月10日 追記
私が使用した環境はMPLAB Ver7.60 C18 Ver3.11(評価版)です。
新しいC18 Ver3.31ではリンク時にエラーが発生しました。
電子回路 > PIC18Fを使う > C18のバージョン を読んでください。