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

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

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

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

Q&A

3回答

1962閲覧

Arduinoで思うような処理ができない

wakame_495

総合スコア1

Arduino

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

0グッド

1クリップ

投稿2022/06/07 10:38

前提

http://jh7ubc.web.fc2.com/arduino/CW_decoder.html
こちらのサイトを参考にしつつ,ArduinoでCWデコーダの作成をしましたが,思うような動作が得られませんでした.

実現したいこと

赤外線LEDから送られてきたモールス信号を,英語に変換し,シリアルモニターに映し出すようにしたいです.

発生している問題・エラーメッセージ

Arduino Uno,Arduino 1.8.19を使用しております.
どの英字のモールス信号を送ってもEと表示されてしまい,困っております.
どなたかご教授いただけますと幸いです.

#define RECV_PIN 11 //デジタルIOの11番ピンを受信データ入力用に設定 byte Mcode=1;//モールス符号内部コード long startLOW; //LOW状態が始まった時刻 long startHIGH; //HIGH状態が始まった時刻 long LOWtime; //LOW状態が続いた時間(ms) long HIGHtime; //HIGH状態が続いた時間(ms) long nosignaltime; //無信号(HIGH状態)が続いた時間 byte data1 = HIGH; //入力ピンの状態 byte data0 = HIGH; //入力ピンの前の状態 byte data; //dot(短点)のときdata=0,dash(長点)のときdata=1 byte bitcount = 0; //入力bit数 long time1; //無信号時の経過時間(ms) boolean space = false; //spaceを送出するかどうかのflag int dottime = 100; //短点と長点を分ける時間(ms)の初期値 int Ltime = 100; //dot(LOWtime)の一時記憶,初期値100ms void setup() { Serial.begin(9600); pinMode(RECV_PIN,INPUT_PULLUP); } void lspace () { Serial.println(" "); } void loop() { data1 = digitalRead(RECV_PIN); //入力ピンの状態を読む if (data1 == HIGH && data0 == LOW) { //信号がLOWからHIGHに変わったら startHIGH = millis(); //HIGH状態が始まった時刻 LOWtime = millis() - startLOW; //LOW状態が続いた時間(信号があった時間)(ms) if (LOWtime < dottime) { //基準時間(dottime)より短ければ data = 0; //dot Ltime = LOWtime; //LOWtimeを記憶 } else { data = 1; //dash } bitcount++; //入力されたビット数をカウント Mcode=Mcode<<1; //Mcodeを左に1bitシフト Mcode=Mcode | data; //McodeとdataのORをとる if (bitcount > 8) { //8 bit 以上はerror Mcode = 1; bitcount = 0; } } if (data1 == LOW && data0 == HIGH) { startLOW = millis(); } if (data1 == HIGH && data0 == HIGH) { time1 = millis() - startHIGH; if (bitcount != 0) { if (time1 > (8 * Ltime)) { decodeEn(); } Mcode = 1; bitcount = 0; space = true; } } if (space == true && time1 > 7 * Ltime) { //スペースの表示 { lspace(); } space = false; } data0 = data1; } void decodeEn() { switch (Mcode) { case B00000101: { Serial.println("A"); //"A" } break; case B00011000: { Serial.println("B"); //"B" } break; case B00011010: { Serial.println("C"); //"C" } break; case B00001100: { Serial.println("D"); //"D" } break; case B00000010: { Serial.println("E"); //"E" }; break; case B00010010: { Serial.println("F"); //"F" } break; case B00001110: { Serial.println("G"); //"G" } break; case B00010000: { Serial.println("H"); //"H" } break; case B00000100: { Serial.println("I"); //"I" } break; case B00010111: { Serial.println("J"); //"J" } break; case B00001101: { Serial.println("K"); //"K" } break; case B00010100: { Serial.println("L"); //"L" } break; case B00000111: { Serial.println("M"); //"M" } break; case B00000110: { Serial.println("N"); //"N" } break; case B00001111: { Serial.println("O"); //"O" } break; case B00010110: { Serial.println("P"); //"P" } break; case B00011101: { Serial.println("Q"); //"Q" } break; case B00001010: { Serial.println("R"); //"R" } break; case B00001000: { Serial.println("S"); //"S" } break; case B00000011: { Serial.println("T"); //"T" } break; case B00001001: { Serial.println("U"); //"U" } break; case B00010001: { Serial.println("V"); //"V" } break; case B00001011: { Serial.println("W"); //"W" } break; case B00011001: { Serial.println("X"); //"X" } break; case B00011011: { Serial.println("Y"); //"Y" } break; case B00011100: { Serial.println("Z"); //"Z" } break; } }

