見出し画像

(5) M5Stick C Plusとペルチェ素子で恒温水槽を作る - 温度制御プログラム

はじめに

さて、(4)までで、水温の計測とペルチェ素子の制御ができるようになりました。水温の計測結果に応じてペルチェ素子の加熱面、冷却面をコントロールすれば、水冷ブロックを通じて水温の制御ができるはずです。

水中ポンプと、ペルチェ冷却ファンは常時稼働にしてあります。

フィードバック制御

このような「水温の計測結果」に応じて「ペルチェ素子の加熱面、冷却面をコントロール」するような制御方式をフィードバック制御といいます。制御方式には、フィードフォワード制御というものもありますが、これは、水温の制御でいえば、「これからの水温の変化予測」からあらかじめ「ペルチェ素子の加熱面、冷却面をコントロール」するような制御になります。

実際の高度な制御の場面では両方行われることが多いですが、素人がやるには、フィードフォワード制御はちょっと難しいので、やるなら、フィードバック制御だけ、かなぁ、というところです。

フィードバック制御の欠点としては、「水温に変化が表れてから」後追いでの制御になるので、後手に回りがち(一定の水温の維持が難しい)であるということです。

フィードフォワード制御は、その点、水温が変化する前に、様々な要因での「これからの水温の変化予測」から、その水温変化を抑えるように制御をすることになるので、うまくいけばフィードバック制御よりも、一定の水温を維持しやすくできます。(予測を失敗すると悲惨ですが)

ただ、フィードフォワード制御を行うには、その「様々な要因」をあらかじめ検知するような機構や高度な予測が必要になってくるので、素人ではちょっと難しいと思います。

まぁ、このへんは、「フィードバック制御」とかで検索かければいろいろなサイトがひっかかります。

水温を維持するプログラムをどうするか

一番最初に思いついたのは、設定温度を設定したら、その温度より水温が高かったら冷却、水温が低かったら加温するというプログラムです。

テストプログラム1

ただ、このプログラムでは、ペルチェ素子が常時通電状態になるうえ、設定温度付近では冷却と加温の切り替えが頻繁に起きます。
電気代がかかるのと、素子に負荷がかかり続けるのが気になります。

プログラム1の動作

設定温度に幅をもたせたらどうでしょう。
つまり、動作のトリガーを設定温度よりちょっと高いと冷却、ちょっと低いと加温ということにするわけです。設定温度間は停止という扱いにすれば、停止期間ができて、常時通電にはならないのでは?

テストプログラム2

結果的には思うようにいきません。

例えば、20℃設定で、温度幅を±1℃とすると、21℃を超えると冷却し初めます。ここまでは予想された動作なのですが、21℃を切ると冷却が止まります。本当は、冷却状態に入ったら、そのまま冷却状態を維持して19℃まで下がってほしいのに、です。この動作をするときは夏場であり、冷却が止まると水温は上昇し始め、21℃を超えるようになります。つまり、止まったらすぐに21℃を超え、冷却が始まるのです。ということは、結局、設定温度が1℃高くなっただけ、です。そして、

プログラム2の動作(夏場、加温は自然上昇)

冬場はこの逆が起こります。19℃を下回ると加温が始まるわけですが、すぐに19度を上回るので、加温が停止します。加温が停止すると、冬場は水温が下降し始めるので、すぐ19℃を下回るようになり、また加温が始まります。

プログラム2の動作(冬場、冷却は自然冷却)

つまり、夏場は21℃近辺でONOFFを頻繁に繰り返し、冬場は19℃近辺でONOFFを繰り返すことになります。温度幅を設定しても、その温度幅の中で動作することはありません。夏場と冬場の設定温度に幅ができただけです。

単純な水温による条件制御だけでは難しいようです。

プログラミングの醍醐味

プログラミングで難しいところは、こういった部分であり、また、解決策はないか、思案を巡らせる面白いところでもあります。

理想的な動作としては、夏場は、21℃を上回ったら冷却し初め、19℃で停止、あとは自然に水温の上昇を待ち、また21℃を上回ったら冷却、のような動作です。プログラムの工夫によって、このような動作を実現したいわけです。

理想的な動作(夏場、加温は自然上昇)

また、冬場は19℃を下回ったら加温、21℃を超えたら停止、水温の低下を待ち、19℃を下回ったら加温、とするのが理想です。

理想的な動作(冬場、冷却は自然冷却)

