« 熱電対によるヒーター制御:比例(P)制御だけで十分か | トップページ | Atmel純正プログラマーDragonで書き損じたCPUチップを救う »

2011年12月 8日 (木)

熱電対によるヒーター制御:まずまずのPID制御。ソースの公開

小学校のクラス会(11/26/2011)
 所長は関西出身で大学卒業まで京都で過ごした。高校や大学時代の友人は東京に結構たくさん出ていて東京での同窓会も多い。最近は共にリタイアした同級生と頻繁に交流して、今や生活の一部となっている。しかし小学校の同窓生は地元に残った人が多いので同窓会は地元で開かれ、滅多に顔を出したことがない。

 高校の同級生で同じ小学校のクラス生から、前から「たまには出なさいよ」と強い要請があり、今回、場所が大津の石山寺と珍しいところだったので、それこそ50年ぶりくらいの感じで出席した。

S_pb264419

 石山寺は、琵琶湖の水が京都・大阪に流れ出す風光明媚なところで、会場はその石山寺の近くの料理屋(昔は川魚料理店だったのだろう)であった。石山寺は紫式部が源氏物語を書いた所ということでも有名である。

 50人のクラスで集まったのが15人。男は4人だけで女が11人。やはり女が元気である。久しぶりの同窓会は、いわば自分探しの場でもある。自分の知らなかった(忘れていた)一面を教えられ、人生観が変わる。今回もいくつかの収穫を得て新幹線の日帰りで京都から帰ってきた。最初は泊まるつもりだったが、京都は紅葉シーズンの最盛期で宿が全くとれなかったのである。

S_pb264433

 帰ってから、熱電対を使ったヒーターの温度制御のためのPID制御をあらためてお勉強する。現在、P(比例)制御まで動いている。対象は自作のアクリル曲げ器である。比例制御だけで一応の制御ができて(前記事参照)、アクリルを曲げるくらいならこれで十分なのだが、「凝り性」の性格で、やりだすと止まらない。それにPID制御は、中断しているライントレーサーなどのロボット制御には必須の技術なので、何とか自分のものにしておきたい。

 温度制御を実際に動かしたあと、前に読んだ全く同じ資料を読み返してみると、不思議なことに何故か新しい発見が増える。面白いものである。視点が変わっているからだろう。見晴らしが良くなって制御技術全体の理解が深まったように思う。

具体的な方法がわからなくて落ち込む(11/27/2011)
 とはいえPID制御の具体的な手順はまだ良くわからない。I制御もD制御も時間成分をどの範囲でどれだけとりいれるのか、その目安を書いている所がないのだ。それにこのところ仕事と行事が重なって電子工作にかけられる時間がなかなかとれない。

 そのうち気の滅入ることが続いて、制作意欲ががた落ちした。まず、エアコンのリモコンの液晶部分が壊れた(尖ったものでぶつけたらしい)ので代替品を買おうとした。ウェブで調べたところ純正品は¥5000以上するが、多種類エアコン対応を謳う互換リモコンの方がはるかに安い(1/3)のでアマゾンで取り寄せてみた。ところが、どのコード(うちの三菱だけでも10種類以上)でも動かず、一気に落ち込む。安物買いの銭失いを絵に描いたような話である(これはこのあと別の部屋のエアコンに使えて無駄にならなかった。やれやれ)。

 続いて、帯状疱疹(ヘルペス)という病気にかかる。顔に水疱のような吹き出物が出来て、最初、うるしにかぶれたのだろうと放置していたら段々広がり、医者に行くと「これは立派な帯状疱疹です」と宣言された。全く痛みはない。帯状疱疹は痛いと聞いていたので最初は半信半疑だったが、薬を飲んだらすぐ良くなったので医者の見立ては正確だったようだ。

Amalia

 結構、怖い病気らしいが痛くないので深刻感がない。しかし、顔が張れているので、気持ちが集中しない。しかも、そのころ知人がスペインで買ってきたという「Amalia Rodrigues」のCDを借りて何気なく聞き出すと、このポルトガルのシャンソンと言われるファド(Fado)の世界がとまらなくなった。暗い情念の溢れ出るCDを聴き続け、余計何もする気がなくなった。ということで、電子工作の進展は完全に止まってしまった。

