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的函式庫

    • 下載函式庫 https://github.com/markszabo/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);

    • }