PI制御のオーバーシュートは、起動時してから温度が目標値に達してからはじめてファン制御を開始すれば回避できそうです。またゲインKpが大きいと温度入力のノイズをそのまま増幅してしまうのでこれは小さめに変更。
ということで電源ON後から目標値Sv=40℃の間はファンを停止して自然上昇に任せ2-3分後Svに達したところでKp=1,Ki=1,Kd=0のPI制御を開始した時の温度プロファイルはこうなりました
制御開始直後にハンチングを起こしていますがその後は安定します
ここまでPC上のツールでパラメータを制御していましたが、値が決定したのでこれらの作りをすべてPIC側ファームに組み込み自律的に動作できるようにします。といってもWindowsAPLのタイマイベント内でやったものをPICの1秒間隔のタイマ割込みの中へそっくり移植するだけで温度取得、そこから1スロット分のPID計算、制御量決定、PWM出力を一気にやってしまいます
486CPUからのリクエストで現在温度、現在制御量を返すコマレスI/Fは残しておきますが制御パラメータの変更、ファン強制停止のような自爆系コマンドは念のため操作禁止にしてあります。逆にサーミスタの断線検知(測定温度が超低温にみえる)の場合は強制的にファンを100%全開にして異常レスポンスを返すようにしました。
これらをPIC12F1822にインプリメントしてプログラム領域1933word、94%使用。いい感じに収まりました
このうち半分以上の1200wordはAD値-摂氏温度変換テーブル int temp_tbl[]が占めています