自己流のPID制御を試みるがいまいち(12/2/2011)
 欝(うつ)には必ず終わりがある。Fadoを聞き続ける事でどん底まで落ち込み、かえって回復が早まったようだ。再び意欲が回復し、気がつけば、PCの前で温度制御のロジックをいじっていた。ハードは殆ど完成しており、やることはもう殆どない。2つのケースをアクリル曲げ器の台板に固定するだけだ。残る作業はもっぱら制御ロジックを作るソフト開発となる。

 1秒ごとのメッセージをUARTに出して、温度制御のプログラムテストを繰り返す。ウェブのPID制御のページを片っ端から拾い上げて参考になりそうなところを探す。殆どのページは基本の話の繰り返しばかりで、肝心の実践的なことが載っているページはほとんどない。後閑さんのPICのページはさすがで、少し参考になる式が載っている。

 微分積分と言っても、どうも多数のポイントをとっているのではなく、前回データの差分を見ているだけのようだ。微分の方がわかりやすいので、まず、こちらからやる。しかし、文献での説明と、自分の感覚がどうもずれているような気がする。

 こちらは急激なオーバーシュートを避けたいので、目標温度に突っ込んでくるような温度上昇を緩和させるのに微分係数を使いたいが、どうも逆の説明である。同じようなことを疑問に思っているページも見つけた。

 それと実際の係数をどう決めるかは何も書いていない。積分制御は比例制御との区別が良くわからない。目標温度との温度差が大きい時に積分制御を適用すると、ヒーターの加熱の効果が、かなりあとから出てくるので、猛烈なオーバーシュートになってしまう。これも適用する範囲を限定しないとおかしくなる。

S_pc084447

いまいちよくわからないが、自己流のPID制御ロジックを次のように決めた。

・まず比例制御帯を目標温度の1/2からとする。全体にすると、目標温度付近の勾配が少なくなりすぎ、効果が遅れて出てハンチング(値の振動)が大きくなるのを避けるためである。

・比例制御帯に入ったら、常に前の温度と比較し(1秒ごと)、一定の温度以上の上昇があるときは、ヒーターの制御定数を1/2にする(当面固定)。これが(d)制御にあたる部分である。

・目標温度の90%以内に現在温度がなったら、(I)制御帯に入り、1秒ごとに目標温度との偏差(オフセット)を積み上げる。制御定数はすぐに反映せず、次の手順でまとめる(温度変化が遅れることを考慮)。

・5秒ごとに、足し上げたオフセットの温度値の平均をとり、そのときの温度に応じた制御定数に一定の倍率をかけて、100段階の制御定数に足し込む(200℃なら1℃あたり2が基礎数)。

・温度が目標温度を上回ったら、途中まで積み上げていたオフセットはすべてクリアする。

・微分制御のもうひとつ、温度が目標温度以上になったあと、下がってきた時は、(d)制御として、そのときの比例で決まったヒーターの制御定数を2倍にして、現在温度が目標より高くてもヒーターを加熱し必要以上の温度低下を事前に食い止める。

 しかし、色々工夫しては見たが結果は比例制御とあまり大差がない。パラメーターを変えてみても(2倍を1.5倍とか)グラフなどで余り顕著な効果は出てこない。オフセットの解消については、(I)制御が非常に効果があったが、相変わらず目標温度を上下するハンチングをとめることはできない。

 ヒーターが点いてから、温度に反映されるまでの時間が長すぎて、PID制御が効かないのである。ウェブ情報にも、遅れ時間の大きい制御はPIDでは難しいという記事がある。

もういちど最初からPID制御(12/4/2011)
 やっぱり我流は先が見えない。それにパラメーターの調整がしにくい。もういちど制御ロジックを最初から作りなおすことにする。パラメーターで制御できるようにするため、変数をunsignedから符号付きのsignedにかえ、マイナスを導入して制御定数を計算しなおすことにする。

 勉強をもういちどやりなおす。伝達関数とPID制御の関係もやっと理解出来てきた。PID制御の伝達関数はちゃんと存在するのだ。PIDが理論以前の実践的手法から始まったことが良くわかった。

 ソースコードを大幅に見直すことにした。本格的なPID制御にするため、各種定数を#defineであらためて定義し、忠実に式をたててプログラムを作り直す。1以下の定数は、10倍(1から10)で定義しあとで10で割る。これで小数点の操作が整数データで出来るようになる。

 これまで符号無し変数とifでやりくりしてきた演算を、マイナスを含んだ符号付き変数にしたので、計算が面倒になったが、楽になったところもある。温度がオーバーシュートしたあと、目標温度の下に突っ込む時のヒーターの加熱指示が計算式だけで出来るようになった。

 あわせて、このあいだの空焚き警告のエラーメッセージが出るようにコードも追加した。汎用性を持たせるため固定数値は持たないようにしようとしたが、これは無理だった。高温の時は、いくらヒーターが連続で加熱されていても温度変化しないのですぐエラーになってしまう。

 結局、「計測温度が35℃以下で、長時間(当面20 秒)ヒーターが点きっ放しになっても温度変化が2℃以内」という固定条件で、ヒーターをただちに止めるロジックになった。解除は、リセットか、ロータリーエンコーダーの回転で戻る。

