質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1413閲覧

昇圧回路でPID制御

PHENIXa

総合スコア47

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/10/02 12:20

編集2022/11/03 10:13

前提

PID制御の勉強のために昇圧回路で試行中です。
(PID制御を使わないと制御できます)
パラメータの設定などほぼ初心者です。

環境

PC:Mac OS Big Sur
IDE:STM32CubeIDE(v1.7.0)
マイコン:Nucleo-F303K8

実現したいこと(仕様)

  • 起動時間:昇圧開始から1.5秒〜2秒(許容できて5秒)で2段階でも構わないので100Vになるようにしたい(起動からではなく立ち上がり始めてから)
  • スイッチング周波数は100kHz固定(可変はしない)
  • TL431とPC817を使ったフィードバック回路を使用する。
  • duty比のリミット範囲は25%〜75%(25%のままだと1時間経過しても100Vに到達しない)
  • 負荷が変動してから2ms以内に目標電圧に復旧する必要がある。

発生している問題・エラーメッセージ

10/2 時点
1秒以内で立ち上がったり、立ち上がっても軽負荷になると目標電圧がズレる(上がる傾向にある)
Kp=0.1,Ki=0.1,Kp=0.0 だと起動までに時間がかかって(負荷変動すると復旧まで時間がかかる
抵抗負荷(回路図上のRL1)を取りつけた状態で起動し、取り外すと電圧が上昇してしまう(150V程度で維持されている?)

10/10 時点
起動時の電圧が目標電圧の100Vになるようにはなった。(PID設定値にもよりオーバーシュートすることもあるが)
目標値になった時点でRL負荷を外すと電圧が130V程度まで上がってしまう。(元に戻ろうとするが125Vで維持されてしまう。)
そこから再びRLを取り付けるとと93V付近まで低下する(10秒程度は93Vを維持しその後0.5秒程度で100Vに戻る)

該当の回路図

イメージ説明

該当のソースコード

c

1/* USER CODE BEGIN 0 */ 2 3float kp = 0.7f * 1.0f; 4float ki = 0.0f * 1.0f;//立ち上がりが早くなるだけ(0.001~0.1) 5float kd = 2.0f * 1.0f; 6 7/* USER CODE END 0 */ 8 9/* USER CODE BEGIN 4 */ 10 11void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) 12{ 13 //HAL_GPIO_TogglePin (GPIOB, GPIO_PIN_3); 14 15 //処理完了までの時間 16 float us_time = 35.0f; 17 18 const float Target = 256; // 目標値 19 20 float x = 0.00f;//現在値 21 static float P=0.00f , I=0.00f , D=0.00f ; 22 static float Old_P = 0.00f;//1つ前の偏差 23 float u = 0.00f;//操作量 24 25 // 現在値(出力電圧)の取得・数値変換 26 x = HAL_ADC_GetValue(&hadc1); 27 x = (x / 4095.0f) * TIM1->ARR ; 28 29 // 偏差の計算 30 P = Target - x; 31 32 // 積分項の計算 33 I += P * (us_time * 1e-6); 34 35 //微分項の計算 36 D = (P - Old_P) / (us_time * 1e-6) ; 37 38 //偏差の更新 39 Old_P = P ; 40 41 // 操作量の計算(PID 制御) 42 u = kp * P + ki * I + kd * D ; 43 44 45 /* 46 32000kHz/100kHz = 320 47 400 * 0.25 = 80 48 400 * 0.75 = 240 49 */ 50 51 // リミット演算 52 if (u < 80) 53 { 54 u = 80; 55 } 56 if (u > 240) 57 { 58 u = 240; 59 } 60 61/* 62タイマー反映処理 63*/![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-10-26/71e8ff8b-04d3-4b16-b175-00d35ba1e8e2.png) 64} 65 66/* USER CODE END 4 */

※void HAL_ADC_ConvCpltCallbac()は無限ループプログラムだと思ってもらって構いません。
main関数等は省略しています。

該当の波形

起動時の波形(RL接続済)
イメージ説明
抵抗RLを外す
イメージ説明
抵抗RLを再取り付け
イメージ説明

試したこと

限界感度法
試そうとしたが、オーバーシュートするまで確認すると200Vまで上昇して過電圧になり壊れる可能性があるため断念

ランダムに調節
P=1.0 I=0.5 D=0.5を初期値として確認した
【Pだけを上げる】
0.9で目標電圧にはなるが、1.0秒で目標電圧に到達してしまう。それ以下だと立ち上がりが遅く、その逆だと早くなる

【Iだけをあげる】
0.1〜3.0まで確認したが目標電圧が数V上がっただけ(立ち上がりは全く変わらず)

【Dだけをあげる】
Iと同様の動作をした。

IとDを1,5,10,20と変化させたが立ち上がり・目標電圧は変わらず。

試していること

ozwkさんの回答を参考に、起動から1.5〜2秒間はあるPIDパラメータにしその後別のパラメータの2段階のような形式となってしまいますが、その方法で現在試行中です。

フォトカプラ経由のフィードバック回路から分圧抵抗を直接接続する回路に変更しました。
目標値のプログラムも変更しました。
(アナログデータとして読み取るため)

const float Target = ; // 目標値 float Target = TargetVolt * ( R2) / (R1 + R2 ) / 3.3f * 4095.0f ; //R1が上側抵抗値(回路図上のR6)でR2が下側抵抗値(回路図のR7+VR)

確認したいこと

このあたりのADCの読み取り・変換の部分で何か間違っているものはありますか?

x = HAL_ADC_GetValue(&hadc1); x = (x / 4095.0f) * TIM1->ARR ;

この辺りのPID制御処理の計算が間違っているものはありますか?

// 偏差の計算 P = Target - x; // 積分項の計算 I += P * (us_time * 1e-6); //微分項の計算 D = (P - Old_P) / (us_time * 1e-6) ; //偏差の更新 Old_P = P ; // 操作量の計算(PID 制御) u = kp * P + ki * I + kd * D ;

補足情報(FW/ツールのバージョンなど)

参考サイト
https://controlabo.com/pid-gain-tuning/#toc1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2022/10/03 01:39 編集

直感なんですが、 起動時の立ち上がりは2秒程度と遅い応答が必要で、 負荷変動時の電圧変動はms程度で速い応答が必要となると 通常のPID制御では無理な気がします。 普通に速い応答で制御するようにして、 ソフトスタートは目標出力電圧を徐々に上げて実現するほうがいいと思います。
yuki23

2022/10/04 03:38

L1の値はいくつでしょうか?
PHENIXa

2022/10/05 11:34

L1の値は330μHです。
ozwk

2022/10/10 01:55

結局のところ、今の問題はなんですか?
ozwk

2022/10/10 10:40

目標値になった時点でRL負荷を外すと電圧が130V程度まで上がってしまう。(元に戻ろうとするが125Vで維持されてしまう。) 逆に外すと93V付近まで低下する 何が「逆に」なんですか?どちらも外しているようですが
PHENIXa

2022/10/10 11:23

すみません。間違えていました。
yuki23

2022/10/10 11:34

1. 目標値(100V)の時, 2. RLを外した後, 3. RLを再びつけた後、のそれぞれのデューティ比(実測値)はどうなっていますか?
PHENIXa

2022/10/10 13:46

マイコンが壊れてしまったため、修理後にもう一度再確認しますが 1,2,3全てにおいて最小と最大を(75%〜25%)行ったり来たりしている状態となっています。 例えば25%→30%→50%→75%まで徐々に上がるというわけではなく25%か75%というような動作をしている状態でした。
yuki23

2022/10/27 15:27

この回路は自分で設計されたんでしょうか?それとも何か出典があるのでしょうか? それと、デューティ比の制御範囲を25-75%と決めた根拠は何でしょうか?
PHENIXa

2022/11/03 09:47

自分で設計というわけではありませんが考案しました。 デューティ比の制御範囲を25-75%にすると故障する可能性があるからそのような制限にしました。
PHENIXa

2022/11/03 10:45

ところでPID制御の計算式に違うものはないのでしょうか?一方通行の質問ばかりで回答いただいていないのですが、
ozwk

2022/11/03 10:52

下限値と上限値しか出てないのはなにか変ですね 上どちらかにに張り付き続けるとかならまだわかるのですが、 どっちにも振れるとなると係数が大きすぎるとか処理が間違っているとか回路がおかしいとかで制御が大きく振動してしまっているのでしょう シリアル出力などで各変数が意図通りの振る舞いをしているかの確認や 昇圧回路部分を外してAD変換部に適当な電圧を与えて意図通りの出力が得られるかの確認をすると良いかと思います
yuki23

2022/11/03 11:37

PID制御の計算式に違うものはないかということですが、そこがあなたの抱えている問題の原因であるという根拠が何も示されていないので、それ以外の部分が原因であると思って質問しています。原因を特定せずに当てずっぽうでプログラムばかりいじっていても何も解決しません。 質問している内容は、私が原因ではないかと思った部分です。 しかし、質問者さんのやりとりから、この回路の動作はどうなっているべきなのか、このプログラムにはどのような入力があってどのような出力をするべきなのかについて、そもそも理解されていないようなので、まずはちゃんとした教科書と実績のある制御対象を使って勉強されるのが良いのではないかと思います。なお、私はPID制御に対するちゃんとした知識はないのでおすすめの教科書などはご紹介できません。あしからず。
PHENIXa

2022/11/03 12:22

PID制御のD項があると上下が増減してしまうようですが、この動作は正常なのでしょうか? この制御が正常でないなら改善する必要があるのですが.
ozwk

2022/11/03 12:37

上下が増減とは?
PHENIXa

2022/11/03 12:45 編集

デューティー比が最大と最小を行ったり来たりしてしまいます。 これはアナログ信号を直接3.3Vに接続してる状態でもそうなります(この時はコイルは接続していません。)
ozwk

2022/11/04 06:17 編集

Targetは4095倍が入っている一方で xは4095で割ってますけどこれは意図通りですか? Targetに対してxがかなり小さな値になりそうです。
PHENIXa

2022/11/06 11:37

それは必要だと思ったから記述しましたが、今回はよく考えたら必要ありませんでした。
guest

回答1

0

自己解決

yuki23 さんのヒントのおかげで解決することができました。
>何か出典があるのでしょうか?

ほぼPIDについて無知でしたが、とてもいい勉強になりました。
解決方法としては
・出力のアナログ値をフィードバックする(薄々わかってはいたのですが...)
・PIDパラメータを今回の場合はかなり小さくする(本当にかなり小さくしないと動作しませんでした)
これで解決することができました。

投稿2022/11/06 11:37

PHENIXa

総合スコア47

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問