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

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

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

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

Q&A

解決済

1回答

5753閲覧

Arduinoで赤外線送受信

Alyn

総合スコア50

Arduino

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

0グッド

0クリップ

投稿2019/07/14 04:08

編集2019/07/14 04:18

Arduinoから赤外線を送信し、送信した信号を自身で受信しモニタに表示したいです。

最終的にリモコンの変換器にしたいと考えています。
しかしながら変換できる信号とそうでない信号がありました。
LEDが点灯したことから受信はできているので、送信ができていなかったです。

原因をとりあえず赤外線LEDと仮定し、実際に送信した信号をモニタしようとしましたが、うまくいきませんでした。
IR receiverモジュールは赤く点滅するので受信しているはずなのに赤外線を受信できていなかったです。
どうすればいいでしょうか?

赤外線送信検証ソースコード

Arduino

1#include <IRremote.h> 2 3int Recvpin = 11; 4int Ledpin = 12; 5 6IRrecv irrecv(Recvpin); // create instance of 'irrecv' 7IRsend irsend; 8decode_results results; // create instance of 'decode_results' 9 10void setup() 11{ 12 Serial.begin(9600); 13 Serial.println("IR Receiver Button Decode"); 14 irrecv.enableIRIn(); // Start the receiver 15 pinMode(Ledpin, OUTPUT); 16} 17 18void loop() 19{ 20 int result = 0; 21 static unsigned long data = 0xff10ef; 22 static bool flg = 0; 23 24// digitalWrite(Ledpin, HIGH); 25 irsend.sendNEC(data, 32); //D3pin only PWM 26// digitalWrite(Ledpin, LOW); 27 delay(10); 28 29 if(irrecv.decode(&results)) 30 { 31 Serial.println("Read"); 32 result = translateIR(); 33 Serial_print(); 34 35 irrecv.resume(); 36 37 if(result == 1) 38 { 39 Serial.print('\t'); 40 Serial.println(data, HEX); 41 data++; 42 } 43 else if(result == 0) 44 { 45 Serial.println(); 46 data++; 47 } 48 else 49 { 50 Serial.println("Not NEC"); 51 } 52 flg = 0; 53 } 54 else 55 { 56 if(flg == 0) 57 { 58 Serial.println("Not Read"); 59 flg = 1; 60 } 61 } 62 if(data == 0xffea16) 63 { 64 Serial.println("\nIR_END"); 65 while(1) 66 { 67 68 } 69 } 70 71 irrecv.enableIRIn(); 72 delay(100); 73} 74 75int translateIR() 76{ 77 int data = 0; 78 79 switch(results.value) 80 { 81 case 0xFF728D: //TV電源 82 { 83 data = 1; 84 break; 85 } 86 case 0xFFEA15: //TV入力切替 87 { 88 data = 1; 89 break; 90 } 91 case 0xFFC837: //決定 92 { 93 data = 1; 94 break; 95 } 96 case 0xFFB04F: //消音 97 { 98 data = 1; 99 break; 100 } 101 case 0xFF12ED: //音量+ 102 { 103 data = 1; 104 break; 105 } 106 case 0xFF926D: //音量- 107 { 108 data = 1; 109 break; 110 } 111 case 0xFF32CD: //十字↑ 112 { 113 data = 1; 114 break; 115 } 116//変換できなかった 117///////////////////////////////////////////////////////// 118 case 0xFF8A75: //十字↓ 119 { 120 data = 1; 121 break; 122 } 123 case 0xFFBA45: //戻る 124 { 125 data = 1; 126 break; 127 } 128 case 0xFF22DD: //番組表 129 { 130 data = 1; 131 break; 132 } 133 case 0xFFA25D: //番組情報 134 { 135 data = 1; 136 break; 137 } 138 case 0xFF38C7: //字幕 139 { 140 data = 1; 141 break; 142 } 143//////////////////////////////////////////////////////// 144 case 0xFF52AD: //1 145 { 146 data = 1; 147 break; 148 } 149 case 0xFFD02F: //2 150 { 151 data = 1; 152 break; 153 } 154 case 0xFF50AF: //3 155 { 156 data = 1; 157 break; 158 } 159 case 0xFF906F: //4 160 { 161 data = 1; 162 break; 163 } 164 case 0xFF629D: //5 165 { 166 data = 1; 167 break; 168 } 169 case 0xFFE01F: //6 170 { 171 data = 1; 172 break; 173 } 174 case 0xFF609F: //7 175 { 176 data = 1; 177 break; 178 } 179 case 0xFFA05F: //8 180 { 181 data = 1; 182 break; 183 } 184 default: 185 { 186 break; 187 } 188 } 189 190 if(results.decode_type != NEC) 191 { 192 data = -1; 193 } 194 195 return data; 196} 197 198void Serial_print() 199{ 200 Serial.print(results.decode_type); 201 Serial.print('\t'); 202 Serial.print(results.value, HEX); 203 Serial.print('\t'); 204 Serial.print(results.bits); 205 Serial.print('\t'); 206} 207

