2011年3月31日 星期四

2.1 發射紅外線訊號

實驗目的

練習用 IRRemote 函式庫發射紅外線訊號。在這個實驗裏,你將學習用 IRsend 物件發射紅外線訊號。

前提

在做這個實驗前,我假設:

  1. 你已經看過「IRRemote 紅外線遙控教學」一文,而且
  2. 也已經把 IRRemote 函式庫安裝起來了
材料
  • 麵包板 x 1
  • Arduino 主板 x 1
  • 發射波長為 940nm 的紅外線發射器 x 1
  • 按鈕 (pushbutton) x 1
  • 10k 歐姆電阻 x 1
  • 100 歐姆電阻 x 1
  • 單心線 x N
接線
  • 把紅外線發射器 (IR LED) 接到 pin 3,長腳 (陽極) 串接一顆 100 ohm 電阻接到 pin 3,短腳 (陰極) 接到 GND
  • 按鈕的一支腳接到 +5V,另一支腳接到 pin 4 同時接一個 10K 電阻連到 GND

image

注意!因為 IRRemote 函式庫限定使用 pin 3,所以你只能把紅外線發射器接到 pin 3,不能接到其它腳位。

程式

底下這支程式 (Example2.1.pde) 示範如何用 IRsend 物件發射紅外線訊號:

在按下按鈕的時候,程式就會發射一個 NEC 協定(NEC IR Protocol)的紅外線訊號,紅外線編碼為 0x4FB48B7,資料長度為 32 位元。

0x4FB48B7 是我電視遙控器 Power 鈕的紅外線編碼,有關如何取得遙控器的紅外線資料,請見「1.5 兩個取得遙控器紅外線資料的方法」一文。

如何用 IRsend 發射紅外線訊號

要發射紅外線訊號,只要三個步驟:

1) 引用 IRRemote 函式庫:

2) 建立一個 IRsend 的物件:

3) 呼叫對應紅外線協定的 send() 函式並傳入紅外線編碼與資料長度,就可以送出一個紅外線訊號:

IRRemote 函式庫支援 NEC, Sony SIRC, Philips RC5, Philips RC6, DISH, Sharp 這些紅外線協定,所以 IRsend 有下這幾個 send() 函式可用:

  • sendNEC(data, nbits)
  • sendSony(data, nbits)
  • sendRC5(data, nbits)
  • sendRC6(data, nbits)
  • sendDISH(data, nbits)
  • sendSharp(data, nbits), 及
  • sendRaw(buf[], len, hz) - 進階的函式,可指定頻率傳送指定的波形 (waveform)。
示範影片

底下這個影片示範用 Arduino 控制關電視機的開關:

用 Serial Port 控制紅外線的發射

如果你手上沒有按鈕 (Pushbutton),可以用底下這個版本的程式(Example2.1v2.pde):

這支程式會不斷地檢查 Serial Port,如果 Serial Port 上有資料進來,就會發射紅外線訊號,因此你只要打開 Serial Monitor,隨便輸入任何資料就可以測試紅外線的發射,。

動動腦
  1. 請找一個紅外線遙控器,電視、音響、手機、相機、投影機或是冷氣機的遙控器都可以,先取得遙控器任意一個按鈕的紅外線資料,然後再修改這個實驗的範例程式,用 Arduino 來控制你的影音設備。
  2. 閱讀「Arduino 筆記 – Lab8 使用光敏電阻控制 LED 的開關」一文,然後把按鈕換成光敏電阻,用光敏電阻來控制電視機。你的程式邏輯可以這樣寫: 當光敏電阻讀值有大幅度的變化時,就送出 Power 鈕紅外線訊號。
延伸閱讀

41 意見:

邵賢 提到...

哈摟~前輩您好!看到您分享的教學文章 非常的有收穫!~
想請教一下!假設紅外線IRRemote 函式庫部分假使我要使用的是日立的紅外線冷氣機遙控器,請問是否一樣能夠使用其他send fuction然後只改變紅外線編碼的部分,這樣行得通嗎??謝謝@@有說錯的地方請幫忙指點一下 感謝您!

Cooper Maa 提到...

讀者有收獲,我也感到高興。:)

你有用 IRRemote 解出冷氣機遙控器的 ir code 嗎?如果可以解出 ir code,理論上是可以用 send function 的。只不過,我發現大部份冷氣機遙控器的紅外線好像都比較複雜,不是每支都解得出說。

邵賢 提到...

哈摟~!!!首先感謝版主回應,本人測試過後,SAMPO冷氣機遙控器按不同Button有著不同的ir code也可以控制,但是日立冷氣遙控器如這:http://goods.ruten.com.tw/item/show?11090628847220 (圖片中RAR-2C1)按不同button經過觀察後發現ir code 都是一樣的,接過測試好像沒有辦法控制冷氣機!!不知道版主大大可否給點建議呢~謝謝喔@@
本人考慮過是否IRRemote當中無法解析日立冷氣機遙控器的訊號,不知道還有沒有其他函式庫能夠支援嗎?

