DCモータのセンサレス回転速度制御
先日、現代制御理論の基礎を学習いたしました。
この学習を経て これまでの古典的な制御から徐々に脱却をはかりたいと思いまして、ここではDCモータの回転制御について考えます。
目次
DCモータを考えるにあたり
以下を参考にDCモータの回転制御を考えます。
DCモータ回転システムはSHISEIGYO-1 DCをベースに構築します。
回転システム構築
まずはSHISEIGYO-1 DCの部品群をベースに回転システムを構築します。
まーた なんかしようとして pic.twitter.com/ZqPo8K8MCd
— HomeMadeGarbage (@H0meMadeGarbage) January 12, 2023
電流センス
モータに流れる電流をはかるために電流センサも使用します。
モータ配線間にセンサを挿入して電流値を確認しました。
若干ノイジー。。
モータの電流 pic.twitter.com/UeNf7u4iJH
— HomeMadeGarbage (@H0meMadeGarbage) January 14, 2023
可変抵抗でモータドライバ DRV8835に印可するPWMデューティ比を指定して回転速度を変えています。
回転センス
回転速度はSHISEIGYO-1 DCと同じ磁気エンコーダを使用して計測します。
回転数検知 pic.twitter.com/I2ThQ4QoPV
— HomeMadeGarbage (@H0meMadeGarbage) January 17, 2023
エンコーダは1周 5パルス出力し、それを4逓倍して回転速度を算出しています。
まずは古典的にPI制御
基本的なモータ回転システムが完成しましたので、まずは古典的手法であるPI制御でモータ回転速度制御をやってみます。
可変抵抗で指定した回転速度とエンコーダで測定した回転速度を比較してPI制御しました。
DCモータ
クラシカルにPI制御 pic.twitter.com/gOXdzbN8P2— HomeMadeGarbage (@H0meMadeGarbage) January 19, 2023
いい感じに制御出来てるかと思います。
コントローラ変更
PI制御の際に制御ゲインを調整するためにWiFi通信を用いようとしたところ、ATOM Matrix (ESP32-pico)だとADC2ピンがWiFiと併用できないことが発覚しました (たびたびこのトラップにハマる。。)。
可変抵抗や電流センサでanalogReadピンが必要となりWiFi使用でI/Oピン不足になってしまいます。
そこでコントローラとしてATOMS3を採用することにしました。
ATOMS3にはESP32-S3が搭載されています。ESP32-S3のADC2がWiFiとの併用が可能であるかは不明ですが (いや調べろよ) ATOMS3ではADC2ピンは外に出ていないため安心です。
ATOM MatrixだとWiFiとの併用でanalogReadできないピン発生
ATOMS3に変更
センシング値もディスプレイ表示できて便利だ pic.twitter.com/E5TiKd01f4— HomeMadeGarbage (@H0meMadeGarbage) January 19, 2023
問題なくWiFiとの併用でき、ディスプレイ表示もできて便利です。
モータ定数測定
PI制御で十分なモータ回転制御はできましたが、ここではより現代的な制御を目指します。
参考書籍にならってDCモータを数理的にモデル化して制御するためにここではモータの定数を測定します。
抵抗 R
モータの抵抗はテスタで測定
R = 0.8 Ω
インダクタンス L
モータのインダクタンスは NanoVNA で測定
L = 107 uH
発電定数 (磁束密度) $\Phi_m$
同じモータを連結させて速度をはかりながら回転させて、他方のモータの電圧を測定
$\Phi_m$ = 0.135 mV/rpm
慣性モーメントJ
慣性モーメントを測定するためにまず電流制御器を構成して電流を指定してモータを回してみます。
ブロック図は以下の通り(詳細は参考書籍。本当に勉強になりました)。
電流制御器内のR, Lは先ほど測定したモータの値を使用します。
可変抵抗で電流値を指定して回転させてみた。
電流制御でDCモータの回転を味わう
当然電流では回転速度をコントロールできない pic.twitter.com/ckm3VMmw6b— HomeMadeGarbage (@H0meMadeGarbage) January 24, 2023
次に目標電流値を0から0.6Aのステップで指定して回転速度変化を測りました。
モータ起動の傾きから間接的に慣性モーメントJを換算します。
$\frac{\Phi_m}{J} = 2910$
センサあり回転速度制御
モータの定数がわかったので、先ほどの電流制御器によるフィードバックに速度制御器を追加してモータを回してみます。
ブロック図は以下の通り(繰り返しますが 詳細は参考書籍。本当に本当に勉強になりました)。
速度制御器内の$j / \Phi_m$は先ほど測定した値を使用します。
可変抵抗で回転速度を指定して回転させてみました。
電流制御に速度制御を加えた憧れの多重フィードバック制御 pic.twitter.com/WtMTKOREv1
— HomeMadeGarbage (@H0meMadeGarbage) January 25, 2023
なかなか良い追従です。
測定回転速度が1周20パルスのエンコーダによるもので荒いことと、電流センサのノイズケアをしていないので心配しておりましたが、多重フィードバックによる制御が実現できました。
センサレス回転速度制御
センサありの時は測定回転速度をフィードバックして指定回転速度と比較しましたが、ここでは回転速度を推定するセンサレス制御を目指します。
推定回転速度はモータの電気回路モデルから以下で得られます(何度も繰り返しますが 詳細は参考書籍。本当に本当に本当に勉強になりました)。
$$\omega_{est} = \frac{V + \Delta V – R I_{meas}}{\Phi_m}$$
ここでVは電流制御器で算出された電圧で、$\Delta V $は電圧のオフセット値で実測とのずれをこの値で調整しました。
まずは上の式で得られる推定回転速度を実システムで観てみました。
まだ回転フィードバックはエンコーダによる測定値を使用しています。
DCモータ 回転速度推定
少し応答弱いけどちゃんと推定できてて喜ぶ
いい加減電流センサのフィルタリングも検討したほうがよいなまだ回転フィードバックはエンコーダ測定値使用 pic.twitter.com/i0husHCHpe
— HomeMadeGarbage (@H0meMadeGarbage) January 26, 2023
推定回転速度は少し応答性が良くないですが測定回転速度とよく一致しています。
絶対値が一致するように上式の$\Delta V $を調整しました。
いよいよ推定回転速度をフィードバックして指定回転速度と比較するセンサレス制御を実施します。
DCモータ センサレス回転制御
推定回転速度でフィードバック制御
実にいい感じ。比較検証用にエンコーダ使用。まぁセンサレスと言っても電流センサは使っているのだが pic.twitter.com/tibIJt61vh
— HomeMadeGarbage (@H0meMadeGarbage) January 26, 2023
センサレスでもよく指定回転速度に追従し、推定回転速度は測定回転速度とも一致しています。
ついにDCモータのセンサレス回転速度制御が実現できました。
Arduinoコード
コードのコア部のみ掲載しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
void loop() { nowTime = micros(); loopTime = nowTime - oldTime; oldTime = nowTime; Ts = (float)loopTime / 1000000.0; //sec //電流センサ https://amzn.to/3euX3Id VOUT=2.5+0.185*I Imeas = -(analogReadMilliVolts(ImeasPin) - offset) / 185.0; //[A] //回転推定 + 10msフィルタ rotEst += ((V + Voffset - R * fabs(Imeas)) / Phi - rotEst) * 0.01; //速度制御 roterr = rotSpeedTarget - fabs(rotEst); float KpASR = WcASR * JpPhi; SiASR += 0.2 * KpASR * WcASR * Ts * roterr; SiASR = constrain(SiASR, 0.0, 1.0); I = SiASR + KpASR * roterr; I = constrain(Ipi, 0.0, 1.0); //電流制御 Ierr = I - fabs(Imeas); SiACR += WcACR * R * Ts * Ierr; SiACR = constrain(SiACR, 0.0, 2.0); V = SiACR + WcACR * L * Ierr; V = constrain(Vpi, 0.0, 2.0); //モータ回転 pwm = 1023 - (1023 * V / 5.0); pwm = constrain(pwm, 800, 1023); } |
演算周期が一定でないので毎度 制御サンプル周期Tsを測って制御器で使用しています (L. 2-6)。
電流センサ値は起動の冒頭 (0A)で値を測っておいてoffsetとして電流計測時に引いています (L. 9)。
推定回転速度は10msecのフィルタをかけています (参考書籍 を参考 L. 12)。
電流制御で導出された電圧Vをpwmに変換してモータドライバに印可します (L. 37, 38)。
おわりに
ここではDCモータの現代的制御をめざしてセンサレス回転制御について勉強しました。
モータの物理モデル、電気回路モデルを用いたフィードバック制御によってセンサレス回転制御できることを確認でき感動いたしました。
エンコーダを使用しないモータ回転速度制御ができるようなったことは大きな前進と言え、色々応用したいと考えております。
しかし改めてPI制御の手軽さも痛感しました。
モータの電流検知って結構大変だし、モータ定数を測るのも結構めんどくさいからなぁ。。。