赤外線変換ソースコード

Arduino

1#include <IRremote.h> 2 3int Recvpin = 11; 4int Ledpin = 12; 5 6IRrecv irrecv(Recvpin); // create instance of 'irrecv' 7IRsend irsend; 8decode_results results; // create instance of 'decode_results' 9 10void setup() 11{ 12// Serial.begin(9600); 13// Serial.println("IR Receiver Button Decode"); 14 irrecv.enableIRIn(); // Start the receiver 15 pinMode(Ledpin, OUTPUT); 16} 17 18void loop() 19{ 20 unsigned long data = 0; 21 22 if(irrecv.decode(&results)) 23 { 24 data = translateIR(); 25 irrecv.resume(); 26 27 if(data != 0) 28 { 29 digitalWrite(Ledpin, HIGH); 30 irsend.sendNEC(data, 32); //D3pin only PWM 31 irrecv.enableIRIn(); 32 digitalWrite(Ledpin, LOW); 33 } 34 } 35} 36 37unsigned long translateIR() 38{ 39 unsigned long data = 0; 40 41 switch(results.value) 42 { 43 case 0xA90: //TV電源 44 { 45 data = 0xFF728D; 46 break; 47 } 48 case 0xA50: //TV入力切替 49 { 50 data = 0xFFEA15; 51 break; 52 } 53 case 0xA70: //決定 54 { 55 data = 0xFFC837; 56 break; 57 } 58 case 0x290: //消音 59 { 60 data = 0xFFB04F; 61 break; 62 } 63 case 0x490: //音量+ 64 { 65 data = 0xFF12ED; 66 break; 67 } 68 case 0xC90: //音量- 69 { 70 data = 0xFF926D; 71 break; 72 } 73 case 0x2F0: //十字↑ 74 { 75 data = 0xFF32CD; 76 break; 77 } 78//変換できなかった 79///////////////////////////////////////////////////////// 80 case 0xAF0: //十字↓ 81 { 82 data = 0xFF8A75; 83 break; 84 } 85 case 0x62E9: //戻る 86 { 87 data = 0xFFBA45; 88 break; 89 } 90 case 0x6D25: //番組表 91 { 92 data = 0xFF22DD; 93 break; 94 } 95 case 0x34E9: //番組情報 96 { 97 data = 0xFFA25D; 98 break; 99 } 100 case 0xAE9: //字幕 101 { 102 data = 0xFF38C7; 103 break; 104 } 105///////////////////////////////////////////////////////// 106 case 0x10: //1 107 { 108 data = 0xFF52AD; 109 break; 110 } 111 case 0x810: //2 112 { 113 data = 0xFFD02F; 114 break; 115 } 116 case 0x410: //3 117 { 118 data = 0xFF50AF; 119 break; 120 } 121 case 0xC10: //4 122 { 123 data = 0xFF906F; 124 break; 125 } 126 case 0x210: //5 127 { 128 data = 0xFF629D; 129 break; 130 } 131 case 0xA10: //6 132 { 133 data = 0xFFE01F; 134 break; 135 } 136 case 0x610: //7 137 { 138 data = 0xFF609F; 139 break; 140 } 141 case 0xE10: //8 142 { 143 data = 0xFFA05F; 144 break; 145 } 146 default: 147 { 148 // break; 149 return 0; 150 } 151 } 152 153 if((results.value != 0xFFFFFFFF) && (results.decode_type != -1)) 154 { 155// Serial_print(data); 156 } 157 158 return data; 159} 160 161void Serial_print(unsigned long data) 162{ 163 Serial.print(results.decode_type); 164 Serial.print('\t'); 165 Serial.print(results.value, HEX); 166 Serial.print('\t'); 167 Serial.print(results.bits); 168 Serial.print('\t'); 169 Serial.println(data, HEX); 170}

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

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

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

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

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