Cooper Maa 提到...

「經過觀察後發現 ir code 都是一樣的」你是用 irremote library 觀察的嗎?如果 irremote 解不出來,也許可以試試看用 WinLIRC。接收器的話,只要弄條 audio plug 接到麥克風,然後供 5v 的電就可以了,簡單一點,5v 的電從 arduino 借過來用就行了。

邵賢 提到...

謝謝!版主回應!經本人測試過後,以及翻閱一些資料,請問WinLIRC是否也會有無法解析出來的遙控器,因為我測試過hitachi遙控器 畫面顯示這些訊息Press a button. Error reading signal; please try again.
有人說可能是遙控器過於複雜?請問版主是否有遇過這類的問題呢?謝謝

Cooper Maa 提到...

我也有遇到這樣的情形。,因為不是每支遙控器都會遵循常見的紅外線協定,有些廠商可能是自己編碼,波形 pattern 可能都是自己定義,這就比較麻煩了。

IRDA 提到...

所以並不是每一台冷氣機都可以解碼 和控制?
我測試用資訊家和NATIONAL冷氣機 都不能控制 而且距離不同解出來的碼也不一樣 很奇怪...

要改函式庫嗎? 還是有其他函式庫可以支援?
我用WinLIRC 一樣解不出來...

如果用這個指令--> sendRaw(buf[], len, hz) - 進階的函式,可指定頻率傳送指定的波形(waveform)。

我該怎麼使用?

Cooper Maa 提到...

@IRDA
冷氣機的紅外線編碼確實比較複雜
我試過 National 和日立的冷氣機遙控器,也是沒辦法成功解碼。

我沒用過 sendRaw(),不過 IRRemote 有範例可供參考,
請見 irtest2 這個 example。

IRDA 提到...

若先用示波器 量冷氣機發送的訊號

再用這個指令--> sendRaw(buf[], len, hz) - 進階的函式,可指定頻率傳送指定的波形(waveform)。
可以很金準發送一磨一樣的code嗎?

IRDA 提到...

剛好小弟明天要期末考 所以在這邊跟板大說聲抱歉!
晚點再動手 有心得 會跟板大討論

Cooper Maa 提到...

等你的好消息。:)

IRDA 提到...

剛剛研究了一下
參考範例 改了程式 sendRaw(buf[], len, hz)
不過一樣 冷氣機還是不動
不知道是不是我做錯了

IRDA 提到...

len 指的事buf的長度嗎?

Cooper Maa 提到...

len 是 rawbuf 的長度沒錯。

chinggo 提到...

前輩你好,我使用Mega ADK的版子利用pin 3
好像紅外線就送不出去了..

Cooper Maa 提到...

你好,我沒在 Mega ADK 上試過,沒發現這問題

如果是用 Mega ADK 的話,有兩個地方要注意
第 1 個是要改用 pin 9,不再是 pin 3
第 2 個是要修改 IRRemoteInt.h,因為 IRRemote 還不支援 Mega ADK,所以要把所有底下這行:

#if defined(__AVR_ATmega1280__)

改成這樣:

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

不確定有沒其它沒考慮到的事,試試看吧。

林廷廷 提到...

您好,我是剛接觸的初學者,當我收到紅外線編碼時,它無法解析是何種協定,這樣我還能用發射器去控制電視嗎?

Cooper Maa 提到...

Hi,

如果無法解析是何種協定,但有收到紅外線訊號的話,可能還是可以辦得到,要用 sendRaw)() 這個 method,我沒用過 sendRaw(),不過 IRRemote 有範例可供參考,請見 irtest2 這個 example

Cooper Maa 提到...

@Eric-Chen, 我在 Mega 2560 試過了,Mega ADK 也可以發射紅外線,不能用 pin 3 ,要改用 pin 9,詳情請參考這篇:
http://coopermaa2nd.blogspot.com/2012/04/irremote-atmega2560.html

comet 提到...

對於特殊的紅外線編碼,例如:冷氣遙控器上有LCD版的紅外線,可用IRremote Library解出raw data,只是要注意RAWBUF的大小,Library 原始只給76,把它設大一點,我自己調成150,可解panasonic的冷氣,解完之後,也成功發射了出去了。

從版主這邊學到不少,所以也小小回饋一下,供有需要的人參考試試。

Cooper Maa 提到...

@comet, 謝謝你的回饋與分享。

林廷廷 提到...

您好,請問有辦法讓紅外線的發射距離增長嗎?例如我拿著UNO就可以像用電視遙控器一樣,不用在靠很近按BUTTON

Cooper Maa 提到...

試試看用 2n3904 NPN 電晶體來驅動 IR LED

Unknown 提到...

