HOME >> 鉄道模型実験室 > Arduino Nano Every のPWM周波数をアップする

鉄道模型実験室 No.152  Arduino Nano Every のPWM周波数をアップする

 先回の報告「卓上レイアウトで楽しもう 自動運転 その23」(2020/3/1)で、PWM制御によって当初の狙いどうりの制御を実施することが出来ましたので、次の課題に取り組みました。 それは、PWM制御の周波数が約 1KHz と低いため、動きがぎごちなく感じられますし、ピーという音も気になりますので、このPWM周波数を20KHz近くまでアップさせることに挑戦しました。 結果はうまく行きましたが、新たな問題も出てきました。

 

■ PWM周波数について

 ご存知のように、PWM制御はON/OFFによるスイッチング機能によって、モータなどへの給電を制御しています。 この時のスイッチング周波数が人間の可聴域にあると、ピーという音が聞こえてきます。 従って一般的にはこの可聴域を避けたシステムにする必要があります。 しかし、技術的に難しい電車等ののモータ制御は例外です。

 本当に、どこまでの周波数が聞こえてくるのか調べてみましょう。 道具はスマホにダウンロードしたアプリを使用します。

 このアプリを使って、自分の可聴域をチェックすると、なんと、8,000HZ を越える辺りから聞こえなくなってしまいました・・・・・・・・・(;_;)  参考画面を見ると年齢と共に低下する様子が案内されていましたが、もうすぐ80になる小生には、妥当な数字の様でした。

 今年の正月に孫たちが集まった時、何故だかこの可聴域が話題となり、中学・高校の孫たちは 20KHz 近くまで聞こえており、40〜50代の大人たちは15KHz 程度までで、自分は 10KHz 以下でありました。 このため、PWM周波数のアップは、10KHz以上を目標とすることにしましょう。

 

■ 給電制御での周波数アップの方法は?

 自動運転では、速度制御のためにPWM制御が欠かせません。 このため、20KHz 程度の高周波PWM制御を実施する方法を考えてみました。

 (1)PICマイコンを使って給電制御する
卓上レイアウトで楽しもうシリーズの前半で使用していたPICマイコンのPIC16F1827 を使用すれば、 20KHz 程度の高周波PWM制御を実施することが可能と考えています。 ポート数も対応できるので、Arduino を諦めてこちらに乗り換えることも出来ますが・・・・・・・・。
 
 (2)ブリッジドライバBD6211を使用する
ブリッジドライバを探していたときに見つけたROHM社のHブリッジドライバーシリーズを使って、VREF制御モードにて給電制御する方法です。 試しに入手した石はBD6211の7V耐圧使用でしたが、簡単な実験で確認したところ、立派にコントローラとして応用できそうであることが分かりました。 VREF制御モードでは、入力されたDC電圧と供給電圧の比に応じたヂューティ比てPWM制御を実施してくれるもので、PWM周波数は25KHzでするので、目的にはピッタリです。 ただ、入力はDCである必要がありますので、Arduino のPWM出力は平滑回路を通す必要があります。 抵抗とコンデンサを使えば出来そうですね。
 
 (3)やはりArduino Nano Every で挑戦する
ここまで来たので、やはりArduino Nano Every を放棄することは無いでしょう。

■ Arduino Nano Every で挑戦する

 ます、ネットで情報を集めましたが、なかなか見つかりませんでした。 石が異なると指示方法が異なるので、Everyに関する情報を探りました。 そして、Arduino 関係のページで Topic: Nano Every PWM frequency を見つけましたが、内容はやっぱり理解出来ませんでした。 ただ、関係するタイマーはTCA とTCB があるらしいことがわかり、