PID制御はパラメーターの調整がポイント(12/7/2011)
 この3日間、PIDのパラメーターをあれこれいじって、ヒーターの熱制御をスムーズにしようと頑張ったが、結局、目の覚めるような改善は出来なかった。しかし、まあ、こんなものかという程度までは制御が出来るようになった。グラフがその苦労のあとである。

Pid

 比例制御に較べれば、圧倒的にオーバーシュートは少なくなり、このパラメーターで280℃くらいまでオフセットは補正される。思い切って比例制御の比率を減らし、微分と積分制御の成分を大きくしたのが効果があったようだ。アクリル曲げ器は、内部230℃でアルミパイプ表面がアクリルを曲げる最適温度150℃程度になるので、これで十分である。ハンチングは残るが比例制御より心持ち少なくなっている。

 弁解になるが、こういう時間遅れの大きい制御は、本当に難しい。試しに、このあいだ作った調光器(無段階調整可能)で人間の手で所定の温度に止める制御をやってみた。放置しておけばこの前の記事のようにどこかで一定の温度に落ち着くが、決められた温度を手動で一定に保つことは実は極めて難しい。

 温度が下がってきたとき、ボリュームを上げて温度低下を防ごうとする。ところが温度は急には上がらない。暫くしてから徐々に温度は上がりだし、このとき慌ててボリュームを下げても、温度はどんどん上がっていく。

 結果として目標温度を大幅に上回ってしまう。さっきボリュームを下げたので、再び温度は低下しはじめる。しかし低下に気がついてボリュームを上げてももう遅い。少々ボリュームを上げても温度はいつまでも下がって目標温度をあっさり割り込んでしまう。そして、これの繰り返しになる。

 人間の手ではとても一定には出来ない。負け惜しみになるが、このマイコンの制御などうまくやっているほうだと思う。あまり自信はないが、ここまでの成果のソースコードを公開することにする。ハードはこの前と全く換えていないので回路図は前記事を参照していただきたい。

 まだ改善すべきところは多々あると思うが、あまりこればっかりにこだわっているわけにもいかない(面白いけれど)。このプロジェクトもこのあたりで一段落つけることにする。

 以下に例によってAVRStudioのプロジェクトフォルダーの形で、PID制御のソースコードを置きます。 フォルダー名が替っているだけでソースファイル名は同じなので注意してください。修正したコードはコメントの形で残っています。参考になれば幸いです。

「ThrmCpl861_1208_11.zip」をダウンロード

|

« 熱電対によるヒーター制御:比例(P)制御だけで十分か | トップページ | Atmel純正プログラマーDragonで書き損じたCPUチップを救う »

AVR」カテゴリの記事

電子工作」カテゴリの記事

コメント

ばんとさん、いらっしゃい。

>元々はkumanさんところで話題にしたものが

あ、あ、申し訳ない。アクリル曲げ器の最初の記事には、ばんとさんの名が入っている(FreeRTOSでバッファー付きUARTを動かす 11/06/18)のですが、最近のは省略していましたね。失礼しました。

2ミリ厚のアクリル板もきれいに曲げられるので、やる気さえあれば、ケースぐらい作れそうですが、他の事が忙しくてなかなかそこまで手が廻りません。

秋月の調光器キットは私も使っています。これで十分なのですが、根が凝り性なもので。

過分なお褒めをいただき恐縮です。自分では「波乱万丈」にするつもりは全くないのですが、結果として、どうもそうなるようで、まあ、みなさんが楽しんでもらえば苦労した甲斐があるというものです。

投稿: がた老 | 2012年2月29日 (水) 01時36分

ばんとです。

すんさんの掲示板ではお世話になりました。
明日には届くとは思うのですが、秋月からはまだロ
ジアナは届いてません。

がた老さんも、似たようなアクリル板曲げ器を造っ
てるなぁと読み進めてると、元々はkumanさんとこ
ろで話題にしたものが始まりですか。
ボクのはヒータ制御部は秋月のトライアック万能調
光器キットで作った簡単な代物てす。別物ですね。
すごいですね。

がた老さんの工作記、波乱万丈で読み応え満点です。
がた老さんのレベルに比べればボクはまだまだです
が、それでも小さな波乱万丈はあり、読んでて納得
なところばかりでした。

