ESP32 smart car+PS2 wireless remote control+Mecanum wheel+microPython

from machine import Pin,PWM
from ps2 import PS2Controller
import time
import os

# ############################################
# PS2 Remote Control
# ############################################
ps2ctl = PS2Controller(di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12)
ps2ctl.init()

# ############################################
# Trolley wheel control
# ############################################
pin1=PWM(Pin(19),freq=1000) #Left front red 1
pin2=PWM(Pin(18),freq=1000)
pin3=PWM(Pin(5),freq=1000) #Left rear red 3
pin4=PWM(Pin(17),freq=1000)
pin5=PWM(Pin(16),freq=1000) #right front black 5
pin6=PWM(Pin(4),freq=1000)
pin7=PWM(Pin(0),freq=1000) #right rear black 7
pin8=PWM(Pin(2),freq=1000)

#go ahead
def car_forward(speed):
  pin1.duty(speed) #Left front
  pin2.duty(0)
  pin3.duty(speed) #Left rear
  pin4.duty(0)
  pin5.duty(speed) #right front
  pin6.duty(0)
  pin7.duty(speed) #right rear
  pin8.duty(0)

#Back, reverse, reverse
def car_back(speed):
  pin1.duty(0) #Left front
  pin2.duty(speed)
  pin3.duty(0) #Left rear
  pin4.duty(speed)
  pin5.duty(0) #right front
  pin6.duty(speed)
  pin7.duty(0) #right back
  pin8.duty(speed)

# Ordinary left turn = front left, backward left, forward right, backward right
def car_left(speed):
  pin1.duty(0) #Left front
  pin2.duty(speed)
  pin3.duty(0) #Left rear
  pin4.duty(speed)
  pin5.duty(speed) #right front
  pin6.duty(0)
  pin7.duty(speed) #right rear
  pin8.duty(0)

# Ordinary right turn = forward left and rear left, forward right and backward right
def car_right(speed):
  pin1.duty(speed) #Left front
  pin2.duty(0)
  pin3.duty(speed) #Left rear
  pin4.duty(0)
  pin5.duty(0) #right front
  pin6.duty(speed)
  pin7.duty(0) #right back
  pin8.duty(speed)

#park,stop
def car_stop():
  pin1.duty(0)
  pin2.duty(0)
  pin3.duty(0)
  pin4.duty(0)
  pin5.duty(0)
  pin6.duty(0)
  pin7.duty(0)
  pin8.duty(0)

# Left translation = left front inversion, left back forward, right front forward, right back reverse
def car_left_pingyi(speed):
  pin1.duty(0) #Left front
  pin2.duty(speed)
  pin3.duty(speed) #Left rear
  pin4.duty(0)
  pin5.duty(speed) #right front
  pin6.duty(0)
  pin7.duty(0) #right back
  pin8.duty(speed)
  
# Right translation = forward left front, reverse left rear, reverse front right, forward right rear
def car_right_pingyi(speed):
  pin1.duty(speed) #Left front
  pin2.duty(0)
  pin3.duty(0) #Left rear
  pin4.duty(speed)
  pin5.duty(0) #right front
  pin6.duty(speed)
  pin7.duty(speed) #right rear
  pin8.duty(0)

# Upper left corner = left front does not move, left back moves forward, right front moves forward, right back stays still
def car_left_up(speed):
  pin1.duty(0) #Left front
  pin2.duty(0)
  pin3.duty(speed) #Left rear
  pin4.duty(0)
  pin5.duty(speed) #right front
  pin6.duty(0)
  pin7.duty(0) #right back
  pin8.duty(0)
  
# Lower left corner = forward left and backward, left and rear motionless, right front and motionless, right and rearward motionless
def car_left_down(speed):
  pin1.duty(0) #Left front
  pin2.duty(speed)
  pin3.duty(0) #Left rear
  pin4.duty(0)
  pin5.duty(0) #right front
  pin6.duty(0)
  pin7.duty(0) #right back
  pin8.duty(speed)
  
# Upper right corner = forward left, forward left, fixed front left, fixed forward right, forward right backward
def car_right_up(speed):
  pin1.duty(speed) #Left front
  pin2.duty(0)
  pin3.duty(0) #Left rear
  pin4.duty(0)
  pin5.duty(0) #right front
  pin6.duty(0)
  pin7.duty(speed) #right rear
  pin8.duty(0)
  
# Lower right corner = Left front does not move, left back goes backwards, right front goes backwards, right back does not move
def car_right_down(speed):
  pin1.duty(0) #Left front
  pin2.duty(0)
  pin3.duty(0) #Left rear
  pin4.duty(speed)
  pin5.duty(0) #right front
  pin6.duty(speed)
  pin7.duty(0) #right back
  pin8.duty(0)
  
