質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

解決済

ラジコン受信機のプロポ信号をArduinoUNOで受信しようとしていますが上手くいきません

tom20220220
tom20220220

総合スコア10

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

2回答

0評価

0クリップ

372閲覧

投稿2022/07/28 08:10

前提

ラジコンの受信器から出てくる信号を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/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

y_waiwai

2022/07/28 08:21

このままではコードが読みづらいので、質問を編集し、</>(コードの挿入)ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。