※超非効率なDuty比測定プログラム(測定精度はそこそこで、測定時間がかなり長い)から始まり、測定精度と測定速度向上を狙いローパスフィルターを使ってPWMを電圧に変換してDuty比を測定する(OPアンプを4~8個も使う?な回路)等々紆余曲折しました。
ラジコンの制御はサーボモーターもDCモーターも全てPWM信号のDuty比を変化させる事で動作しており、Arduinoでラジコンを半自動運転(半とは自分もラジコンで遊びたいのでプロポで操作も可能にするの意味です、全自動ではなく半自動にしたのがハマりポイントでした)するにはどうしてもDuty比を高速・高精度に測定する必要が有りました。
1. プログラム
色々遠回りしましたが結局プログラムの作り方が悪かったと言うオチでした(;'∀')
// PWM信号のD比測定 volatile unsigned long UpNew; volatile unsigned long UpOld; volatile unsigned long DownNew; volatile unsigned long DownOld; volatile float Duty; //測定したD比 void setup() { pinMode(2, INPUT_PULLUP); //割込を監視する2番ピンをプルアップし入力に設定 attachInterrupt(0, SUB, CHANGE); //2番ピンの電圧変化時にSUBを実行 Serial.begin(9600); //シリアル通信を9600bpsで開始 } void loop() { Serial.println(Duty); //SUBルーチンで測定したDuty比をPCに送信 delay(1000); //1000ms(一秒)待つ } void SUB() { if (digitalRead(2) == LOW) { //もし2番ピンがLOWなら{}内を実行する DownOld = DownNew; //DownOldに前回の電圧の立下り時刻を保存 DownNew = micros(); //DownNewに現在の時刻を保存 Duty = ((DownNew - UpNew) * 1000) / ((UpNew - UpOld)) * 0.1; //D比計算 } else { //もし2番ピンがLOWでなかったら(HIGHなら)以下の{}内を実行する UpOld = UpNew; //UpOldに前回の電圧の立上り時刻を保存 UpNew = micros(); //UpNewに現在の時刻を保存 Duty = ((DownNew - UpOld) * 1000) / (UpNew - UpOld) * 0.1; //D比計算 } }
図1:プログラム例
2. 測定限界の確認!
2.1 周波数
接続後オシロスコープからD比50%PWM信号の周波数を50、100、200、500、1000、2000、5000Hzと出力し、何処までDuty比をArduinoUNOで測定可能か試してみました。 測定の結果2000Hz迄ArduinoUNOでDuty比を測定出来ました。
図1:周波数2,000Hz迄測定可能!
2.2 デューティー比
周波数はラジコンのPWM信号で一般的に使用する50Hzとし、オシロスコープ(DSO Nano v3)からDuty比10~90%を10%刻みで出力し、ArduinoUNOでDuty比を測定した結果、全てのDuty比で出力値+0~-0.1の精度でDuty比が測定出来る事を確認しました!
図2:ArduinoUNOでDuty比10%を測定した結果
3. まとめ
励みになりますのでよければクリック下さい(^o^)/