IR - 使用紅外線傳送、接收器
材料準備
- Ameba x 1
- Grove – Infrared Receiver x 1
- Grove – Infrared Emitter x 1
原理
紅外線是不可見光,波長在770nm~1mm之間,常見於家中的遙控器。
一般的紅外線傳送端與接收端需要事先規範好傳送的頻率,常見的規範有NEC, Philips RC5, RC6, RCMM, Toshiba, Sharp, JVC, Sony SIRC……。其中NEC是家電常用的規範,它使用38K Hz的頻率。
紅外線接收器裡面有解調器(demodulator),它的訊號線平常會輸出數位訊號3.3V (or 5V)。接收到一定頻率的紅外線訊號時,它的數位輸出會變成0V。如果不是這個頻率的紅外線,像是手上拿著紅外線燈開關個幾次,紅外線接收器不會對這有反應,以避免雜訊。
紅外線發射器則要傳送對應頻率的訊號,一般來說是PWM訊號。
一個完整的紅外線發設器的訊號如下圖,它分成幾個階段:
- 一開始它會送起始訊號,它分成Start high與Start low,其中Start high的訊號為PWM訊號,頻率為38K。Start low則是一般的數位輸出,只要不是PWM訊號即可,一般為了省電會將訊號置於0V。
- 接著會送資料,依序將資料以byte為單位送出,送的順序為LSB(Least Significant Bit) 至MSB(Most Significant Bit)。其中bit 1的表示方式,先打出長度560us的PWM訊號,再停止1.69ms。而bit 0的表示方式,打出長度560us的PWM訊號,再停止560us。可以看到0跟1的表示方式差別只在於後面的停止長度。
- 資料送完之後,送一個bit 1當作Stop bit,然後不再送訊號。
接收端的部份,因為已經經過解調器,所以原本是PWM訊號的地方,都被轉成一般的數位輸入:
而原本不是PWM訊號的地方,都被置於3.3V ( or 5V )的地方。
紅外線接收範例
在接收器的部份,這個範例裡使用Grove Infrared Receiver,如果你使用其它的紅外線接收器也類似。一般只會用到三根Pin:一根VCC(接3.3V),一根GND,一根RX。範例裡RX接到D3 (具有GPIO Interrupt),接法如下:
![3](https://www.amebaiot.com/wp-content/uploads/2016/04/3.png)
RTL8710,接法如下:
然後編譯程式並上傳到Ameba,完成之後按Reset按鍵。
如果你手邊有NEC規格的遙控器,就可以試試看是否有接收到訊息。如果沒有的話,也可以參考紅外線發射的範例,並設定另一塊Ameba互傳。
如果有接收到訊息,那麼會在Serial Monitor裡看到解析的結果
紅外線傳送範例
Grove的Infrared Emitter有3根Pin:一根VCC,一根GND,一根TX。實際上也可以只接GND與TX。
Ameba在傳送上,為了要及時地送出38K的訊號,在實作上使用了一組UART,並且用UART的TX將訊號送出去。也因為用了一組UART,當使用Ameba傳送紅外線,D0 (UART RX)就無法使用。接法如下:
![5](https://www.amebaiot.com/wp-content/uploads/2016/04/5.png)
![6](https://www.amebaiot.com/wp-content/uploads/2016/04/6.png)
RTL8710接線圖如下:
這樣的話,不傳送的時候,GND的PIN與TX的PIN都在3.3V,電壓差為0,燈就不會亮。
最後打開範例, “File” -> “Examples” -> “AmebaIRSendRecv” -> “send”,編譯並上傳到Ameba之後,按下Reset按鈕。
範例裡會每兩秒送一次訊號,可以與前一個紅外線接收的範例對測即可。
程式碼說明
這裡的API參考Grove IR Send Recv的library,原始的程式碼可以參考這裡,Ameba雖然API一樣,但實作上與Arduino不同。
- 紅外線接收
首先接收要先設定要在哪根PIN上,它需要使用GPIO Interrupt,所以只能選有GPIO Interrupt的PIN,範例裡使用的是D3IR.Init(pinRecv)
在Loop裡則是一直檢查是否有訊號進來IR.IsDta()
如果有訊號進來,就將結果放進使用者自行宣告的buffer裡IR.Recv(dta)
這個buffer的資料格式如下:- Byte 0: 整包資料的長度
- Byte 1: Start high的長度,單位為50us
- Byte 2: Start low的長度,單位為50us
- Byte 3: 資料如果是bit 1,不打PWM的長度,單位是50us
- Byte 4: 資料如果是bit 0,不打PWM的長度,單位是50us
- Byte 5….: 傳送的資料
- 紅外線傳送
傳送的部份只需要呼叫Send,第一個參數是資料內容,第二個參數是訊號頻率,單位是1K,範例中使用38KHzIR.Send(dtaSend, 38)
資料內容的格式如下:- Byte 0: 整包資料的長度
- Byte 1: Start high的長度,單位為50us
- Byte 2: Start low的長度,單位為50us
- Byte 3: 資料如果是bit 1,不打PWM的長度,單位是50us
- Byte 4: 資料如果是bit 0,不打PWM的長度,單位是50us
- Byte 5: 資料的長度
- Byte 6….: 資料內容