こうすれば、ペルチェ素子が通電しているのは加温や冷却時のみで、あとは自然な加温や冷却なので、電気を使用しません。

なぜ、このような動作にならないのか、という理由の一つに、うまく動かない方のプログラムは、「水温をもとに単純に動作を決めている」ということと、「夏場と冬場では、停止時の自然な水温の変化が(夏場は上昇、冬場は下降というように)違う」ということが挙げられます。

で、結局どうすればよいのか

この解決の一つには、

  • 動作を、直接温度を条件として切り替えるのではなく、動作状態を参照し、動作状態を変更することで、動作させる

  • 温度は、動作状態の遷移の条件にする

  • 夏場モードと冬場モードを用意して、それぞれで、違うプログラムにする

という方法があります(別の方法もあるでしょう)。
どうせ、夏場と冬場(ペルチェOFF時の水温が上昇するか下降するか)は頻繁に変わるものでもないのだから、年2回くらいのモード切替は許容する、という考え方です。

夏場(冷房)モードなら冷房、冬場(暖房)モードなら暖房を動作させる
(Settingモードは今回の動作とは直接関係ありません)
温度条件によって動作状態を変化させる。冷房と暖房で動作条件が違う。
(状態変化関数の中の「一つ前の状態」は別の動作のために使用しているので、
今回の動作とは関係ありません。また、このプログラムの動作幅は±0.5℃です。)

また、動作状態を変数として用意し、「cooling」「heating」「stop」の3つの状態を遷移することにします。冷房として働くときは、現在温度が設定温度+温度幅より大きかったら「cooling」に、現在温度が設定温度-温度幅より小さかったら「stop」の動作状態に移行するように設定してあります。
動作時は、温度を直接みて動作するのではなく、この動作状態を見て動作します。ポイントは、動作状態の遷移は、温度が一定条件を満たしたときに行われる、というところです。
先ほどの例でいうと、19~21℃の間は、状態の遷移条件がなく、遷移が行われないので、21℃から下がるときは「cooling」状態のままですし、19℃から上がるときは「stop」状態のままです。(以下に、図で動作を説明してあります)

これで、21℃より大きかったらcooling状態に移行、冷却して19℃まで下げ、19℃を下回ったらstop状態に移行、停止、その後は自然な温度上昇に任せ、また21℃より大きかったら冷却する、ようなことができます。
水温は直接動作条件に使用するのではなく、動作状態の判断に間接的に使用するようにすることで、21℃でONOFFを繰り返す動作をしなくなる、ということです。

夏場の動作
(動作モードという言葉を使用していますが、夏場モードと冬場モードと紛らわしいので、
動作状態と読み替えてください。)

暖房も、この逆を行えば実現できます。

冬場の動作

この方法の課題

現在は、ひとまずこの方法を取っています。

ただ、季節の変わり目ではどっちのモードにすればよいのかがわかりませんし、間の季節で、今日は暑いから夏場モード、でも昨日は寒が戻って冬場モードだった、みたいなことが起こるかもしれません。
まぁ、そもそも季節の変わり目では、もしかしたら、温度管理は必要ないかもしれませんが、昼間と夜間でモードを変える必要が出てくる、みたいなことは起こる可能性がありそうです。

この方法でのもう一つの課題は、夏場モードと冬場モードを結局人間が判断する必要があることです。あんまりスマートではないような気もします。
夏場モードと冬場モードを停止時の温度変化から自動決定するようにすればいけるかもしれません。

フィードバック制御そのものの課題

もう一つは、フィードバック制御そのものの課題です。これは、原理的に起こる問題なので、回避はできません。(緩和はできるでしょうが)
フィードバック制御は後追いでの制御という話はしました。
例えば、水温が低いから、加温するような制御をした場合、その影響が出て、水温が既定値を上回ったら制御を停止するわけですが、加温する制御を停止したあと、実際に水温に影響が出るまでの時間に差がある場合があります。つまり、制御を停止したあとも、少し、更に水温が上がる、ということが起こります。
これをオーバーシュート(もしくはアンダーシュートの場合もある)といい、計測してから制御をする、というフィードバック制御の性質上、仕方ないわけですが、オーバーシュートをどこまで許容するか、という課題もあったりします。
オーバーシュートを考慮して、設定温度の少し手前で加温を止める、という選択肢もなくはないです。今回は、そこは誤差の範囲として考慮に入れていませんが、制御の種類によっては、オーバーシュートが問題となってくる場合もあるかもしれません。

この記事が気に入ったらサポートをしてみませんか?