タイマーはTCAを触ると時間に関する命令が影響されるので注意せよとのことでした。

 そこで、PWM制御の設定方法は、PICマイコンの場合と基本的には同じであろうと睨んで、Nano Every のチップである ATmega4809 の仕様書を睨んでいました。 内蔵するタイマーにはいくつかあるのですが、5個のPWM制御ポートにつながっているタイマーはTCA でした。 そこで、タイマーTCAを中心に探していると、下のようなページを見つけました。 タイマー/カウンタのプリスケーラ設定倍率を指定するレジスタです。

 そこで、このレジスターの値を変えてやればPWM周波数も変更できるのではないかと考えましたが、さて、どうやってArduino に命令するのか、その方法に悩みました。 さる資料では、cbi( ) とか sbi( ) などの命令でビット操作が出来ると書いてあったので試してみましたが、ケッチンを食らってしまいました。 なにやらのライブラリーを読み込んでおく必要があるようですが、何を読み込むのか分かりません。 しかし、上記の参考サイトで見た記述方法をいろいろ試してみました。

      TCA0.SINGLE.CTRLA = 0x2 ;

 コンパイルをかけてみると、なんと通ってしまいました。  たったこの一行の命令で指定できるのだ!

  .

 そこで、0ビットのENABLE指定も含めた値を入力して、プリスケーラの設定倍率を指定することにしました。

      TCA0.SINGLE.CTRLA = 0b0101 ;

 ENABLE指定ビットは常に1に設定します。

 

■ 実際のPWM出力波形を観察しよう

 そこで、実際のPWM出力波形を観察して、指定倍率と周波数の関係を確認することにしました。 実験装置は、右の写真に示すように、予備のNano Every を使い、出力ポートの波形をオシロで直接観察しました。

 

■ 観察結果

 まず、追加記述の無いオリジナル状態を上記の記述を追加した状態を見てみましょう。 使用したスケッチ ⇒ Every-Test-10

追加記述なし(オリジナル状態) TCA0.SINGLE.CTRLA = 0b0101

  周波数 = 983 Hz

  周波数 = 15.7 KHz

 周波数は、見事にアップしている事が分かります。 そこで数値を変えて周波数を読み取って行き、その結果を表にまとめました。

Value Name 指定した数値 周波数 倍率
0x0 DIV1 0b0001 62.9KHz 1
0x1 DIV2 0b0011 31.4KHz 2.0
0x2 DIV4 0b0101 15.7KHz 4.0
0x3 DIV8 0b0111 7.86KHz 8.0
0x4 DIV16 0b1001 3.93KHz 16.0
0x5 DIV64 0b1011 983Hz 64.0
0x6 DIV256 0b1101 246Hz 256
0x7 DIV1024 0b1111 61.4Hz 1024

 さすがにコンピュータは正確ですね。目標とする 20KHz にするには、他の項目をいじる必要がありますので、DIV4 の15.7KHz で良しとしましょう。

● 他のポートとの同期具合は?

 この実験は、二つのポートに出力させて、波形を観察しました。  使用したスケッチ ⇒ Every-Test-11

D10とD9 D10とD3

ピッタリ一致しています。

ピッタリ一致しています。

 D6やD5ポートの場合の問題無く、ピタリと一致していました。

● 遅延時間関数への影響は?

 タイマーのTCA を触っていますので、時間に関する delay( ) 関数の数値を指定して、実際の時間をオシロで観察しました。 数値を指定してパルスをON/OFFさせました。 使用したスケッチ ⇒ Every-Test-12

delay(1000)を指定 delay(100)を指定

 パルスの間隔は 62msec

 パルスの間隔は 6.2msec

 即ち、1000/62 ≒ 16、100/6.2 ≒ 16 であるので、delay() 関数は16倍して指定する必要がでてきました。 なお、オシロで表示された周波数は休止時間があるため、半分の周波数になったものと解釈しています。

 

■ 実際の卓上レイアウトで確認しましたが、新の問題が発生しました。

 出来た!出来た! と喜んで実際の卓上レイアウト上のプログラムに適応してみました。 先回のスケッチにたった一行を追加しただけですが、思わに問題に突き当た手しまいました。

  コアレスモータの動力車はスムースに動くのに、Bトレ電車は動かない!

 えーー !?????・・・・・・・・? ダイヤルまわしてデューティ比を上げると、電車は脱兎のごとく生きよい良く飛び出していきますが・・・。

  1KHz では問題無く走ったのに、16KHz では動かないのはなぜなの?

 

 これまた、不思議な現象に出くわしました。 まだ、その原因が分からないのですが、オシロで波形を見た限り、疑問点がいくつかありました。 ネット情報で調べた限りでは、「A4953ELJの波形調査」と同じような現象が起きているのではないかと考えています。

 

 この件に関しては、自分なりに色々実験してみることにして、とりあえず、Arduino Nano Every のPWM周波数をアップ出来た事を報告しておきます。

 

ページトップへ戻る  .


 2020/3/3 作成