# ############################################### #
# The main loop begins! ! !
# ############################################### #
i=1 #Number of loops
speed=400 #Initial speed, up to 1000. If it is lower than 400, the voltage will be too low to drive.
print("The car program has started running and is waiting for the PS2 remote control button (press start to stop)")
try:
  while True:

    key_car= ps2ctl.read_once() # The received character format is keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
    #print("Key detected:",key_car)
    key_list= key_car.split(':') # Use: to split the string and write it into the array key_list
    # key_list[1] Input keys
    # key_list[3] Left joystick coordinates
    # key_list[5] Right joystick coordinates

    # stop = remote control start = 4
    if key_list[1]=="START" :
      print(key_car,"Stop....")
      car_stop()

    # Forward = Remote Control Left Stick Up = 5
    # Forward = Remote Control Right Stick Up = 13
    if key_list[1]=="UP" or key_list[1]=="TRIANGLE":
      print(key_car,"Forward")
      car_forward(speed)
      
    # Back = Remote Control Left Joystick Down = 7
    # Back = Remote Control Right Stick Down = 15
    if key_list[1]=="DOWN" or key_list[1]=="CROSS":
      print(key_car,"Back")
      car_back(speed)

    # Left Pan = Remote Control Left Stick Left = 8
    if key_list[1]=="LEFT":
      print(key_car,"Left translation")
      car_left_pingyi(speed)
      
    # Pan right = remote control left joystick right = 6
    if key_list[1]=="RIGHT":
      print(key_car," pan right")
      car_right_pingyi(speed)
      
    # Turn left = remote control right joystick left = 16
    if key_list[1]=="SQUARE" :
      print(key_car,"Turn left")
      car_left(speed)
    
    # Turn right = remote control right joystick right = 14
    if key_list[1]=="CIRCLE":
      print(key_car,"Turn right")
      car_right(speed)
      
    # Upper left = remote control Left L1 = 11
    if key_list[1]=="UP,LEFT":
      print(key_car,"upper left")
      car_left_up(speed)
      
    # Lower left = remote control Left L2 = 9
    if key_list[1]=="DOWN,LEFT":
      print(key_car,"lower left")
      car_left_down(speed)
      
    # Upper right = remote control right R1 = 12
    if key_list[1]=="UP,RIGHT":
      print(key_car,"upper right")
      car_right_up(speed)

    # Lower right = remote control right R2 = 10
    if key_list[1]=="RIGHT,DOWN":
      print(key_car,"lower right")
      car_right_down(speed)
      
    # L1 acceleration
    if key_list[1]=="L1" and speed<1000:
      speed=speed + 100
      print("The current speed has accelerated to:",speed)
      
    # L2 slow down
    if key_list[1]=="L2" and speed>400:
      speed=speed-100
      print("The current speed has been reduced to:",speed)
      
    # Right triangle + X, press simultaneously, delete main.py and cancel automatic startup
    if key_list[1]=="TRIANGLE,CROSS" :
      os.remove("main.py")
      print("---------- main.py has been deleted ----------")
      car_stop()

    # SELECT = 1 L3 = 2 R3 = 3 START = 4
    # UP = 5 RIGHT = 6 DOWN = 7 LEFT = 8
    # L2 = 9 R2 = 10 L1 = 11 R1 = 12
    # TRIANGLE = 13 CIRCLE = 14 CROSS = 15 SQUARE = 16
  
    i=i+1
    time.sleep(0.1)
    
except KeyboardInterrupt:
    print('KeyboardInterrupt program was terminated....')
finally:
    pin1.deinit()
    pin2.deinit()
    pin3.deinit()
    pin4.deinit()
    pin5.deinit()
    pin6.deinit()
    pin7.deinit()
    pin8.deinit()
    print('Exit The program has been run ' + str(i) + ' times, and the program ends.') 

If you need to use the ps2.py file, you can view ESP32 + PS2 wireless controller adapter board + microPython-CSDN blog

ps2.py

import time
from machine import Pin
 
