ブラシモーターのセンサレス制御実験
はじめに
ブラシ付きモーターのセンサレス回転検出&制御にチャレンジしてみました。
模型用のマブチモーターやNゲージのポイント切替に使ったFM90のモーターは
ブラシ付きのDCモーターで小型、安価です。
これらブラシモーターを使って電池電圧の変化や負荷の変動があっても一定速度で回したいとか 回転速度や積算回転数を検出したい場合は何らかの回転速度検出機能と専用回路が必要です。
光学センサーや磁気センサーを使えば精度よく回転検出ができますが
小型モータに回転検出用センサを取り付けるのは面倒ですしサイズ的にも難しい場合が多いと思います。
一方、高価なブラシレスモーター+制御回路のシステムでは回転センサを使うものの他に コイル通電切り替え時の回転による誘起電圧を検出してセンサ無しで回転制御をするものがあります。
ブラシ付きモーターではコイル通電切替がブラシ+整流子によりモーター内で行なわれるため ブラシレスモーターと同じ手法は使えません。
参考: ブラシモーターの解説サイト https://techweb.rohm.co.jp/product/motor/motor-types/87/
しかし、ブラシ+整流子によるコイルへの通電切り替えによって何らかの電流変動が生じているはずです。
ならばその電流変化をうまく処理すれば回転検出できるのではないかと考えて実験しました。
アナログ回路をいろいろ試した結果、センサレス回転検出および制御ができました。
ただし電流変動が小さい低電圧(低回転数)領域では検出精度が落ちたり検出できない場合があります。
また今回の試作ではPWM制御値が0~100%の1%ステップで、ある期間内の複数回転の平均値をフィードバックしています。
そのためステッピングモーターのような正確な回転制御はできません。
模型用のマブチモーターやNゲージのポイント切替に使ったFM90のモーターは
ブラシ付きのDCモーターで小型、安価です。
これらブラシモーターを使って電池電圧の変化や負荷の変動があっても一定速度で回したいとか 回転速度や積算回転数を検出したい場合は何らかの回転速度検出機能と専用回路が必要です。
光学センサーや磁気センサーを使えば精度よく回転検出ができますが
小型モータに回転検出用センサを取り付けるのは面倒ですしサイズ的にも難しい場合が多いと思います。
一方、高価なブラシレスモーター+制御回路のシステムでは回転センサを使うものの他に コイル通電切り替え時の回転による誘起電圧を検出してセンサ無しで回転制御をするものがあります。
ブラシ付きモーターではコイル通電切替がブラシ+整流子によりモーター内で行なわれるため ブラシレスモーターと同じ手法は使えません。
参考: ブラシモーターの解説サイト https://techweb.rohm.co.jp/product/motor/motor-types/87/
しかし、ブラシ+整流子によるコイルへの通電切り替えによって何らかの電流変動が生じているはずです。
ならばその電流変化をうまく処理すれば回転検出できるのではないかと考えて実験しました。
アナログ回路をいろいろ試した結果、センサレス回転検出および制御ができました。
ただし電流変動が小さい低電圧(低回転数)領域では検出精度が落ちたり検出できない場合があります。
また今回の試作ではPWM制御値が0~100%の1%ステップで、ある期間内の複数回転の平均値をフィードバックしています。
そのためステッピングモーターのような正確な回転制御はできません。
試作概要
検出/制御対象の範囲、試作基板の概要を以下のように設定しました。
・電源電圧は3V~5V(乾電池2本~3本)
・一般的な3極コイル+3分割整流子+2本ブラシのモーターを制御対象とする。
・回転数は少なくとも20000RPMまで検出できるようにする。
(検出下限は電源電圧とモーター依存)
・平均のモーター駆動電流は最大で500mA程度を想定
・アナログ処理により電流変動をデジタル的なパルスに変換してPICマイコンに入力
・PICマイコンの内蔵ハードを利用して回転速度を検出し、PWM方式で回転を制御する。
・アナログ回路の評価だけでなくモーターを使った工作に応用しやすい機能を付加する。
1.キャラクタディスプレイ表示
2.プッシュスイッチによる設定変更機能
3.PICの不揮発性メモリを使って電源ON直後のモーターON/OFFや回転数を指定できるようにする。
・電源電圧は3V~5V(乾電池2本~3本)
・一般的な3極コイル+3分割整流子+2本ブラシのモーターを制御対象とする。
・回転数は少なくとも20000RPMまで検出できるようにする。
(検出下限は電源電圧とモーター依存)
・平均のモーター駆動電流は最大で500mA程度を想定
・アナログ処理により電流変動をデジタル的なパルスに変換してPICマイコンに入力
・PICマイコンの内蔵ハードを利用して回転速度を検出し、PWM方式で回転を制御する。
・アナログ回路の評価だけでなくモーターを使った工作に応用しやすい機能を付加する。
1.キャラクタディスプレイ表示
2.プッシュスイッチによる設定変更機能
3.PICの不揮発性メモリを使って電源ON直後のモーターON/OFFや回転数を指定できるようにする。
回路
3極2ブラシのモーターではコイルへの電流切替が1回転あたり6回起こります。
これをアナログ処理してマイコンに入力できるデジタルパルスに変換します。
試作した回路図は以下の通り。
これをアナログ処理してマイコンに入力できるデジタルパルスに変換します。
試作した回路図は以下の通り。
アナログ処理
上記回路図のR9(1Ω 1W)は電流検出用の抵抗です。
R9の端子にモーター駆動電流に比例した電圧が生じるのでC13のコンデンサでDCカットしてオペアンプに入力しています。
電流検出抵抗は3225サイズの表面実装タイプも使用できるように予備ランドを設けています。
モーター駆動の平均電流が0.5Aなら電流検出抵抗によるドロップ電圧は0.5V、発熱量は電流*抵抗値*電流=0.25Wとなります。
もっと電流の大きなモーターの場合は電流検出抵抗を0.1Ωにするなど発熱量と検出感度を見て調整する必要があります。
R9の端子にモーター駆動電流に比例した電圧が生じるのでC13のコンデンサでDCカットしてオペアンプに入力しています。
電流検出抵抗は3225サイズの表面実装タイプも使用できるように予備ランドを設けています。
モーター駆動の平均電流が0.5Aなら電流検出抵抗によるドロップ電圧は0.5V、発熱量は電流*抵抗値*電流=0.25Wとなります。
もっと電流の大きなモーターの場合は電流検出抵抗を0.1Ωにするなど発熱量と検出感度を見て調整する必要があります。
アナログ信号処理には8ピンパッケージに2個入りのCMOSタイプオペアンプ NJU7096D (90円@秋月電子2025/10) を使いました。
電源電圧5Vでオペアンプの実測消費電流が0.25mA程度と小さく、電源電圧2V程度でも動作するようです。
オペアンプの各段は1次のローパスフィルタにしています。
目的はアナログ波形の高調波成分を取り除き、6パルス/1回転のきれいなパルスに近づける事とPWM制御の影響防止です。
カットオフ周波数は上記回路図中オペアンプ1段目のR5*C3と2段目のR3*C2に逆比例し
fc = 1/(2*π*C*R) = 1/(2*π*51KΩ*1000pF) = 3121 Hz としました。
3KHzのパルスまで正確に検出できた場合、最大検出可能な回転数(RPM)は以下の通りです。
3000(Hz)/6(パルス/秒)*60(秒) = 30000RPM
また1段あたり34db (R5/R8=R3/R4=51倍)の増幅率で使用しているので2段で約2500倍となり 電流検出抵抗の端子電圧変動が2mAで5Vの出力振幅になります。
電源電圧5Vでオペアンプの実測消費電流が0.25mA程度と小さく、電源電圧2V程度でも動作するようです。
オペアンプの各段は1次のローパスフィルタにしています。
目的はアナログ波形の高調波成分を取り除き、6パルス/1回転のきれいなパルスに近づける事とPWM制御の影響防止です。
カットオフ周波数は上記回路図中オペアンプ1段目のR5*C3と2段目のR3*C2に逆比例し
fc = 1/(2*π*C*R) = 1/(2*π*51KΩ*1000pF) = 3121 Hz としました。
3KHzのパルスまで正確に検出できた場合、最大検出可能な回転数(RPM)は以下の通りです。
3000(Hz)/6(パルス/秒)*60(秒) = 30000RPM
また1段あたり34db (R5/R8=R3/R4=51倍)の増幅率で使用しているので2段で約2500倍となり 電流検出抵抗の端子電圧変動が2mAで5Vの出力振幅になります。
なおモーター回転制御はアナログ的な電圧制御ではなくPWMによるデジタル制御を使います。
PWMのON/OFF周波数は160KHz(>>Fc=3KHz)としてローパスフィルタで充分抑圧できるようにしています。
オペアンプを単一電源で使うため、オペアンプの+側には抵抗分割による基準電圧(電源電圧の約1/2)を入れています。
1段目と2段目で微小な差を付けているのはモーター停止時のノイズによる誤検出を防ぐためです。
以下はオペアンプ出力の実測波形例です。上の波形が1段目出力、下が2段目出力です。
電源電圧は4.9Vで使用したモーターは分周ギア付きのMercury motor製(1/120分周)とFM90です。
4つめのFM90 PWM=20%のようにモーター電流が小さい低速回転域ではきれいな方形波出力になっていません。
そのため正確な回転数検出ができていない可能性があります。
ですが、実際の回転数と検出回転数間で単調増加性が保たれていればフィードバックによる回転安定化は可能です。
PWMのON/OFF周波数は160KHz(>>Fc=3KHz)としてローパスフィルタで充分抑圧できるようにしています。
オペアンプを単一電源で使うため、オペアンプの+側には抵抗分割による基準電圧(電源電圧の約1/2)を入れています。
1段目と2段目で微小な差を付けているのはモーター停止時のノイズによる誤検出を防ぐためです。
以下はオペアンプ出力の実測波形例です。上の波形が1段目出力、下が2段目出力です。
電源電圧は4.9Vで使用したモーターは分周ギア付きのMercury motor製(1/120分周)とFM90です。
4つめのFM90 PWM=20%のようにモーター電流が小さい低速回転域ではきれいな方形波出力になっていません。
そのため正確な回転数検出ができていない可能性があります。
ですが、実際の回転数と検出回転数間で単調増加性が保たれていればフィードバックによる回転安定化は可能です。
【Mercury 1/120, PWM=100%】
【Mercury 1/120, PWM=50%】
【FM90, PWM=50%】
【FM90, PWM=20%】
オペアンプ出力は念のためPICマイコン内蔵のヒステリシス機能付き差動入力コンパレータ(14ピン、19ピン)へ入力しています。
ですが上記のオペアンプ出力波形を見ると通常のデジタル入力ピンでも問題なさそうです。
PICマイコンによる処理
電池駆動(3V~5V)なので電圧レギュレーターは付けていません。
モーター駆動電圧を高くしたい場合は回路図のフェライトビーズ(FB2)の位置に5Vの電圧レギュレーターを入れれば 電源電圧20V程度まで使えます。
PICマイコンには設定数値の増減、選択、モード切替のためのに4つのプッシュボタンを付けました。
また高電圧(40V)対応の入力端子(P7 IN_HV)も付けましたが今回は未使用です。
オペアンプ出力はPIC内蔵のヒステリシス機能付きコンパレータで受けています。
コンパレータ出力のパルスの計測は割り込み処理とPIC内蔵のカウンタで行ないます。(詳細は後述のソフトウェア参照)
モーター駆動電圧を高くしたい場合は回路図のフェライトビーズ(FB2)の位置に5Vの電圧レギュレーターを入れれば 電源電圧20V程度まで使えます。
PICマイコンには設定数値の増減、選択、モード切替のためのに4つのプッシュボタンを付けました。
また高電圧(40V)対応の入力端子(P7 IN_HV)も付けましたが今回は未使用です。
オペアンプ出力はPIC内蔵のヒステリシス機能付きコンパレータで受けています。
コンパレータ出力のパルスの計測は割り込み処理とPIC内蔵のカウンタで行ないます。(詳細は後述のソフトウェア参照)
設定値や状態表示のために8文字×2行のバックライト付きLCDディスプレイを付けました。
PICマイコンとの接続はI2C規格の2線式シリアルインタ―フェイスです。
I2Cはオープンドレイン方式の双方向インターフェイス規格でディスプレイ側からもACKが返ってきます。
そのためPIC出力はソフトウエアによるI/Oレジスタ操作によるオープンドレイン(プルダウン or Hi-Z)としています。
オープンドレインの場合、プルアップ抵抗が必要になります。
PICマイコンには内蔵のプルアップ機能がありますがこれはかなり高インピーダンスなので 動作速度をあげるためプルアップ抵抗を外付けしています。
PICマイコンには内蔵のUART機能があり、ハードウエアでI2Cもサポートしますが I/Oピンが限定されてしまうため使っていません。
ソフトウエア+通常のデジタルI/OピンでI2Cに対応しています。
内蔵の10bit A/D変換器を使い電源の電圧を計測しています。
A/D変換器の基準電圧を電源(A/D変換値=1023)とし、内蔵の固定電圧源=1.024VをA/D変換した値から電源電圧を計算します。
VDD = 1.024V*1023/(1.024VのA/D変換値)
LCDディスプレイのバックライトの平均電流(輝度)は電源電圧に対して指定した電流値になるよう計算してPWM制御しています。
ただし電源電圧がバックライトLEDのVf≒2.6V以下になるとバックライトは点灯しません。
PICマイコンとの接続はI2C規格の2線式シリアルインタ―フェイスです。
I2Cはオープンドレイン方式の双方向インターフェイス規格でディスプレイ側からもACKが返ってきます。
そのためPIC出力はソフトウエアによるI/Oレジスタ操作によるオープンドレイン(プルダウン or Hi-Z)としています。
オープンドレインの場合、プルアップ抵抗が必要になります。
PICマイコンには内蔵のプルアップ機能がありますがこれはかなり高インピーダンスなので 動作速度をあげるためプルアップ抵抗を外付けしています。
PICマイコンには内蔵のUART機能があり、ハードウエアでI2Cもサポートしますが I/Oピンが限定されてしまうため使っていません。
ソフトウエア+通常のデジタルI/OピンでI2Cに対応しています。
内蔵の10bit A/D変換器を使い電源の電圧を計測しています。
A/D変換器の基準電圧を電源(A/D変換値=1023)とし、内蔵の固定電圧源=1.024VをA/D変換した値から電源電圧を計算します。
VDD = 1.024V*1023/(1.024VのA/D変換値)
LCDディスプレイのバックライトの平均電流(輝度)は電源電圧に対して指定した電流値になるよう計算してPWM制御しています。
ただし電源電圧がバックライトLEDのVf≒2.6V以下になるとバックライトは点灯しません。
LCDディスプレイのコントラストも電源電圧に応じて調整しないと文字が見えなくなってしまいます。
そのため、これもA/D変換で測定した電源電圧に応じて設定を調整しています。
コントラスト設定変更はLCDディスプレイに対するI2Cインターフェイス経由コマンド送信で行ないます。
PICマイコンの19ピンは差動入力コンパレータの+側入力とPICのプログラム書き込みデータ入力(ICSPDAT)を兼ねています。
ですがCMP+の信号線を19ピンに直結するとC15(1μF)の影響でプログラム書き込みが出来ません。
そこで対策としてR12(22KΩ)を挿入しました。
そのため、これもA/D変換で測定した電源電圧に応じて設定を調整しています。
コントラスト設定変更はLCDディスプレイに対するI2Cインターフェイス経由コマンド送信で行ないます。
PICマイコンの19ピンは差動入力コンパレータの+側入力とPICのプログラム書き込みデータ入力(ICSPDAT)を兼ねています。
ですがCMP+の信号線を19ピンに直結するとC15(1μF)の影響でプログラム書き込みが出来ません。
そこで対策としてR12(22KΩ)を挿入しました。
プリント基板データ
最近はサンハヤトの感光基板が高価になりました。
一方、少量でも中国の基板メーカー(例:seeed fusion、PCBGOGO、JLCPCB、・・・)に発注可能で、送料を含めても感光基板による自作より安いかもしれません。
KiCadが使えればGerberフォーマットのデータ作成は簡単で、それを送って発注すればきれいな基板が手に入ります。
以前、susukuma鉄道チャンネルから多数の基板提供依頼が来た時、私もずいぶんお世話になりました。
基板が複数枚必要な時には非常に楽で安価になり助かりました。
特に小さな基板だと「基板の面付け」対応のメーカーならば多数枚必要な時に劇的に安価になります。
ですが感光ドライフィルムと片面銅張基板の在庫がまだいっぱい残っていて、回路修正も多そうだったので今回も自作しました。
8文字×2行のLCDキャラクタディスプレイのピン間隔が狭いため、手作業での穴あけはかなり難しく慎重に行なう必要がありました。
基板自作用のpdfデータとGerberデータ(2層基板)をまとめてzip圧縮したものを以下に置きます。
(このGerberデータそのままで基板製造を外注できるかは確認していません。)
【片面基板+ジャンパ配線による自作用データ】
NEG_BMTRCTL-B_Cu.pdf 裏面マスク 感光ドライフィルム用
POS_BMTRCTL-B_Cu.pdf 裏面マスク 感光基板用
BMTRCTL_Jumper_back.pdf 裏面ジャンパ配線
BMTRCTL-B_Silkscreen.pdf 裏面部品配置
BMTRCTL-F_Silkscreen.pdf 表面部品配置
BMTRCTL-PTH-drl_map.pdf ドリルマップ
【2層基板用Gerbarデータ+ドリルファイルをまとめてzip圧縮したデータ】
BMTRCTL_Gerber.zip
抵抗、コンデンサは電流検出抵抗とLCDディスプレイ付属の20Ω以外は1608サイズ(inchだと0603)の表面実装部品を使いました。
一方、少量でも中国の基板メーカー(例:seeed fusion、PCBGOGO、JLCPCB、・・・)に発注可能で、送料を含めても感光基板による自作より安いかもしれません。
KiCadが使えればGerberフォーマットのデータ作成は簡単で、それを送って発注すればきれいな基板が手に入ります。
以前、susukuma鉄道チャンネルから多数の基板提供依頼が来た時、私もずいぶんお世話になりました。
基板が複数枚必要な時には非常に楽で安価になり助かりました。
特に小さな基板だと「基板の面付け」対応のメーカーならば多数枚必要な時に劇的に安価になります。
ですが感光ドライフィルムと片面銅張基板の在庫がまだいっぱい残っていて、回路修正も多そうだったので今回も自作しました。
8文字×2行のLCDキャラクタディスプレイのピン間隔が狭いため、手作業での穴あけはかなり難しく慎重に行なう必要がありました。
基板自作用のpdfデータとGerberデータ(2層基板)をまとめてzip圧縮したものを以下に置きます。
(このGerberデータそのままで基板製造を外注できるかは確認していません。)
【片面基板+ジャンパ配線による自作用データ】
NEG_BMTRCTL-B_Cu.pdf 裏面マスク 感光ドライフィルム用
POS_BMTRCTL-B_Cu.pdf 裏面マスク 感光基板用
BMTRCTL_Jumper_back.pdf 裏面ジャンパ配線
BMTRCTL-B_Silkscreen.pdf 裏面部品配置
BMTRCTL-F_Silkscreen.pdf 表面部品配置
BMTRCTL-PTH-drl_map.pdf ドリルマップ
【2層基板用Gerbarデータ+ドリルファイルをまとめてzip圧縮したデータ】
BMTRCTL_Gerber.zip
抵抗、コンデンサは電流検出抵抗とLCDディスプレイ付属の20Ω以外は1608サイズ(inchだと0603)の表面実装部品を使いました。
ソフトウェア
-- 書き込みデータとソースコード --
ソフト開発環境はMPLAB X version 6.25で、書き込み器はMPLAB SNAPを使いました。
コンパイル済みのhexファイルとMPLAB X IDEのプロジェクトデータ(ソースコード含む)をまとめてzip圧縮したものを添付します。
BMTRCTL.X.production.hex
BMTRCTL.X.zip
MPLAB IPEを使ってコンパイル済みプログラムを書き込む手順は以下の通りです。
ソースコードの確認、修正、デバッグをして書き込む場合は上記zipファイルを展開し、できたBMTRCTL.XフォルダをMPLAB X IDE の作業環境下に置きます。
MPLAB X IDE を起動して File --> Open Projectで表示されるウインドウでBMTRCTL.Xをダブルクリックして開きます。
ソースファイルはProjectタブ以下のWindowを使って表示や編集等ができます。
[四角+下むき矢印]のアイコンを押すとコンパイルと書き込みが行なわれます。
ブレークポイント等を使って実機動作のデバッグも可能です。
IDE の使い方はMicrochip社のサイトなどネット検索して参照してください。
以下は詳細説明です。何かの参考になれば幸いです。
-- MCCによる自動コード生成について --
ハードウエアの初期設定や関連ソースコードの生成にMPLAB XのMCC の3種の内の classicを使いました。
MCC(MPLAB Code Configurator)にはより新しいMelodyやHarmonyというのもあるのですがPIC16F1829で使えるのはclassicのみのようです。
MCC Harmonyは32bit CPU用ですし、 MCC Melodyは移植性重視?など高機能なのかもしれませんが細かいハード設定の仕方がわからず私はいまだにClassicを使っています。
MCC Classicを使うとプログラムコードを書く前にPIC本体やPIC内蔵ペリフェラルのヘッダーファイル、初期化や制御用サブルーチンを生成できます。
そのためPICの仕様書を詳細に読み込む必要がほとんど無くなります。
ソフト開発環境はMPLAB X version 6.25で、書き込み器はMPLAB SNAPを使いました。
コンパイル済みのhexファイルとMPLAB X IDEのプロジェクトデータ(ソースコード含む)をまとめてzip圧縮したものを添付します。
BMTRCTL.X.production.hex
BMTRCTL.X.zip
MPLAB IPEを使ってコンパイル済みプログラムを書き込む手順は以下の通りです。
1.PC側でMPLAB IPEを起動
2.settingタブを押してRelease from Resetを押す
3.チップ型番=PIC16F1829を指定
4.hexファイルをドラッグ&ドロップで指定
5.PIC書き込み器を選択してconnectを押す
6.書き込みボタンを押す。
2.settingタブを押してRelease from Resetを押す
3.チップ型番=PIC16F1829を指定
4.hexファイルをドラッグ&ドロップで指定
5.PIC書き込み器を選択してconnectを押す
6.書き込みボタンを押す。
ソースコードの確認、修正、デバッグをして書き込む場合は上記zipファイルを展開し、できたBMTRCTL.XフォルダをMPLAB X IDE の作業環境下に置きます。
MPLAB X IDE を起動して File --> Open Projectで表示されるウインドウでBMTRCTL.Xをダブルクリックして開きます。
ソースファイルはProjectタブ以下のWindowを使って表示や編集等ができます。
[四角+下むき矢印]のアイコンを押すとコンパイルと書き込みが行なわれます。
ブレークポイント等を使って実機動作のデバッグも可能です。
IDE の使い方はMicrochip社のサイトなどネット検索して参照してください。
以下は詳細説明です。何かの参考になれば幸いです。
-- MCCによる自動コード生成について --
ハードウエアの初期設定や関連ソースコードの生成にMPLAB XのMCC の3種の内の classicを使いました。
MCC(MPLAB Code Configurator)にはより新しいMelodyやHarmonyというのもあるのですがPIC16F1829で使えるのはclassicのみのようです。
MCC Harmonyは32bit CPU用ですし、 MCC Melodyは移植性重視?など高機能なのかもしれませんが細かいハード設定の仕方がわからず私はいまだにClassicを使っています。
MCC Classicを使うとプログラムコードを書く前にPIC本体やPIC内蔵ペリフェラルのヘッダーファイル、初期化や制御用サブルーチンを生成できます。
そのためPICの仕様書を詳細に読み込む必要がほとんど無くなります。
MCCがIDEにインストールされていない場合はtools-->Plugins-->Available Plugins でMPLAB Code Configuratorを探してインストールします。
開発開始時にMPLAB X IDEでFile-->New Projectから使用チップ、プログラム名称などを選択したら tools-->Embedded--> Mplab Code configurator で表示されるMCCの画面の[For MCC Classic Content: Click Here]を押してMCC classicを起動します。
開発開始時にMPLAB X IDEでFile-->New Projectから使用チップ、プログラム名称などを選択したら tools-->Embedded--> Mplab Code configurator で表示されるMCCの画面の[For MCC Classic Content: Click Here]を押してMCC classicを起動します。
添付したBMTRCTL.X.zipにはMCCの設定ファイルBMTRCTL.mc3が含まれているのでMCCを起動すると必要なペリフェラルが設定された状態になります。
もし新規に追加する場合は Device Resourcesウインドウ内の Peripheralタブの表示中から必要なカテゴリ>を展開し、先頭に+がついた個別名をクリックします。
するとProject Resourcesウインドウにペリフェラルを追加することができます。
ペリフェラルをクリックすると右側のウインドウで各種項目が設定できます。
ペリフェラルの追加や削除、設定項目変更後には忘れずにGenerateボタンを押す必要があります。
Generateで生成されたソースコードはProjectタブ下ウインドウ --> BMTRCTL --> Source FIlesやHeader Files --> MCC Generated Files の下にあります。
以下はテストプログラム(BMTRCTL)の各ペリフェラルのMCC設定画面です。
【System Module: 16MHz内蔵発振器、MPLAB SNAPで書き込めるモード設定】
【ADC: 10bit A/Dコンバータ(電源電圧監視用】
【FVR: 基準電圧発生器(A/Dコンバータ入力)】
【Pin Module: I/O PIN 初期設定】
【TMR0: 8msec毎のインタラプト発生用タイマー】
【TMR1: パルス間隔測定用フリーラン16bitタイマー】
【TMR2: 160KHz Clock for PWM】
【CCP3,CCP4: CCP3 for Motor PWM,CCP4 for LCD Back light PWM】
PWM setting range = 0 to 100(=16MHz/160KHz) , initial PWM=0
【CMP1: コンパレータ】
【MEMORY: 不揮発性メモリ使用】
-- 割り込み処理とパルス計測について --
割り込み処理はMCCで自動生成されたinterrupt_manager.cに追記しました。
まずTMR0の8msec毎の割り込み時に4個のプッシュボタンをサンプリングしてフラグ(sw_u,sw_d,sw_s,sw_m)をセットしています。
このサンプリングの目的はスイッチの機械的なチャタリング対策です。
これらのフラグはカウンタになっていて、mainルーチン側の処理で押しっぱなしの場合に一定間隔でon/offしたのと同じ動作をさせています。
またup/downのスイッチを押し続けた場合にup/downの数値変化幅をだんだん大きくするため(±1、±10、±100、...)、上記のフラグとは別に経過時間判定用のsw_continueをカウントアップまたはリセットしています。
もう一つの割り込み処理はコンパレータによるもので、モーター回転検出パルスの時間計測を行ないます。
2段目オペアンプ出力はコンパレータの負極側に接続され、コンパレータの割り込み条件はFalling Edgeを選択しているのでオペアンプ出力の立ち上がりエッジ毎に割り込みが発生します。
その割り込み毎に前回割り込み時からの経過時間を256ワードのリングバッファに記録します。
経過時間は16bit TMR1カウンタの (今回のカウンタ値 - 前回のカウンタ値) で計算しています。
TMR1はフリーランしていますので最大値(2の16乗=65,535)の次は0に戻りますが、その直後でもunsignedの16bit引き算で正しい経過時間が計算されます。
main.c内のget_rpm()でリングバッファ値を使って約80msec区間の平均RPMを算出しています。
-- LCDキャラクタディスプレイの制御について --
8文字X2行のLCDディスプレイはI2Cインターフェイス(2線式シリアル)で文字表示や制御を行ないます。
説明書 AQM0802A-FLW-GBW.pdf を見てもわかりにくい部分があり、特にコマンドでコントラストの設定を電源電圧に応じて適切に設定しないと文字が見えないので注意が必要です。
そこで今回のプログラムでは電源電圧(2~5V)に応じて自動で調整する機能を入れました。
アクセス用のサブルーチンはソースファイル I2C_LCD.c と I2C_LCD.h で定義しています。
通常のI/Oピンを使ってソフト制御でシリアル通信を行なっているので、I/OピンにMCCで"SDA"と"SCL"の名前を付けて使用します。
LCD1_*の名前のサブルーチンは表示1行目の先頭から、LCD2_*は2行目の先頭から指定した文字を表示します。
1、2の数字を含まない文字表示サブルーチンはそれ以前の表示文字の後ろに続けて表示します。
LCD*_ROMstr()とLCD*_str()の差異は引数が固定値か変数かです。
-- mainルーチンについて --
プログラム書き込み後の初回起動時かどうかを不揮発性メモリの先頭データで判定します。
もし初回なら各種設定のデフォルト値を不揮発性メモリに書き込みます。
ループ処理に入る準備として不揮発性メモリから各種設定値を読み出します。
メインループ内ではTMR0の割り込み10回に1回、すなわち80msec周期で下記の処理を行なっています。
ループ内では毎回モーターの回転数検出を行なっています。
また電源電圧を計測し、それに対応してLCDディスプレイのコントラストとバックライト輝度を調整しています。
MODEのプッシュスイッチを押すと動作モードが切り替わります。
UP/DOWNのプッシュスイッチを押すと表示されている設定値が変更できます。
数値の場合、プッシュスイッチを押し続けると連続的に増減し、さらに押し続けると増減のステップが1桁づつ増加します。
SETのプッシュスイッチを押すと回転数RPMが表示されているモードではモーターON/OFF切替、記憶モードでは不揮発性メモリへの各種設定値の書き込みを行ないます。
(詳細は以下を参照)
操作方法
スイッチ操作と各モードの動作について下記の図にまとめました。
PWM_RPMモードではPWM値を指定して回転数を変えられますが、電源電圧や負荷によって回転数が変動します。
KEEP_RPMモードでは目標回転数に近づくようにフィードバック制御し、電源電圧や負荷変動の影響を減らします。
MEMORYモードでは次回の電源ON時に使用する設定値を記憶します。
例えばモーターが回転している状態でMEMORYモードに変更し、KEEP_RPMを選択してSETスイッチを押します。
すると次回電源ONでKEEP_RPMモードになりモーターが設定した回転速度で回転します。
なお各設定の初期値は以下の通りです。
PWM_RPMモードではPWM値を指定して回転数を変えられますが、電源電圧や負荷によって回転数が変動します。
KEEP_RPMモードでは目標回転数に近づくようにフィードバック制御し、電源電圧や負荷変動の影響を減らします。
MEMORYモードでは次回の電源ON時に使用する設定値を記憶します。
例えばモーターが回転している状態でMEMORYモードに変更し、KEEP_RPMを選択してSETスイッチを押します。
すると次回電源ONでKEEP_RPMモードになりモーターが設定した回転速度で回転します。
なお各設定の初期値は以下の通りです。
MODE = PWM_RPM
PWM = 0%(下図のnnn)
目標RPM = 0(下図のttttt)
モーターのON/OFF = OFF
分周値 = 10(下図のkkk)
LCDバックライト電流 = 25 mA(下図のaa)
回転計測平均期間 = 8(下図のbb、単位80msec)
PWM = 0%(下図のnnn)
目標RPM = 0(下図のttttt)
モーターのON/OFF = OFF
分周値 = 10(下図のkkk)
LCDバックライト電流 = 25 mA(下図のaa)
回転計測平均期間 = 8(下図のbb、単位80msec)
動作テスト
動作例の動画(1/120分周ギア付き、FM90でモード切替有)を先頭に添付しました。
・PICマイコンおよびオペアンプは電源電圧2.0V付近まで動作確認できました。
・フィードバック制御は80msec毎に単純に1%づつPWM値を変えているだけなので回転数は±2~3%程度の変動があるようです。
モーターの推奨動作電圧からその1/2の電圧程度までなら割と安定して回転させることができるようです。
・KEEP_RPMモード(フィードバック有り)で動かしているときに負荷急増でモーター回転が止まったりするとPWM値が100%になります。
モーターの仕様、電源電圧によっては故障の原因になるかもしれません。
そのような可能性がある場合は電源電圧を下げたり、PWM値上限をプログラムに設定する対策が有効と思われます。
・今回のプログラムには実装していませんが、回転数の積算表示や回転数を指定しての自動停止機能の追加は容易です。
・電源電圧5Vでオペアンプの動作電流は0.3mA以下でした。
・電源電圧5VでPICマイコンとオペアンプ合わせた消費電力は4mA以下でした。
(測定条件はモーター接続無し、LCDバックライトはPWM値=0%で消灯、モーター駆動用PWM値=50%)
・PICマイコンおよびオペアンプは電源電圧2.0V付近まで動作確認できました。
・フィードバック制御は80msec毎に単純に1%づつPWM値を変えているだけなので回転数は±2~3%程度の変動があるようです。
モーターの推奨動作電圧からその1/2の電圧程度までなら割と安定して回転させることができるようです。
・KEEP_RPMモード(フィードバック有り)で動かしているときに負荷急増でモーター回転が止まったりするとPWM値が100%になります。
モーターの仕様、電源電圧によっては故障の原因になるかもしれません。
そのような可能性がある場合は電源電圧を下げたり、PWM値上限をプログラムに設定する対策が有効と思われます。
・今回のプログラムには実装していませんが、回転数の積算表示や回転数を指定しての自動停止機能の追加は容易です。
・電源電圧5Vでオペアンプの動作電流は0.3mA以下でした。
・電源電圧5VでPICマイコンとオペアンプ合わせた消費電力は4mA以下でした。
(測定条件はモーター接続無し、LCDバックライトはPWM値=0%で消灯、モーター駆動用PWM値=50%)