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
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).
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).
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).
Figure 2 illustrates the transmission of two repeat codes after an initial message frame is sent.
Figure 2. Example repeat codes sent for a key held down on the transmitting remote controller.
树莓派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()