NEC Protocol
The NEC IR transmission protocol uses pulse distance encoding of the message bits. Each pulse burst (mark – RC transmitter ON) is 562.5µs in length, at a carrier frequency of 38kHz (26.3µs). Logical bits are transmitted as follows:
Logical ‘0’ – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
Logical ‘1’ – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
翻譯:
NEC 紅外傳輸協定是通過控制脈沖寬度實作資訊位傳送,每個脈沖高電平(标注:RC發射器開啟)的寬度為562.5微秒,通過38KHz的負載波發送出去。各個邏輯位按如下方式傳送:
邏輯“0”–一個562.5微秒高電平脈沖後緊跟一個562.5微秒低電平脈沖,總傳輸時間為1.125毫秒。
邏輯“1”–一個562.5微秒高電平脈沖後緊跟一個1.6875毫秒低電平脈沖,總傳輸時間為2.25毫秒。

When transmitting or receiving remote control codes using the NEC IR transmission protocol, the WB_IRRC performs optimally when the carrier frequency (used for modulation/demodulation) is set to 38.222kHz.
When a key is pressed on the remote controller, the message transmitted consists of the following, in order:
■ a 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
■ a 4.5ms space
■ the 8-bit address for the receiving device
■ the 8-bit logical inverse of the address
■ the 8-bit command
■ the 8-bit logical inverse of the command
■ a final 562.5µs pulse burst to signify the end of message transmission.
The four bytes of data bits are each sent least significant bit first. Figure 1 illustrates the format of an NEC IR transmission frame, for an address of 00h (00000000b) and a command of ADh (10101101b).
翻譯:
當使用NEC IR傳輸協定發送或接收遠端控制代碼時,當載波頻率(用于調制/解調)被設定為38.222kHz時,使用WB_IRRC效果最佳。
當在遙控器上按下一個鍵時,發送的消息由以下部分組成,順序如下:
■ 一個9ms的高電平引導脈沖(脈沖寬度為邏輯資料位的16倍)
■ 一個4.5ms的低電平
■ 8位裝置位址
■ 8位裝置位址反碼
■ 8位指令
■ 8位指令反碼
■ 最後以一個562.5微秒高電平脈沖表示資訊傳輸結束。
這四個位元組的資料位都是先發送最低有效位,圖1說明了位址為00h (00000000b)和指令為ADh (10101101b)的NEC IR傳輸幀的格式。
Figure 1. Example message frame using the NEC IR transmission protocol.
Notice from Figure 1 that it takes:
■ 27ms to transmit both the 16 bits for the address (address + inverse) and the 16 bits for the command (command + inverse). This comes from each of the 16 bit blocks ultimately containing eight '0’s and eight '1’s - giving (8 * 1.125ms) + (8 * 2.25ms).
■ 67.5ms to fully transmit the message frame (discounting the final 562.5µs pulse burst that signifies the end of message).
翻譯:
圖1所示,例子中的資訊幀使用NEC IR傳輸協定。
從圖1中可以注意到:
■ 27毫秒内傳輸了16位位址(位址碼+位址反碼)和16位指令(指令碼+指令反碼)。這樣可以知道每個16位資訊塊最終包含8個 '0’位和8個 '1’位—得出(8 * 1.125ms) + (8 * 2.25ms)。
■ 一個消息幀長度為67.5毫秒(扣除表示消息結束的最後562.5微秒高電平脈沖時間)。
REPEAT CODES
If the key on the remote controller is kept depressed, a repeat code will be issued, typically around 40ms after the pulse burst that signified the end of the message. A repeat code will continue to be sent out at 108ms intervals, until the key is finally released. The repeat code consists of the following, in order:
■ a 9ms leading pulse burst
■ a 2.25ms space
■ a 562.5µs pulse burst to mark the end of the space (and hence end of the transmitted repeat code).
翻譯:
如果遙控器上的按鍵一直按下,一個重複代碼就會被發出,通常是在消息結束脈沖發射40毫秒之後。重複代碼将繼續以108ms的間隔發送,直到按鍵最終被釋放。重複代碼由以下部分組成,順序如下:
■ 一個9毫秒高電平引導脈沖
■ 一個2.25毫秒低電平脈沖
■ 一個562.5微秒高電平脈沖結束标志(結束了重複碼傳輸)。
Figure 2 illustrates the transmission of two repeat codes after an initial message frame is sent.
翻譯:
圖2說明了發送初始消息幀後兩個重複碼的傳輸。
Figure 2. Example repeat codes sent for a key held down on the transmitting remote controller.
翻譯:
圖2為紅外遙發射器一個按鍵一直被按下發送重複碼的例子。
樹莓派python示例代碼:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import time
ERROR = 0xFE
PIN = 18 #定義紅外接收器引腳
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIN, GPIO.IN, GPIO.PUD_UP) #設定紅外接收引腳為上拉模式
def getKey():
byte = [0, 0, 0, 0]
if IRStart() == False: #判斷紅外引導脈沖
time.sleep(0.11) # One message frame lasts 108 ms.
return ERROR
else:
for i in range(0, 4):
byte[i] = getByte() #接收32位紅外資料(位址、位址反碼、資料、資料反碼)
if byte[0] + byte[1] == 0xff and byte[2] + byte[3] == 0xff: #校驗接收資料是否正确
return byte[2]
else:
return ERROR
#return byte[2]
def IRStart(): #判斷紅外引導脈沖
timeFallingEdge = [0, 0]
timeRisingEdge = 0
timeSpan = [0, 0]
#通過脈沖上升沿和下降沿讀取脈沖時間
GPIO.wait_for_edge(PIN, GPIO.FALLING)
timeFallingEdge[0] = time.time()
GPIO.wait_for_edge(PIN, GPIO.RISING)
timeRisingEdge = time.time()
GPIO.wait_for_edge(PIN, GPIO.FALLING)
timeFallingEdge[1] = time.time()
timeSpan[0] = timeRisingEdge - timeFallingEdge[0] #第一個脈沖時間
timeSpan[1] = timeFallingEdge[1] - timeRisingEdge #第二個脈沖時間
if timeSpan[0] > 0.0085 and \ #判斷第一個和第二個脈沖是否是紅外引導脈沖
timeSpan[0] < 0.0095 and \
timeSpan[1] > 0.004 and \
timeSpan[1] < 0.005:
return True
else:
return False
def getByte(): #接收32位紅外資料(位址、位址反碼、資料、資料反碼)
byte = 0
timeRisingEdge = 0
timeFallingEdge = 0
timeSpan = 0
for i in range(0, 8):
#通過脈沖上升沿和下降沿讀取脈沖時間
GPIO.wait_for_edge(PIN, GPIO.RISING)
timeRisingEdge = time.time()
GPIO.wait_for_edge(PIN, GPIO.FALLING)
timeFallingEdge = time.time()
timeSpan = timeFallingEdge - timeRisingEdge #讀取脈沖時間
if timeSpan > 0.0016 and timeSpan < 0.0018: #判斷脈沖是否為代表1
byte |= 1 << i
return byte
print('IRM Test Start ...')
try:
while True:
key = getKey() #讀取紅外脈沖
if(key != ERROR): #列印紅外脈沖值
print("Get the key: 0x%02x" %key)
except KeyboardInterrupt:
GPIO.cleanup()
end!