2017-01-28 20:28 | カテゴリ:PIC応用回路

今回は特にマニアックは話です(笑)

先日、Youtubeを見ていたら、安定した低速走行をさせるコントローラを紹介しているサイトがありました。


動画や説明から想像しますと、モーターの回転を検出して、そのフィードバックでPWM波形を制御し、実現されているようです。
詳細は公開されていませんでしたので、実際はどのような仕組みなのかわかりませんが、想像するに、PWMで走行させつつ、PWM波形が出ていない期間に、回転しているモータからの起電力を検出し、それをモーターの回転とみなして、PWM信号を制御し、安定した低速走行を実現していると思いました。

以前に製作した、簡易型のPWM利用のNゲージコントローラが手元にありますので、これに少し手を加えて、このクローズド制御の試行を行ってみました。


MTC012
(コントローラ写真)
MTC12.jpg

続きはこちらで、、、、



回路的には、PICのA/D変換機能と、PWM機能を利用すれば、ハードは簡単にできそうです。
制御の流れを考えてみました。

1)VRでアナログ電圧をPICに与える。
2)PWM信号を停止して、出力回路の電圧(モーターからの起電力をA/D変換する)をPICで読み込む。
3)両者を比較して、モーターからの電圧が低ければ、PWM信号のDUTY比を少し上げる。
  VRからの電圧が低ければ、PWM信号のDuty比を少し下げる。
といった動作を繰り返せば、希望の電圧(出力)で車両を走行させることができそうです。

もちろん、加減速の速さや、レスポンスなど、かなりクリティカルな調整が必要なことは想像できますが。

NETでモーターの回転制御を調べてみると、同様のアイデアがあり、この方法は、間違ってはなさそうです。
回路を検討するに際して、以下の点を考慮しました。


1)Nゲージ車両は、12Vですが、PWMのパワーを得るために、16VのAC/DCアダプターを利用する。
  この16VをPWMでレールに送る。
2)PICは、最近利用を始めた、PIC16F1938を使用する。
  理由は、マイクロチップのコード・コンフィギュレータが利用でき、基本の設定(タイマーやPWMなど)が簡単なこと。

MTC11
MTC11.jpg


3)既存のNゲージコントローラのHWを生かすこと。


ソフトは。XC8で製作しました。
AD変換やPWMの初期設定が簡単に行える、コード・コンフィグレータ(MCC)を利用しましたので、基本部分は容易に制作できました。

ただし、一か所、TMR1の割り込み処理の中で、AD変換を使用するのですが、その際には、TMR1のプロジェクトの中に、AD変換のヘッダーファイルと、AD読み込み関数の定義を入れなければ、エラーとなりますので、注意が必要です。(私も悩みました)

プログラムコードは後程紹介しますが、処理としては簡単なものです。

1、初期設定で、TMR1、MTR2、AD変換(Ch0、Ch1)を定義する。
2、TMR1は、100msecくらいで割り込みを繰り返すように設定し、その都度、VRを接続したAD変換のch0を読み込んで、指定速度を得ます。
3、PWMは、5KHz周期にセットして、5msec毎にPWMを停止し、その後100マイクロ秒待って、出力端子間の電圧(モーターの起電力)をADch1で読み込みます。
4、読み込んだ電圧値と指定速度の電圧値を比較し、指定電圧が高ければ、mPWMのDutyを上げ、逆に、低ければPWMのDutyを下げるようにします。
5、これを繰り返せば、指定された速度電圧を維持する様にモーターが回転する、「はず」です。


速度を指定するAD変換部分は、問題ないのですが、モーターの起電力(電源OFF後に、慣性でモーターのコアが回転する際に生じる電力)をレール経由で検出し、AD変換するところが、この回路の肝です。

肝のポイントを挙げてみました。

1、PWM停止後、どのくらいの時間経過後に起電力が出るのか?
2、電圧はどのくらいか?(鉄道模型は12V)
3、ノイズはどの程度か?(モーターというノイズ、車輪とレールを経由して検出する際のノイズなど)
4、そのノイズをどうやって除去できるのか?
5、PWMのDutyを加減する際の数値はどのくらいが適当か?

などなど、不明なことがたくさんです。

まずは、Nゲージ車両のモータを直接接続して、回転させ、波形を観測してみました。


(波形1)
MTC01
MTC01.jpg

MTC02
MTC02.jpg


PWM波形は、Dutyが低いので、幅の小さな、尖ったパルス状に見えます。
多数の細いパルスは、PWMのパルスで、その後、少し小さなサイン派のような波形が見えますが、これが、PWM波形を停止後に、モーターの空転によって生じた起電力の波形と思われます。
(注意)
通常、モーターの駆動を停止するとmコイルによって、大きな「逆起電力」が生じます。今回は、回路の中に、ダイオードを入れて、この「逆起電力」を吸収する様にしています。