class PS2Controller:
    # These are our button constants
    SELECT = 1
    L3 = 2
    R3 = 3
    START = 4
    UP = 5
    RIGHT = 6
    DOWN = 7
    LEFT = 8
    L2=9
    R2 = 10
    L1 = 11
    R1 = 12
    TRIANGLE = 13
    CIRCLE = 14
    CROSS = 15
    SQUARE = 16
    KEYS = dict([
                  (SELECT, "SELECT"), (L3, "L3"), (R3, "R3"), (START, "START"),
                  (UP, "UP"), (RIGHT, "RIGHT"), (DOWN, "DOWN"), (LEFT, "LEFT"),
                  (L2, "L2"), (R2, "R2"), (L1, "L1"), (R1, "R1"),
                  (TRIANGLE, "TRIANGLE"), (CIRCLE, "CIRCLE"), (CROSS, "CROSS"), (SQUARE, "SQUARE") ])
 
    CTRL_CLK = 10
    CTRL_BYTE_DELAY = 16
 
    CMD_SHORT_POLL = [0x01, 0x42, 0x00, 0x00, 0x00]
    CMD_ENTER_CONFIG = [0x01, 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
    CMD_SET_MODE = [0X01, 0x44, 0x00,
                        0x01, # 00 normal; 01 red or analog
                        0x03, # 03 lock;ee no lock
                        0x00, 0x00, 0x00, 0x00]
    CMD_SET_BYTES_LARGE = [0x01, 0x4F, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00]
    CMD_EXIT_CONFIG = [0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A]
    CMD_ENABLE_RUMBLE = [0x01, 0x4D, 0x00, 0x00, 0x01]
    CMD_TYPE_READ = [0x01, 0x45, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A]
    CMD_READ_DATA = [0X01, 0X42, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00]
 
    MAX_READ_DELAY = 1500
 
    VALID_MODES = [0X41, 0X73]
 
    def __init__(self, di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12): # DI=DAT, DO=CMD You can adjust the pins to your own corresponding pins here
        self.di_pin_no = di_pin_no
        self.do_pin_no = do_pin_no
        self.cs_pin_no = cs_pin_no
        self.clk_pin_no = clk_pin_no
        self.di = Pin(self.di_pin_no, Pin.IN) # DI = DAT
        self.do = Pin(self.do_pin_no, Pin.OUT) # DO = CMD
        self.cs = Pin(self.cs_pin_no, Pin.OUT)
        self.clk = Pin(self.clk_pin_no, Pin.OUT)
        self.buff_out = [0x01, 0x42]
        self.buff_in = [0] * 9
        self.pressed_keys = []
        self.read_delay = 1
        self.last_read_ms = 0
        self.lx = 0
        self.ly = 0
        self.rx = 0
        self.ry = 0
 
    @property
    def red_mode(self): # analog mode
        return self.buff_in[1] & 0xf0 == 0x70
 
    def do_h(self):
        self.do.value(1)
 
    def do_l(self):
        self.do.value(0)
 
    def cs_h(self):
        self.cs.value(1)
 
    def cs_l(self):
        self.cs.value(0)
 
    def clk_h(self):
        self.clk.value(1)
 
    def clk_l(self):
        self.clk.value(0)
 
 
    # noinspection PyUnresolvedReferences
    def delay_byte(self):
        time.sleep_us(self.read_delay)
 
    # noinspection PyUnresolvedReferences
    def delay_clk(self):
        time.sleep_us(self.CTRL_CLK)
 
    # noinspection PyUnresolvedReferences
    def delay_read(self):
        time.sleep_us(self.CTRL_BYTE_DELAY)
        # time.sleep_ms(self.read_delay)
 
    def cmd(self, cmd):
        ret = 0
        for i in range(8):
            if cmd & 1 << i:
                self.do_h()
            else:
                self.do_l()
            self.clk_l()
            self.delay_clk()
            if self.di.value():
                ret |= 1 << i
            self.clk_h()
        self.do_h()
        self.delay_byte()
        return ret
 
    """
    :param
    pure True means not delay
    """
 
    def cmd_group(self, cmds):
        self.cs_l()
        self.delay_byte()
        for cmd in cmds:
            self.cmd(cmd)
        self.cs_h()
        self.delay_read()
 
    def init(self):
        self.di = Pin(self.di_pin_no, Pin.IN)
        self.do = Pin(self.do_pin_no, Pin.OUT)
        self.cs = Pin(self.cs_pin_no, Pin.OUT)
        self.clk = Pin(self.clk_pin_no, Pin.OUT)
        self.do_h()
        self.clk_h()
 
        self.read_once()
        self.read_once()
        #
        if self.buff_in[1] not in [0x41, 0x73]:
            print("control type not ok, expect 41 73 79, bug get ", "{:02x}".format(self.buff_in[1]))
            return 1
 
        self.read_delay = 1
 
        for i in range(10):
            # self.cmd_group(self.CMD_SHORT_POLL)
            # self.cmd_group(self.CMD_SHORT_POLL)
            # self.cmd_group(self.CMD_SHORT_POLL)
            self.cmd_group(self.CMD_ENTER_CONFIG)
            self.delay_byte()
 
            self.do_h()
            self.clk_h()
            self.cs_l()
 
            self.delay_byte()
            #
            temp = [0] * len(self.CMD_TYPE_READ)
            for j in range(9):
                for cmd in self.CMD_TYPE_READ:
                    temp[j] = self.cmd(cmd)
            self.cs_h()
 
            self.cmd_group(self.CMD_SET_MODE)
            # self.cmd_group(self.CMD_ENABLE_RUMBLE)
            self.cmd_group(self.CMD_EXIT_CONFIG)
            self.read_once()
            if self.buff_in[1] in self.VALID_MODES:
                print("read_delay configured,", self.read_delay)
                break
            else:
                self.read_delay + = 1
                print("read_delay + + ,", self.read_delay)
 
    def reconfig(self):
        print("reconfig")
        self.cmd_group(self.CMD_ENTER_CONFIG)
        self.cmd_group(self.CMD_SET_MODE)
        self.cmd_group(self.CMD_EXIT_CONFIG)
 
    def p(self, debug=True):
        if debug:
            for d in self.buff_in:
                print("{:08b}".format(d))
 
        key_raw = (self.buff_in[4] << 8) | self.buff_in[3]
        for i in range(1, 17):
            if not key_raw & 1 << i - 1:
                self.pressed_keys.append(i)
 
        if self.red_mode:
            self.rx = self.buff_in[5] - 128
            self.ry = self.buff_in[6] - 128
            self.lx = self.buff_in[7] - 128
            self.ly = self.buff_in[8] - 128
        if self.pressed_keys:
            out = "keys:" + ','.join(self.KEYS[k] for k in self.pressed_keys) + "; "
        else:
            out = ""
        # for key in self.pressed_keys:
        # print(key, self.KEYS[key])
        if self.red_mode and (out or any(x != 0 for x in [self.rx, self.ry, self.lx, self.ly])):
            out + = "pos: (lx,ly):{},{}; (rx,ry): {},{}".format(self.lx, self.ly, self.rx, self.ry )
 
        if out:
            print(out)
 
    def read_once(self, debug=False):
        now = time.ticks_ms()
        delay = now - self.last_read_ms
        if delay > self.MAX_READ_DELAY:
            print(now, self.last_read_ms, delay)
            self.reconfig()
        elif delay < self.read_delay:
            # noinspection PyUnresolvedReferences
            time.sleep_ms(self.read_delay - delay)
 
        self.buff_in = [0] * 9
        self.pressed_keys.clear()
 
        for j in range(5):
            # for i in range(1):
            self.do_h()
            self.clk_h()
            self.cs_l()
            self.delay_byte()
 
            for i, c in enumerate(self.CMD_READ_DATA):
                self.buff_in[i] = self.cmd(c)
 
            self.cs_h()
 
            if self.buff_in[1] in self.VALID_MODES:
                break
            else:
                print("mode: {:08b}, retry_J: {}".format(self.buff_in[1], j))
                self.reconfig()
                self.delay_read()
        if self.buff_in[1] not in self.VALID_MODES and self.read_delay < 10:
            self.read_delay + = 1
 
        self.last_read_ms = time.ticks_ms()
        #self.p(debug)
 
        #Add below for yourself, the code in the original P()
        key_raw = (self.buff_in[4] << 8) | self.buff_in[3]
        for i in range(1, 17):
            if not key_raw & 1 << i - 1:
                self.pressed_keys.append(i)
 
        if self.red_mode:
            self.rx = self.buff_in[5] - 128
            self.ry = self.buff_in[6] - 128
            self.lx = self.buff_in[7] - 128
            self.ly = self.buff_in[8] - 128
        if self.pressed_keys: #Pay attention to the following lines: and, do not modify them, they will be marked and used later!
            out = "keys:" + ','.join(self.KEYS[k] for k in self.pressed_keys) + ": "
        else:
            out = "keys:none:"
        # for key in self.pressed_keys:
        # print(key, self.KEYS[key])
        if self.red_mode and (out or any(x != 0 for x in [self.rx, self.ry, self.lx, self.ly])):
            out + = "pos(lx,ly):{},{}: pos(rx,ry):{},{}:".format(self.lx, self.ly, self.rx, self. ry)
        if out:
            print(out)
            
        #return self.buff_in
        return out
 
'''
# Call the method and create a new file with the following lines of code, such as: ps2_test.py
from ps2 import PS2Controller
import time
ps2ctl = PS2Controller(di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12)
ps2ctl.init()
while True:
    key_car= ps2ctl.read_once() # The received character format is keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
    #print("Key detected:",key_car)
    key_list= key_car.split(':') # Use: to split the string and write the keys input by key_list[1] in the array key_list, key_list[3] left joystick coordinates, key_list[5] right joystick rod coordinates
    if key_list[1]=="UP":
      print(key_car,"Forward")
      
    if key_list[1]=="UP,LEFT":
      print(key_car,"upper left")
    time.sleep(0.2)
''' 

?

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Python entry skill treeHomepageOverview 383651 people are learning the system