【 古いブログで掲載した記事(2020/4/4)を一部修正して再掲載します。】 Nゲージ鉄道模型で自動運転を楽しんでいます。
自動運転は、マイコンとして Arduino の Uno や Nano Every を使ってPWM制御を使って速度を調整しています。今回は Uno の場合を紹介します。 PWMキャリア周波数を 20kHz にアップする方法について、皆さんの情報をもとに自分でも調査しました。その結果、次のような実験にて確認しました。 まず実験方法はパソコンと Arduino Uno とオシロを使いました。
接続状態は下のようにオシロ用の端子を出力ポートに接続しただけの状態です。
そしてオシロで確認した波形を下に示します。
CH1はD10ポートで、CH2はD3ポートです。
CH1はD5ポートで、CH2はD3ポートです。
CH1はD9ポートで、CH2はD910ポートです。
CH1はD6ポートで、CH2はD5ポートです。
D3、D5、D10ポートでは、キャリア周波数は 20.0kHz となり、狙いどうりです。しかし、D6、D9、D11ポートではその半分の周波数で、かつ、デューティ比が50%の波形となっています。 また、正常に出力している D3、D5、D10ポート間の波形を観察すると、波形ごとにタイミングがズレている事が分かります。そして、リセットを掛けてもその状態が変わらなかったので、このタイミングのズレは内部的な必然と思われます。
実験にで使用したスケッチは、次の通りです。
// Uno 20KHzPWM test // 2020.4.3
#include < avr / io . h > void setup ( ) { pinMode ( 3 , OUTPUT ) ; pinMode ( 5 , OUTPUT ) ; pinMode ( 6 , OUTPUT ) ; pinMode ( 9 , OUTPUT ) ; pinMode ( 10 , OUTPUT ) ; pinMode ( 11 , OUTPUT ) ; TCCR0A = 0b01100011 ; TCCR0B = 0b00001010 ; OCR0A = 99 ; TCCR1A = 0b01100011 ; TCCR1B = 0b00011010 ; OCR1A = 99 ; TCCR2A = 0b01100011 ; TCCR2B = 0b00001010 ; OCR2A = 99 ; } void loop ( ) { int vol = 20 ; // OCR0B = vol; // OCR1B = vol; // OCR2B = vol; analogWrite ( 5 , vol ) ; analogWrite ( 10 , 70 ) ; analogWrite ( 3 , 40 ) ; }
setup 部分で関係するレジスタの設定を行い、loop の部分でデューティ比を設定してPWMを出力しています。最初は、//の部分のようにレジスタに直接アクセスして設定しましたが、その後、analogWrite( ) のコマンドを使ってみると、正常に出力されることを確認しました。 このコマンドが使用出来るのです! 上記に示した波形は、この状態で出力した時のオシロ波形なのです。
この方法では、デューティ比を設定できるPWM出力は、D3、D5、D10ポートのみです。 D6、D9、D11ポートはデューティ比が50%の半分の周波数しか出力していませんし、これ以外に使用出来ないのです。即ち、この方法では、このポートを他の用途として使用出来ない事を示しています。これもチャンとした理由があります。 また、D3、D5、D10ポートのタイミングも一致していませんが、これもチャンとした理由があります。 その理由を下記のサイトで説明しいますので参照してください。
鉄道模型工作実験室 Arduino Uno のPWMキャリア周波数を20kHzにする
ただし、注意が必要です 。 今回の処理は、ノコギリ波のトップの値を 255 から 99 に変更して20kHz 化を実施しています。従ってデューティ比の指定は0~99までしか指定できません 。このため、スケッチでのanalogWritr( ) のコマンドは使用できるものの、その指定値には注意が必要です。99以上の値は無効なので、結果的にはデューティ比100%の状態になるものと推定します(未確認ですが・・・・・)。 しかし幸いなことに、0~99までで 0~100%を指定することになるので、デューティ比のパーセント表示そのままの値を使用すれば良い事になります。