前提
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); }
デコードしなくてもクリアされてしまうので
decodeEn();呼び出しの次の行の}が
Mcode = 1;
bitcount = 0;
space = true;
の下まで移動でわかる?
回答いただきありがとうございます.
仰っている通りに直したところ,出力に大量に出ていた改行が無くなりましたが,今度はAと打ったら
E
H
E
E
E
E
H
E
I
S
E
E
I
I
E
I
S
E
E
E
E
E
E
と出力されるようになりました.長点がうまく認識できていないのかと考えております.もう少し考えてみます.
LEDの出力ピンをそのまま入力ピンにいれていませんか?
赤外線受光ユニットは、何を使ってますか?
(短点しかでてこないということで、入力された信号の論理が逆と疑っての上記の質問です。)