想請教coopermaa大大
我家的TECO MW525BR9冷氣遙控器可用irremote解出來是NEC規格,但是開啟電源的按鈕按下去,晚上是9090040A,早上變成9890040A,關閉電源也是從8090000A變成8890000A,然後我用irsend送出這些數值都無法啟動或關閉冷氣,我有用手機的相機去看紅外線發射器,的確是有在閃爍送出訊號,所以我又用irtest那個範例去讀取raw值,但每次的32個數值都不一樣,請問是我做法有錯嗎?因為可以順利decode,照您的教學應該是可以運作,可以麻煩您指導個方向嗎?
我是按照這篇去操作的
http://coopermaa2nd.blogspot.tw/2012/04/irremote-atmega2560.html

ison 提到...

您好!看到您的教學文章 , "受益良多"
我也以Arduino nano試過是可以正常使用~
但想請教一下!假設我要使用ATtiny2313,請問要修改哪裡,才能夠使用??

Cooper Maa 提到...

ATtiny2313 可能有困難喔,因為它 Flash 只有 2KB,把 IRRemote 塞進去恐怕沒法子

如果是 ATtiny4313 還有機會,已經有個老外成功試出來囉:

http://ubiyubix.wordpress.com/2012/05/05/porting-the-arduino-irremote-library-to-the-attiny4313/

專題生 提到...

您好,我需要跟別人搭配一個介面,他們傳送訊號來給我發射,然後是傳什麼就發射什麼,請問這類程式碼該如何做修改

Cooper Maa 提到...

hi, 你可以參考一下 IRrecord 這範例,這個好像就是收到什麼就傳送什麼的 Playback 範例:

https://github.com/shirriff/Arduino-IRremote/blob/master/examples/IRrecord/IRrecord.ino

我沒試過,不知道可不可行,最近在忙別的事 :)

Unknown 提到...

嗨! 您好
我在您部落格上學到不少
非常感謝你
不過我在用IRremote時遇到很糟糕的情形
就是用了irsend.sendNEC(......)
之後,雖然訊息如期送出
但是會影響到其他的pin
我pin11的led只要當上面那個function結束之後
就會一直持續在一個奇怪的狀態
本來能讓他用pwm的方式漸層的明暗,現在就只會亮跟暗而已。整個爛掉了。
我也試圖把pin3換成的pin9了,結果只是其他pin出現別的問題而已,始終無法根治,不知道大大有沒有解,感恩。

Cooper Maa 提到...

@Unknown,
IRRemote 確實會影響 pin 11 的運作,這是因為 pin 3 跟 pin 11 共用 timer2 的關係,見這篇 http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html 的討論,Michael Gold 在 December 30, 2009 8:38 AM 有反應這個問題,他建議改用其它腳位做 PWM

如果你改用 pin 9,可能會影響 pin 10

專題生 提到...

我想請問這行的意思 if (Serial.read() != -1

Cooper Maa 提到...

這裏有 Serial.read() 的函式說明:
http://arduino.cc/en/Serial/Read

傳回值這段是這麼說的:

Returns
the first byte of incoming serial data available (or -1 if no data is available) - int


所以 Serial.read() 回傳 -1 就代表沒有收到資料囉

ison 提到...

你好:

請問~可以在程式裡加上(睡眠程式)來達到更省電的效果嗎?如果可以的話,要程式怎麼寫??

Cooper Maa 提到...

Arduino 可以進入睡眠模式達到省電的效果
這方面我沒有實戰經驗,不過網路上有很多資料,不妨參考一下:

例如底下這個,不過它的喚醒方法好像只能靠外部中斷:
http://arduino.cc/playground/Learning/ArduinoSleepCode

還有下面這個,這個就厲害了,我沒細看,但是似乎可以做到睡眠時間的控制,還有可以指定要關掉哪些硬體模組,比如 ADC, Timer, SPI, BOD 等等的:
http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

等你研究出來後,分享一下吧!:)
Luck for you!

ison 提到...

謝謝~我再研究看看,其實我只是一個菜鳥= =.

Cooper Maa 提到...

不客氣,加油啊。

wola 提到...

因為我完全還沒接觸過Arduino
所以想請教一個非常基本的問題

寫好程式後
有辦法將這個程式上傳至Arduino中
然後不用接電腦,單純直接使用Arduino嗎?(電力用電池來供給)

因為我想要DIY做一組很簡單的紅外線發射器來控制相機的快門達成定時攝影的功能,簡單弄一個按鈕按下後就會自動repeat 送出我要的紅外線訊號

不知道不接電腦是否能達成呢?
謝謝

如果可以的話,我就要來購買Uno來玩了^^

Cooper Maa 提到...

可以的,程式上傳到 Arduino 後,你就可以拔掉 USB cable 直接以電池或是 DC Adapter 供電給 Arduino。請參考這篇:

http://coopermaa2nd.blogspot.tw/2011/01/9v-arduino.html

歡迎加入 Arduino 的世界啊! ^o^

wola 提到...

非常感謝
這樣我就可以開始玩我的新玩具了^_^

Unknown 提到...

請問我要接2n3904放大紅外線訊號該怎麼接呢?
謝謝

Cooper Maa 提到...

可以參考底下的電路設計接 2n3904 放大紅外線訊號 (圖中 Q1 即 2n3904):

http://wgrube-electronics.blogspot.tw/2011_08_01_archive.html