補足

モールス信号は以下のコードで送信しております.

int LED = 8; // LEDを指すピン int timeUnit = 100; // モールス信号のトンツーの長さの基準100ミリ秒 char input; // 入力を保存する変数 void setup () { Serial.begin(9600); //シリアル通信の速度を設定 pinMode(LED,OUTPUT); //ピンを入力に設定 } void loop () { if (Serial.available()) { input = Serial.read();//read the input if (input == 'A') {lA();} //入力がaまたはAのとき,関数lAにいく else if (input == 'B') {lB();} //以下同様 else if (input == 'C') {lC();} else if (input == 'D') {lD();} else if (input == 'E') {lE();} else if (input == 'F') {lF();} else if (input == 'G') {lG();} else if (input == 'H') {lH();} else if (input == 'I') {lI();} else if (input == 'J') {lJ();} else if (input == 'K') {lK();} else if (input == 'L') {lL();} else if (input == 'M') {lM();} else if (input == 'N') {lN();} else if (input == 'O') {lO();} else if (input == 'P') {lP();} else if (input == 'Q') {lQ();} else if (input == 'R') {lR();} else if (input == 'S') {lS();} else if (input == 'T') {lT();} else if (input == 'U') {lU();} else if (input == 'V') {lV();} else if (input == 'W') {lW();} else if (input == 'X') {lX();} else if (input == 'Y') {lY();} else if (input == 'Z') {lZ();} else if (input == ' ') {wordPause();} else {Serial.println("error!");} Serial.println (input); } } //Letter functions void lA () {dot();dash();letterPause();} //モールス信号のA void lB () {dash();dot();dot();dot();letterPause();} //同様にB void lC () {dash();dot();dash();dot();letterPause();} void lD () {dash();dot();dot();letterPause();} void lE () {dot();letterPause();} void lF () {dot();dot();dash();dot();letterPause();} void lG () {dash();dash();dot();letterPause();} void lH () {dot();dot();dot();dot();letterPause();} void lI () {dot();dot();letterPause();} void lJ () {dot();dash();dash();dash();letterPause();} void lK () {dash();dot();dash();letterPause();} void lL () {dot();dash();dot();dot();letterPause();} void lM () {dash();dash();letterPause();} void lN () {dash();dot();letterPause();} void lO () {dash();dash();dash();letterPause();} void lP () {dot();dash();dash();dot();letterPause();} void lQ () {dash();dash();dot();dash();letterPause();} void lR () {dot();dash();dot();letterPause();} void lS () {dot();dot();dot();letterPause();} void lT () {dash();letterPause();} void lU () {dot();dot();dash();letterPause();} void lV () {dot();dot();dot();dash();letterPause();} void lW () {dot();dash();dash();letterPause();} void lX () {dash();dot();dot();dash();letterPause();} void lY () {dash();dot();dash();dash();letterPause();} void lZ () {dash();dash();dot();dot();letterPause();} void dot() //100ミリ秒点灯 { digitalWrite(LED, HIGH); delay(timeUnit); digitalWrite(LED, LOW); delay(timeUnit); } void dash() //300ミリ秒点灯 { digitalWrite(LED, HIGH); delay(timeUnit * 3); digitalWrite(LED, LOW); delay(timeUnit); } void letterPause() //アルファベット間の待ち時間300ミリ秒 { digitalWrite(LED, LOW); delay(timeUnit * 3); } void wordPause() //単語間の待ち時間700ミリ秒 { digitalWrite(LED, LOW); delay (timeUnit * 7); }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tmp

