01紅外線接收及發射之使用
(2017/07/23)
一直想利用DIFI來進行物聯網之應用,如利用它來開關冷氣或電視之類,剛好DIFI上有內建紅外線接收器及發射器,因此進行此一專題的研究!
參考資料:新DiFi第17課紅外線遙控(機器人)
一、環境建置:
同之前「15-TUNIOT+NodeMCU初體驗」的方式來建立NodeMCU(也是用ESP8266)的建置環境
打開ARDUINO軟體,檔案>>偏好設定,在下方額外的開發板管理員網址:輸入http://arduino.esp8266.com/stable/package_esp8266com_index.json
接著到工具>>開發板>>開發板管理員
拉到最下一欄會多一項ESP8266,需在欄內點一下才會出現安裝訊息
安裝好後會顯示INSTALLED
接下來到工具>>開發板>>選 NodeMCU
取得IRremoteESP8266的函式庫
Click "Download ZIP"
Extract the downloaded zip file
Rename the extracted folder to "IRremoteESP8266"
Move this folder to your libraries directory (under windows: Arduino\libraries)
Restart your Arduino ide
Check out the examples
二、測試範例程式:
先把線接好
IR_R(接收) 接 IO14
IR_E(發送) 接 IO4
開啟範例程式 IRrecvDemo 取得遙控器各按鍵的「碼」
將程式上傳後,利用常見的KEYES遙控器來測試
上傳前要先確定板子及序列埠有沒有正確設定
可以把這遙控器各按鍵的解碼找出來,如下:
0,1,2,3,4,5,6,7,8,9,#,*,向上,向左,OK,向右,向下
{"ff4ab5","ff6897","ff9867","ffb04f","ff30cf","ff18e7","ff7a85","ff10ef","ff38c7","ff5aa5","ff52ad","ff42bd","ff629d","ff22dd","ff02fd","ffc23d","ffa857"};
其實除了這組解碼外,有時還會出現另一組解碼,如上圖按0及按#所出現的解碼
為再精確得到解碼資料,再開啟另一個範例程式 IRrecvDumpV2
下圖是利用NEC的編碼方式,得到一組編碼
下圖同樣按1,卻呈現是UNKNOWN的編碼格式,當然得到另一組碼
所以,同一個鍵,有時會出現不同的解碼!
所以可利用上面的程式,取得你手中各種遙控器的解碼,包括電視、冷氣等等
開啟範例程式 IRsendDemo 來發送剛取得遙控器的「碼」,如果有NEC格式的編碼更好
三、利用DIFI的紅外線【發射器】來遙控電視:
利用上面 IRrecvDumpV2 程式取得我家電視(Zinwell)的遙控器的按鍵編碼資料
電源按鍵:Encoding : NEC、Code : 430218E7 (32 bits)
頻道 + :Encoding : NEC、Code : 4302D827 (32 bits)
頻道 - :Encoding : NEC、Code : 4302F00F (32 bits)
利用 IRsendDemo來修改程式,讓我們在【序列埠監控視窗】輸入1,則可以開啟或關閉電視:輸入2,則增加頻道數(往上一台);輸入3,則減少頻道數(往下一台)。完整程式如下:
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
char val;
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2) //發射器接在pin4(D2)
void setup() {
irsend.begin();
// Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY); //原始程式,但出問題,改成下一行的方式就可以了
Serial.begin(115200);
}
void loop() {
if(Serial.available()){
val = Serial.read();
if ( val == '1'){ //在序列埠監控視窗下輸入1,開啟電視或關閉電視
Serial.println("NEC");
irsend.sendNEC(0x430218E7, 32);
delay(2000);
}
if ( val == '2'){ //在序列埠監控視窗下輸入2時,頻道數增加一
Serial.println("NEC");
irsend.sendNEC(0x4302D827, 32);
delay(2000);
}
if ( val == '3'){ //在序列埠監控視窗下輸入3,頻道數減少一
Serial.println("NEC");
irsend.sendNEC(0x4302F00F, 32);
delay(2000);
}
}
}
大家可以針對自己的需要來控制想控制的電器(如電視、冷氣等)
四、利用DIFI的紅外線【接收器】來控制DIFI上的元件:
利用上面 IRrecvDemo 程式來修改
但以下有一些重要指令先認識一下
When specific buttons are pressed, you can use the incoming values to do something else in your code, for example turn on and off a motor or LED.
The results from each button press can be found by calling the value() method:
COPY CODE
results.value
You can print the values to the terminal window:
COPY CODE
Serial.println(results.value, HEX); //prints the hex value a a button press
Or you might need read the values to run a conditional statement:
COPY CODE
if(irrecv.decode(&results)) //this checks to see if a code has been received { if(results.value == 0xC284) //if the button press equals the hex value 0xC284 { //do something useful here } irrecv.resume(); //receive the next value }
程式如下:(當我按KEYES遙控器的1時,會亮綠燈;當按2時,會亮紅燈,當按3時,兩燈都滅掉)
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU //接收器接在pin14(D5),若影響藍燈,可改變到其他腳位
// board).
uint16_t RECV_PIN = 14;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
pinMode(13, OUTPUT); //綠燈
pinMode(12, OUTPUT); //紅燈
Serial.begin(115200);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
if (results.value == 0xff6897) { //按1鍵時
Serial.println("1");
digitalWrite(13,HIGH);
digitalWrite(12,LOW);
}
if (results.value == 0xff9867) { //按2鍵時
Serial.println("2");
digitalWrite(13,LOW);
digitalWrite(12,HIGH);
}
if (results.value == 0xffb04f) { //按3鍵時
Serial.println("3");
digitalWrite(13,LOW);
digitalWrite(12,LOW);
}
irrecv.resume(); // Receive the next value
}
delay(100);
}
結果
五、將上面兩個例子做一個結合(利用KEYES遙控器來控制電視):
程式如下:
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include <IRsend.h>
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU
// board).
uint16_t RECV_PIN = 14;
IRsend irsend(4); // An IR LED is controlled by GPIO pin 4 (D2) //發射器接在pin4(D2)
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
irsend.begin();
Serial.begin(115200);
irrecv.enableIRIn(); // Start the receiver
}
void loop() {
if (irrecv.decode(&results)) {
if (results.value == 0xff6897) {
// Serial.println("NEC");
irsend.sendNEC(0x430218E7, 32);
delay(2000);
}
if (results.value == 0xff9867) {
// Serial.println("NEC");
irsend.sendNEC(0x4302D827, 32);
delay(2000);
}
if (results.value == 0xffb04f) {
// Serial.println("NEC");
irsend.sendNEC(0x4302F00F, 32);
delay(2000);
}
irrecv.resume(); // Receive the next value
}
delay(100);
}