MICROPYTHON ESP32 中对necri 红外解码驱动的源码解析

2020/06 28 16:06
































































































































































MICROPYTHON ESP32 中对necri 红外解码驱动的源码解析
#引脚输入信号 做 红外捕获解码
#知识点
# 1.红外信号协议入门
# 2.PIN引脚输入信号高低电平触发处理
# 3.电平信号分析
# 4.信号解码
#5. py中 数据处理 优化 移位除法 插入数据 8位二进制255 求时间差值
# 实时数据处理 避免不必要的计算,存储,打印。



# Connect HX1838B receiver to 35
# (That's a 38kHz IR receiver, as shipped on taobao)
#
#
# Created by Zhao Tang  2018-03-13 Initial draft
#    Matt Page / tju.tangzhao@gmail.com

# Difference with the version for pyboard(Nano):
# time module (utime module on pyboard)
# pin=35(pyboard can only use the form like: pin=pyb.Pin.board.Y10 and number is not supported)

# Usage:
#    def nec_cb(nec, a, c, r)
#        print(a, c, r)             # Address, Command, Repeat
#
#    from necir import NecIr
#    nec = NecIr()
#    nec.callback(nec_cb)
#
#
#





from machine import Pin
import time


class NecIr:
    def __init__(self, pin=35):
        self._ic_start = 0
        self._ic_last = time.ticks_us()#初始化的时候获取一个初始时间
        self._ic_width = 0#信号位宽
        self._sr = [0, 0, 0, 0] 










        self._rst()#重置数据缓存区
        self._address = 0
        self._command = 0
        self._cb = None
        self._ic_pin = Pin(pin, Pin.IN) #初始化pin 引脚 输入模式
        self._ic_pin.irq(trigger=Pin.IRQ_RISING, handler=self._ic_cb)#配置IRQ 中断 高电平触发_ic_cb
        self._id = 0#计数器

    def _rst(self):
        self._sr[0] 
 = 0
        self._sr[1] 
 = 0
        self._sr[2] 
 = 0
        self._sr[3] 




 = 0
        self._sc = 0
        self._sb = 0

    def _bit(self, v):#解码模块
        self._sr[self._sb]  = (self._sr[self._sb] 








 >> 1) + v
        #每次识别到高低电平 进行处理 0x80=128   /2 +v
        #每次获取到数据后右移动一位。第八位1是128 右移动一位1是64,11111111
        #128 64 32 16 8 4 2 1
        self._sc = self._sc + 1
        if (self._sc > 7):# 累积到8个后处理
            self._sc = 0
            self._sb = self._sb + 1
            if (self._sb > 3):# 4组二进制之后解码
                if ((self._sr[0]  ^ self._sr[1]  ^ self._sr[2]  ^ self._sr[3] 
) == 0):#异或校验2组数据完整性 根据红外协议来讲 没问题pass 有问题清空重新来过
                    self._address = self._sr[0] 

                    self._command = self._sr[2] 




















                    if (self._cb):#执行回调函数
                        self._cb(self, self._address, self._command, False)  # Contains the address & command
                self._rst()#重置

    def _ic_cb(self, pin):#信号处理
        ''' 这里的信号处理要根据红外编码说起
        数据
        信号0 低电平0.56  高0.56  总长1.125ms
        信号1 低0.56  高0.56     总长 2.25ms
        引导位忽略 引导位时长大于高低电平
        32位,8位系统 8位系统,8位数据 8位数据反码
        '''
        self._ic_start = time.ticks_us()#时间
        icw = time.ticks_diff(self._ic_start, self._ic_last)#获取时间差 得到信号宽
        self._ic_last = self._ic_start# 时间传递,方便下次计算
        self._ic_width = icw#信号位宽
        self._id += 1
        '''通过对 每一次 高低信号 icw 时间长度来测算 数据指令'''
        if (icw > 5500):#一个高低信号 大于 5.5ms   5ms 起始码未知
            # print('[gap] 

















')  # gap in transmission
            pass
        elif (icw > 4000):#一个高低信号 大于 4ms  4.5ms 是发送结束 和起始
            # print('IR start')
            self._rst()
        elif (icw > 2500):  # Repeat command#一个高低信号 大于 2.5ms 结束码2.5ms   收到 结束信号直接结束
            # print('IR repeat')
            if (self._cb):
                self._cb(self, self._address, self._command, True)
        elif (icw > 1500):#一个高低信号 大于 1.5ms     有效信号处理
            self._bit(0x80)  # High bit
            # print('High bit')
        else:
            self._bit(0x00)  # Low bit#低8位  小于 1.5ms的 有效信号处理
            # print('Low bit')
        # print(self._id, self._ic_width)

    def callback(self, fn):# 回调函数
        self._cb = fn

--转载请注明: http://91o.cc/micropython-esp32-%e4%b8%ad%e5%af%b9necri-%e7%ba%a2%e5%a4%96%e8%a7%a3%e7%a0%81%e9%a9%b1%e5%8a%a8%e7%9a%84%e6%ba%90%e7%a0%81%e8%a7%a3%e6%9e%90/