ところで、がた老さんの作られたATTiny2313の
UART2313のライブラリィ愛用させて貰ってます。
最初はがた老さんのライブラリィでテストした後、
書き換えようと思ったのですが、シンブルで完成度
が高いので、使い続けてます。

これからもよろしく、お願いいたします。

投稿: ばんと | 2012年2月28日 (火) 20時15分

Sam.Yさん、詳しい解説ありがとうございます。

熱容量の大きい機器の温度制御は、大きな船の接岸と考えれば良いわけですね。参考になりました。

サンプリングが1秒ごとで、温度があまり正確(ときどき値が飛ぶ)に
計れていないので余計難しくなっているようです。

熱電対計測専用のIC(MAX6675)を入手したので、いずれまたやります(今は一段落)。ありがとうございました。

投稿: がた老 | 2011年12月15日 (木) 12時27分

こんにちは いつも楽しく拝見させて頂いています。

積分制御を作るのは Iだけ単独だと 比較的楽で、
偏差に係数を掛けたものを 現在の制御値に足すだけで実現できます。
これは 考えてみればあたりまえなんですが、I単独制御だと 現在の制御値は 過去の制御値の和になっているからです。
人間の制御も 積分制御に近いものがあって 車のハンドルにしろ 水道の蛇口にしろ 足りないなって 思ったら ハンドルなら 切り足すし 蛇口なら もう少し開けるようにしますよね。

P.I制御の場合は 制御値をP制御(偏差に比例)と I制御(偏差の積分値に比例)の和にしますから 現在の制御値は 過去の偏差積分値に 一回前のタイミングの比例値を足したものになっていますので 新しい制御値は
現在の制御値 - 前回の比例制御値 + 今回の積分制御値 + 今回の比例制御値
としても 求められますが、どちらかと言えば 積分用の変数を持ったほうが楽だと思います。(たしか 値が飽和した時に面倒だった覚えがありますので)

P.I.Dの調整面倒ですよね。
私も 自己流ですが こんな風にやっています。
制御対象が 制御量に対して 即時に応答するとき -> 積分制御 (モーターのスピード制御とか)
制御対象が 制御量に対して積分的(一次遅れ的)に応答するとき -> 比例制御 (温度制御はほぼこれ)
制御量に対して2回積分的に応答するとき -> 微分制御

実際には 完全に即時応答だったり 積分だったりしないので 適当に Mixします。

感覚的には でっかい船を考えて これの加速度を制御するなら アクセル ( って言うのですかね? ) を 積分制御。
速度を制御するなら 比例制御。 ( 水の抵抗を考えなければ 目標速度に達したら アクセル開度 0で巡航できます )
位置を制御--船着場に接岸とか するならば 微分制御。 ( 目標位置到達前に前に必ず逆転が必要です )
といった感じです。 参考になりますでしょうか。

投稿: Sam.Y | 2011年12月14日 (水) 23時48分

shuji009さん、お久しぶりです。

エアコンの赤外線データは数十ビットあって解析が
大変なようです。

リモコンはその後、オリジナルが発見され(壊れたのは
別のエアコン用だった)、開発の必然性がなくなりました。
やってみたかったんですけれどね。

投稿: がた老 | 2011年12月12日 (月) 14時00分

石山寺・・・最近では昨年の秋に行ってきました。
昔は、会社の保養所があり良く利用していました(遠い目)。

ところで、赤外線リモコンですが、うちの三菱のエアコン
のものは、コードはAV機器に比べて、長かったのですが
AEHAのフォーマットなので、作るのは一応可能かな?って
思いましたが~~~ものがエアコンだけに、安全面も考え
ないと駄目ですし、表示は独自なので、難しいと思います
けど(汗;)。

投稿: shuji009 | 2011年12月12日 (月) 10時05分

そら。さん、いつもコメントありがとうございます。
情報ありがとうございました。見せていただきました。

ちゃんと日本語のコメントまでついているのですね。すばらしい。同じようなことをしていて少し安心しました。

投稿: がた老 | 2011年12月 9日 (金) 12時05分

こんにちは。

使った事は無いのですが、
http://www.avr.jp/user/an.htm
こちらのAVR221(離散PID(比例/積分/微分)制御器)は見ましたか?
サンプルソースもありますよ。

PID制御って考え方はなんとなく分かりますが、自分が制御したい対象にプログラミングするとなると、分からないです。

投稿: そら。 | 2011年12月 9日 (金) 06時56分

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1089557/43307687

この記事へのトラックバック一覧です: 熱電対によるヒーター制御:まずまずのPID制御。ソースの公開:

« 熱電対によるヒーター制御:比例(P)制御だけで十分か | トップページ | Atmel純正プログラマーDragonで書き損じたCPUチップを救う »