guest

回答1

0

ベストアンサー

前提を無視するなら、Arduinoをもう一台用意して送信受信それぞれ走らせるのが一番単純明快確実な方法だと思いますがどうでしょう? UNOやnanoの互換機なら1000円しないでしょ?
どうしても1台でやらないといけない理由があるのなら仕方ないのでIRemoteルーチンの内部を解析して送受同時動作可能か確認しましょう。もしタイマーを叩いていたりしているとすると、送受の同時動作は不安です。

余談ですが、スマホとかのCMOSやCCDカメラは赤外線に感度があるので、スマホのカメラで赤外線リモコン等をみると赤外線LEDが「光って」みえる、なんてのは知ってますか?


追記
IRremoteライブラリの中身を覗いてみました。
sendNEC()関数の先頭 (ir_NEC.cpp)

Arduino

1void IRsend::sendNEC (unsigned long data, int nbits) 2{ 3 // Set IR carrier frequency 4 enableIROut(38);

enableIROut()関数 (irSend.cpp)

Arduino

1void IRsend::enableIROut (int khz) 2{ 3#ifdef USE_SOFT_CARRIER 4 periodTime = (1000U + khz/2) / khz; // = 1000/khz + 1/2 = round(1000.0/khz) 5 periodOnTime = periodTime * DUTY_CYCLE / 100U - PULSE_CORRECTION; 6#endif 7 8 // Disable the Timer2 Interrupt (which is used for receiving IR) 9 TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt

enableIRIn()関数 (irRecv.cpp)

void IRrecv::enableIRIn ( ) { // Interrupt Service Routine - Fires every 50uS cli(); // Setup pulse clock timer interrupt // Prescale /8 (16M/8 = 0.5 microseconds per tick) // Therefore, the timer interval can range from 0.5 to 128 microseconds // Depending on the reset value (255 to 0) TIMER_CONFIG_NORMAL(); // Timer2 Overflow Interrupt Enable TIMER_ENABLE_INTR;

送信開始時にはタイマー割り込みを止めていて、
受信許可時にはタイマー割り込みを開始しています。
これより、
IRremoteライブラリをそのまま使っている限り、自分が送信した信号を自分で拾うことは出来ない、と言ってよさそうです。

ただし、この場合出来ないのは「受信」のはずであって、「送信できない」というのが観測できる事実だとすれば一致しないですね。

投稿2019/07/14 06:14

編集2019/07/14 09:55
thkana

総合スコア7629

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

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

Alyn

2019/07/14 06:19

Arduinoは1台しか持っていません… 赤外線変換コードでは送受信できて、赤外線送信検証コードでは送信できないのはなぜかなと
thkana

2019/07/14 06:54

> 1台しか持っていません そうだろうという予想もあって、もう一台用意して、と言っています。 もちろん、1人1Arduinoを貫く、というのならそれはそれですが、今回に限らずちょっと複雑なことを始めると1台で苦労するより2台あったほうが楽、ということもあるものです(苦労自体を楽しむケースもあるので、何が目的かによります)。 > 赤外線変換コードでは送受信できて、赤外線送信検証コードでは送信できないのはなぜかなと 二つのコードでそれぞれどういうふるまいがみられたか、というのはあなたの質問に明確には書かれていないので理解していません。 少なくとも、検証コードの方ではLEDを点灯するコードはないので、 > LEDが点灯したことから受信はできているので、送信ができていなかった のは検証コードではなく、したがって検証コードでは送信できない、ということは質問から読み取れませんでした。 それはともかく。 IRemoteライブラリでは送信した後 受信開始しなきゃいけないことになってますよね。変換コードの方では irsend.sendNEC(data, 32); //D3pin only PWM irrecv.enableIRIn(); とやっているところ。私も内部を解析したことがあるわけではありませんが、sendの関数に入ったところで即受信禁止になっている可能性は高いと思います。その場合、ライブラリをそのまま使っていては送信中は受信出来ない、ということになるでしょう。
Alyn

2019/07/14 10:06 編集

LEDはIRモジュールに付いてるLEDです。受信すると点灯するので送信できないというより正しく受信できてないが正しいと思います。 送信中は受信できないとなると赤外線変換コードで送受信できたのも合点がいきますね。 ありがとうございました。 Arduinoもう1台用意して検証しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問