2022/06/08 03:01

デコードしなくてもクリアされてしまうので decodeEn();呼び出しの次の行の}が Mcode = 1; bitcount = 0; space = true; の下まで移動でわかる?
wakame_495

2022/06/08 12:38

回答いただきありがとうございます. 仰っている通りに直したところ,出力に大量に出ていた改行が無くなりましたが,今度はAと打ったら E H E E E E H E I S E E I I E I S E E E E E E と出力されるようになりました.長点がうまく認識できていないのかと考えております.もう少し考えてみます.
tmp

2022/06/08 22:40

LEDの出力ピンをそのまま入力ピンにいれていませんか? 赤外線受光ユニットは、何を使ってますか?
tmp

2022/06/09 11:02

(短点しかでてこないということで、入力された信号の論理が逆と疑っての上記の質問です。)
guest

回答3

0

ハードが正しく動いていて、ビット反転とかもないと仮定して、
if (data1 == HIGH && data0 == HIGH)
これではRECV_PINがONの時はほぼ毎サイクルif文が成立して、bitcountは実質1か0しか取らない羽目になるのでは。

投稿2022/06/07 14:45

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wakame_495

2022/06/08 12:33

回答いただきありがとうございます。 確かに仰っている通りだと思います。少し考え直してみます。
guest

0

基本、matukesoさんが書いている通り。(3行を上に持っていく)
後はどういった送信の仕方をしているのか?による。

で、送信側がスイッチならチャタリングがあるからその対策も必要になる。
因みに、ちょっとタクトスイッチを繋いで確かめたけど、
(私が押した感覚だと)dottimeが少なすぎ。250程度で問題無い感じ。
(一応添付図のようにA~Oまでは試した)

で、手動(スイッチ)で送信なら、間隔が重要なので、添付図のように、どっちを判断しているかデバックコード(*と-を表示させて、押しながらどう判断してるか見る)も追加した方が良い。
そうしないと雲をつかむような事になっちゃうよ。
イメージ説明

投稿2022/06/09 07:40

nac_tnk

総合スコア463

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nac_tnk

2022/06/09 08:28

御免。補足見ていなかった。 送信側もあったんだね。 まぁ、上に書いた通り、3行を移動させれば、基本、プログラム自体は動きます。 なので、タイミングが合っていないか、回路や出力が悪いのか・・・ LEDでも付けて確認してみれば?
nac_tnk

2022/06/09 09:11

シミュレーション上では、送信側のコードを int timeUnit = 60; にしたら動いたよ。 (100msより短いか長いかで判断するのに100msで送ったらダメ。60なら60msと180msとで判断される)
guest

0

まずはその赤外線なるものの信号をオシロスコープで見て、きちんと意図している信号が出ているのかを確認するところから始めましょう
そして、その受信側の信号を確認することです。
ハードウエア周りがしっかり動いているというのをきちんと確認しとかないと、いくらコードをいじったところで動きません。

投稿2022/06/07 12:23

編集2022/06/07 12:25
y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wakame_495

2022/06/07 12:28

早速回答いただきありがとうございます。 詳しく記載せず申し訳ございません。iPhoneの内カメラにて赤外線LEDの様子を撮影し、無事に動作確認を終えております。
y_waiwai

2022/06/07 12:34

目視でいくら確認したつもりになってもダメですよw
Zuishin

2022/06/07 13:06

モールス信号なんて目視で十分判別できると思いますが。
wakame_495

2022/06/07 13:45

手元にオシロスコープがないため、確認することが厳しい状況です。せっかくご教授いただいたにも関わらず、大変申し訳ございません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問