前提
ラジコンの受信器から出てくる信号をArduinoUNOで読み込もうとしていますが、どうしても上手くいきません。
信号は1500usec±500usecのパルスで、複数チャンネルが同時にHighになり、操縦するレバーの位置によりパルス幅が1000usec~2000usecの間で変化します。
下記するプログラムは3チャンネルの信号を受信するもので、パルスの立ち上がりで割込みを掛け、割込み処理部の最初にmicros()関数で電源ON後の経過時間をusec単位で計り、その後各チャンネルの出力がゼロになるまで待って、ゼロになった直後のmicros()との差をパルス幅として計測しようとしています。
しかし、 if (digitalRead(ch1) == 0 ){AAA};としてCh1の入力がゼロになるまでAAAパスする部分が何故かAAAを実行してしまい、正しくパルス幅を計測できません。
二日ほど格闘していますが、どうしても理解できず、質問する次第です。
どなたかご教示いただけると助かります。
追記すると本来なら1000~2000という数値が返ってくるべきところ、信号がゼロになるのを待たずにパルス幅を測る為、24~44という数値が返ってきます。
実現したいこと
シンプルにCh1、Ch2、Ch3のパルス幅をusec単位で計りたいです。
該当のソースコード
int ch1 = 2; // D1ピンにプロポのCh1を入力
int ch2 = 3; // D2ピンにプロポのCh2を入力
int ch3 = 4; // D3ピンにプロポのCh3を入力
volatile boolean ch1_HL;
volatile boolean ch2_HL;
volatile boolean ch3_HL;
volatile boolean flag;
volatile boolean ch1_end; // Ch1パルス幅計測終了フラグ
volatile boolean ch2_end; // Ch2パルス幅計測終了フラグ
volatile boolean ch3_end; // Ch3パルス幅計測終了フラグ
volatile int puls1 = 0; // Ch1のパルス幅
volatile int puls2 = 0; // Ch2のパルス幅
volatile int puls3 = 0; // Ch3のパルス幅
volatile unsigned long time0; // パルス幅計測ゼロ点記憶
int LED = 13; // 割込み処理中点灯
void setup() {
Serial.begin(9600);
pinMode (ch1, INPUT);
pinMode (ch2, INPUT);
pinMode (ch3, INPUT);
pinMode (LED, OUTPUT);
attachInterrupt(0, Measure_puls_wide, RISING);
}
void loop() {
LP:
while (flag == 0) goto LP; // 割込み処理終了を待つ
flag = 0; // 割込み処理が終了したらフラグをリセットし次処理に
Serial.print (puls1); // これ以降はテスト用に計測値を表示
Serial.print ("+");
Serial.print (puls2);
Serial.print ("+");
Serial.println (puls3);
}
void Measure_puls_wide() {
time0 = micros();
digitalWrite(LED, 1);
noInterrupts();
// Serial.println ("Interupt");
while ((ch1_end + ch2_end + ch3_end) < 3) { //全チャンネルの終了をするまで
ch1_HL = digitalRead(ch1); // Ch1のレベルを読み込む ch2_HL = digitalRead(ch2); // Ch2のレベルを読み込む ch3_HL = digitalRead(ch3); // Ch3のレベルを読み込む if (digitalRead(ch1) == 0 ); { // もしCh1が1ならパス puls1 = micros() - time0; // Ch1が0ならパルス幅を計算 ch1_end = 1; // Ch1計測終了フラグを1にする } if (digitalRead(ch2) == 0 ); { // もしCh2が1ならパス puls2 = micros() - time0; // Ch2が0ならパルス幅を計算 ch2_end = 1; // Ch2計測終了フラグを1にする } if (digitalRead(ch3) == 0 ); { // もしCh3が1ならパス puls3 = micros() - time0; // Ch3が0ならパルス幅を計算 ch3_end = 1; // Ch3計測終了フラグを1にする }
}
ch1_end = 0; // Ch1計測終了フラグをリセット
ch2_end = 0; // Ch2計測終了フラグをリセット
ch3_end = 0; // Ch3計測終了フラグをリセット
flag = 1; // 割込み処理終了フラグをセット
digitalWrite(LED, 0); // 割込み中LEDをオフ
// if (time_ch1 < 1000 || time_ch1 > 2000) time_ch1 = 1500;
// if (time_ch2 < 1000 || time_ch2 > 2000) time_ch2 = 1500;
// if (time_ch3 < 1000 || time_ch3 > 2000) time_ch3 = 1500;
interrupts();
}
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答2件
あなたの回答
tips
プレビュー