micropython esp8266 红外控制小车


简述

使用ESP8266+micropython+红外遥控模块+接收头HX1838(NEC编码)实现简单红外遥控小车。


效果

ESP8266 Micropython红外小车

在这里插入图片描述


代码

红外解码参考代码链接

boot.py

# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import gc
import os
#import webrepl
#webrepl.start()
gc.collect()

main.py

# from machine import Pin
# import configs
import os
import machine
import utime
import micropython
import ujson
from machine import Pin, PWM
micropython.alloc_emergency_exception_buf(100)

'''
无重复:
[9047, 4488, 554, 573, 558, 626, 556, 599, 558, 598, 558, 599, 557, 600, 532, 625, 532, 624, 558, 1672, 582, 1624, 554, 1698, 534, 1693, 533, 1697, 558, 1648, 555, 1696, 559, 1670, 557, 1671, 558, 598, 559, 1670, 558, 599, 582, 550, 582, 598, 559, 1671, 532, 623, 557, 600, 586, 1614, 562, 624, 557, 1645, 584, 1672, 558, 1671, 559, 573, 557, 1696, 557]
有重复
[9072, 4492, 535, 601, 535, 600, 581, 571, 588, 596, 559, 572, 586, 596, 535, 622, 534, 597, 586, 1669, 581, 1669, 535, 1696, 585, 1644, 534, 1696, 559, 1670, 534, 1696, 558, 1673, 559, 1645, 610, 572, 560, 1670, 534, 629, 554, 570, 587, 573, 558, 1696, 559, 598, 533, 624, 558, 1671, 533, 623, 560, 1643, 588, 1642, 561, 1696, 533, 623, 560, 1671, 559, 39230, 9049, 2246, 583, 95490, 9027, 2265, 534, 95509, 9023, 2268, 559, 95482, 9014, 2269, 533, 95514, 9019, 2268, 585, 95443, 9041, 2268, 559, 95467, 9043, 2271, 531, 95495, 9043, 2247, 581, 95490, 9020, 2243, 559, 95517, 9043, 2246, 558, 95492, 9042, 2244, 559, 95492, 9017, 2268, 534, 
95490, 9046, 2269, 537, 95516, 9041, 2243, 535, 95517, 9089, 2152, 579, 95489, 9044, 2244, 585, 95492, 9025, 2269, 585]
'''

class IR(object):
    CODE = {
    
    162: "1", 98: "2", 226: "3", 34: "4", 2: "5", 194: "6", 224: "7", 168: "8", 144: "9",
            152: "0", 104: "*", 176: "#", 24: "up", 74: "down", 16: "left", 90: "right", 56: "ok"}

    def __init__(self, gpioNum):
        self.irRecv = machine.Pin(gpioNum, machine.Pin.IN, machine.Pin.PULL_UP)
        self.irRecv.irq(
             trigger=machine.Pin.IRQ_RISING | machine.Pin.IRQ_FALLING,
             handler=self.__logHandler)

        self.ir_step = 0
        self.ir_count = 0
        self.buf64 = [0 for i in range(64)]
        self.recived_ok = False
        self.cmd = None
        self.cmd_last = None
        self.repeat = 0
        self.repeat_last = None
        self.t_ok = None
        self.t_ok_last = None
        self.start = 0
        self.start_last = 0        
        self.changed = False

    def __logHandler(self, source):
        thisComeInTime = utime.ticks_us()

        # 更新时间
        curtime = utime.ticks_diff(thisComeInTime, self.start)
        self.start = thisComeInTime
        

        if curtime >= 8500 and curtime <= 9500:
            self.ir_step = 1
            return

        if self.ir_step == 1:
            if curtime >= 4000 and curtime <= 5000:
                self.ir_step = 2
                self.recived_ok = False
                self.ir_count = 0
                self.repeat = 0
            elif curtime >= 2000 and curtime <= 3000:  # 长按重复接收
                self.ir_step = 3
                self.repeat += 1

        elif self.ir_step == 2:  # 接收4个字节
            self.buf64[self.ir_count] = curtime
            self.ir_count += 1
            if self.ir_count >= 64:
                self.recived_ok = True
                self.t_ok = self.start #记录最后ok的时间
                self.ir_step = 0

        elif self.ir_step == 3:  # 重复
            if curtime >= 500 and curtime <= 650:
                self.repeat += 1

        # elif self.ir_step == 4:  # 结束码,若果没有结束码有可能收到重复码再从step=1开始
        #     if curtime >= 500 and curtime <= 650:
        #         self.ir_step = 0

    def __check_cmd(self):
        byte4 = 0
        for i in range(32):
            x = i * 2
            t = self.buf64[x] + self.buf64[x+1]
            byte4 <<= 1
            if t >= 1800 and t <= 2800:
                byte4 += 1
        user_code_hi = (byte4 & 0xff000000) >> 24
        user_code_lo = (byte4 & 0x00ff0000) >> 16
        data_code = (byte4 & 0x0000ff00) >> 8
        data_code_r = byte4 & 0x000000ff
        self.cmd = data_code

    def scan(self):        
        # 接收到数据
        if self.recived_ok:
            self.__check_cmd()
            self.recived_ok = False
            
        #数据有变化
        if self.cmd != self.cmd_last or self.repeat != self.repeat_last or self.t_ok != self.t_ok_last:
            self.changed = True
        else:
            self.changed = False

        #更新
        self.cmd_last = self.cmd
        self.repeat_last = self.repeat
        self.t_ok_last = self.t_ok
        #对应按钮字符
        s = self.CODE.get(self.cmd)
        return self.changed, s, self.repeat, self.t_ok



if __name__ == "__main__":
    machine.freq(160000000)
    pwm1 = PWM(Pin(5), freq=500, duty=0)
    pwm2 = PWM(Pin(4), freq=500, duty=0)
    pwm3 = PWM(Pin(0), freq=500, duty=0)
    pwm4 = PWM(Pin(2), freq=500, duty=0)
    state = 0
    speed = 512
    t = IR(14)
    while(True):
        changed, s, repeat, t_ok = t.scan()
        if changed == True:
            if s == '1':
                speed = 512
            elif s == '2':
                speed = 640
            elif s == '3':
                speed = 768
            if repeat >= 2:
                if s == 'up' and state != 1:
                    state = 1
                    pwm1.duty(speed)       
                    pwm2.duty(speed)        
                    pwm3.duty(0)          
                    pwm4.duty(0)          
                    print("state1")
                elif s == 'down' and state != 2:
                    state = 2
                    pwm1.duty(0)          
                    pwm2.duty(0)          
                    pwm3.duty(speed)        
                    pwm4.duty(speed)        
                    print("state2")
                elif s == 'left' and state != 3:
                    state = 3
                    pwm1.duty(0)          
                    pwm2.duty(int(speed/2 + 128))        
                    pwm3.duty(int(speed/2 + 128))        
                    pwm4.duty(0)         
                    print("state3")
                elif s == 'right' and state != 4:
                    state = 4
                    pwm1.duty(int(speed/2 + 128))        
                    pwm2.duty(0)          
                    pwm3.duty(0)          
                    pwm4.duty(int(speed/2 + 128))        
                    print("state4")
        else:
            if state != 0:
                state = 0
                pwm1.duty(0)         
                pwm2.duty(0)         
                pwm3.duty(0)          
                pwm4.duty(0)         
                print("state0")
        utime.sleep(0.2)

猜你喜欢

转载自blog.csdn.net/qq_37429313/article/details/113956554