MTC09
MTC09.jpg

この二つのダイオードで、逆起電力を逃がしています。


波形を見ますと、PWMパルス終了後、150マイクロ秒以降に電圧が出ているようです。

電圧としては、3-5Vくらいでしょうか?

メモリーが無いオシロでの観測ですから、かなりいい加減です(笑)

PWMのDutyを少しずつ増大させてみて、波形の変化を見てみます。

MTC03
MTC03.jpg

MTC04
MTC04.jpg

MTC05
MTC05.jpg

MTC06
MTC06.jpg


この波形を見るとこの時点でも相当なノイズ(安定した波形ではありません)があります。
これが、レールの上を走る車輪経由で検出するとなると、さらに困難が予想されます。

これらの波形は、レール上の電圧波形ですが、制御用には、この信号をRCのローパスフィルターにかけて、その出力をAD変換に入力しています。

MTC08
MTC08.jpg

ここの抵抗とコンデンサーです。

そのローパスフィルターの出力が、この様な波形です。

MTC07
MTC07.jpg


なお、デバッグ時にフィードバック用の電圧の数値確認や、速度指示用のVRの電圧確認用に、バーLEDに二進数で表示できるようにしてあります。

MTC10
MTC10.jpg

実は、ここからが非常に手間取りました。
調整するパラメータが、先に述べました肝のポイントが多くあり、正直なところ、こちらを変えてはダメ、あちらをいじったらまた変になった、の繰り返しで、数日消費。

結果、何とか基本調整が終わりました。

以下にMainプログラムコードの繰り返し部分を抜粋しましたが、ここで変数BEMFがAD変換で読み込んだ、起電力の電圧を平均したものです。
Dutyはその結果でPWMのDutyを変化させる変数で、プラス・マイナス1づつ増減させています。(B)と(C)

PMW停止後に、100マイクロ秒待って、AD変換しています。(A)
MAX回数繰り返してAD変換し、平均をとっています。(ノイズ除去と安定化のため)

BEMFの値は、バーLEDに表示しています。(D)
実際は10ビットなので、2ビットカットして、上位8ビットをBレジスターに入れて、LEDに表示しています。



//------------------------------
// 以下繰り返し処理
//------------------------------
while (1) {
RunLED ^= 1;
//__delay_ms(5);


//-------------------------------------
// 読み込んだAD値BEMFとSpeedを比較して制御
//-------------------------------------

if (Flag == 0) {
EPWM1_LoadDutyValue(0); // PWM停止
__delay_us(100); // 100usec 遅延  <=====(A)
BEMF = 0;
for (i = 0; i < MAX; i++) {
Temp = ADC_GetConversion(1) >> 6;
if(Temp <= 10) Temp = 0;//ノイズ対策
BEMF += Temp;
//__delay_us(20); // AD変換時間待ち20usec
}

BEMF = BEMF / MAX; //BEMFに現在のモーター回転の電圧が保存される


//------------------------
// 平均したBEMFをチェックする
//------------------------

if (BEMF > Speed) {
Duty = Duty - 1; <=====(B)
if (Duty < 0) {
Duty = 0;
}
EPWM1_LoadDutyValue(Duty); // PWMセット

}
if (BEMF < Speed) {
Duty = Duty + 1; <=====(C)
if (Duty >= 1023) {
Duty = 1023;
}
EPWM1_LoadDutyValue(Duty); // PWMセット

}


PORTB = ~(BEMF >> 2);//BEMFの値をLEDに表示 <=====(D)

__delay_ms(5);
} else {

//-------------------------------------------
// PWMをSpeedの値によって設定(Flag=1)の場合
//-------------------------------------------

EPWM1_LoadDutyValue(Speed); // 読み取ったVRのAD変換値をDutu比として指定

}
}
}



というわけで、とりあえず、プログラムコードの基本部分が出来ましたので、実際に列車を走らせて、様子を観察しました。

再度、DD51に登場してもらいました。
最初は、ループ制御をOFFにして、PWMだけの出力で、DD51を低速走行させて、少し傾斜をつけた線路を走らせてみました。


(制御OFF)



途中で負荷が大きくなったようで、止まってしまいました。


一方、制御ONにした場合は、

(制御ON)


ゆっくり走行していますが、坂道になっても速度がほとんど低下しないで、上っていきました。
ループ制御の効果が出ていると思うのですが、確証はありません。(笑)




【ジャンル】:趣味・実用 【テーマ】:鉄道模型
コメント(4)

管理者のみに表示する