Ameba Arduino: [RTL8195] [RTL8710] 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訊號。
一個完整的紅外線發設器的訊號如下圖,它分成幾個階段:
1

  1. 一開始它會送起始訊號,它分成Start high與Start low,其中Start high的訊號為PWM訊號,頻率為38K。Start low則是一般的數位輸出,只要不是PWM訊號即可,一般為了省電會將訊號置於0V。
  2. 接著會送資料,依序將資料以byte為單位送出,送的順序為LSB(Least Significant Bit) 至MSB(Most Significant Bit)。其中bit 1的表示方式,先打出長度560us的PWM訊號,再停止1.69ms。而bit 0的表示方式,打出長度560us的PWM訊號,再停止560us。可以看到0跟1的表示方式差別只在於後面的停止長度。
  3. 資料送完之後,送一個bit 1當作Stop bit,然後不再送訊號。

接收端的部份,因為已經經過解調器,所以原本是PWM訊號的地方,都被轉成一般的數位輸入:
2
而原本不是PWM訊號的地方,都被置於3.3V ( or 5V )的地方。

紅外線接收範例

Ameba在實作上,使用了一根GPIO Interrupt與硬體的Timer 4。範例請打開 “File” -> “Examples” -> “AmebaIRSendRecv” -> “recv”
在接收器的部份,這個範例裡使用Grove Infrared Receiver,如果你使用其它的紅外線接收器也類似。一般只會用到三根Pin:一根VCC(接3.3V),一根GND,一根RX。範例裡RX接到D3 (具有GPIO Interrupt),接法如下:
3

RTL8710,接法如下:
3

然後編譯程式並上傳到Ameba,完成之後按Reset按鍵。
如果你手邊有NEC規格的遙控器,就可以試試看是否有接收到訊息。如果沒有的話,也可以參考紅外線發射的範例,並設定另一塊Ameba互傳。
如果有接收到訊息,那麼會在Serial Monitor裡看到解析的結果
4

紅外線傳送範例

紅外線傳送器一般只有2根Pin,就像是一般的LED燈泡,只不過發出的是紅外線燈光。
Grove的Infrared Emitter有3根Pin:一根VCC,一根GND,一根TX。實際上也可以只接GND與TX。
Ameba在傳送上,為了要及時地送出38K的訊號,在實作上使用了一組UART,並且用UART的TX將訊號送出去。也因為用了一組UART,當使用Ameba傳送紅外線,D0 (UART RX)就無法使用。接法如下:
5這樣接會有額外的耗電,因為UART的TX平常準位(Level)在3.3V,造成平常紅外線的登是亮的,於是我們改變接法,將Ameba的UART TX接在傳送器的GND,並且將傳送器的訊號線接在3.3V上:
6

RTL8710接線圖如下:
6

這樣的話,不傳送的時候,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,範例裡使用的是D3
    IR.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,範例中使用38KHz
    IR.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….: 資料內容