- from machine import Pin,PWM
- from ps2 import PS2Controller
- import time
- import os
-
- # #############################################
- # PS2 遥控器
- # #############################################
- ps2ctl = PS2Controller(di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12)
- ps2ctl.init()
-
- # #############################################
- # 小车轮子控制
- # #############################################
- pin1=PWM(Pin(19),freq=1000) #左前 红1
- pin2=PWM(Pin(18),freq=1000)
- pin3=PWM(Pin( 5),freq=1000) #左后 红3
- pin4=PWM(Pin(17),freq=1000)
- pin5=PWM(Pin(16),freq=1000) #右前 黑5
- pin6=PWM(Pin( 4),freq=1000)
- pin7=PWM(Pin( 0),freq=1000) #右后 黑7
- pin8=PWM(Pin( 2),freq=1000)
-
- #前进
- def car_forward(speed):
- pin1.duty(speed) #左前
- pin2.duty(0)
- pin3.duty(speed) #左后
- pin4.duty(0)
- pin5.duty(speed) #右前
- pin6.duty(0)
- pin7.duty(speed) #右后
- pin8.duty(0)
-
- #后退、倒车、倒转
- def car_back(speed):
- pin1.duty(0) #左前
- pin2.duty(speed)
- pin3.duty(0) #左后
- pin4.duty(speed)
- pin5.duty(0) #右前
- pin6.duty(speed)
- pin7.duty(0) #右后
- pin8.duty(speed)
-
- # 普通左转 = 左前、左后后退, 右前、右后前进
- def car_left(speed):
- pin1.duty(0) #左前
- pin2.duty(speed)
- pin3.duty(0) #左后
- pin4.duty(speed)
- pin5.duty(speed) #右前
- pin6.duty(0)
- pin7.duty(speed) #右后
- pin8.duty(0)
-
- # 普通右转 = 左前、左后前进, 右前、右后后退
- def car_right(speed):
- pin1.duty(speed) #左前
- pin2.duty(0)
- pin3.duty(speed) #左后
- pin4.duty(0)
- pin5.duty(0) #右前
- pin6.duty(speed)
- pin7.duty(0) #右后
- pin8.duty(speed)
-
- #停车、停止
- 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)
-
- # 左平移=左前倒转、左后前进、右前前进、右后倒转
- def car_left_pingyi(speed):
- pin1.duty(0) #左前
- pin2.duty(speed)
- pin3.duty(speed) #左后
- pin4.duty(0)
- pin5.duty(speed) #右前
- pin6.duty(0)
- pin7.duty(0) #右后
- pin8.duty(speed)
-
- # 右平移=左前前进、左后倒转、右前倒转、右后前进
- def car_right_pingyi(speed):
- pin1.duty(speed) #左前
- pin2.duty(0)
- pin3.duty(0) #左后
- pin4.duty(speed)
- pin5.duty(0) #右前
- pin6.duty(speed)
- pin7.duty(speed) #右后
- pin8.duty(0)
-
- # 左上角 = 左前不动、左后前进、右前前进、右后不动
- def car_left_up(speed):
- pin1.duty(0) #左前
- pin2.duty(0)
- pin3.duty(speed) #左后
- pin4.duty(0)
- pin5.duty(speed) #右前
- pin6.duty(0)
- pin7.duty(0) #右后
- pin8.duty(0)
-
- # 左下角 = 左前倒退、左后不动、右前不动、右后倒退
- def car_left_down(speed):
- pin1.duty(0) #左前
- pin2.duty(speed)
- pin3.duty(0) #左后
- pin4.duty(0)
- pin5.duty(0) #右前
- pin6.duty(0)
- pin7.duty(0) #右后
- pin8.duty(speed)
-
- # 右上角 = 左前前进、左后不动、右前不动、右后前进
- def car_right_up(speed):
- pin1.duty(speed) #左前
- pin2.duty(0)
- pin3.duty(0) #左后
- pin4.duty(0)
- pin5.duty(0) #右前
- pin6.duty(0)
- pin7.duty(speed) #右后
- pin8.duty(0)
-
- # 右下角 = 左前不动、左后倒退、右前倒退、右后不动
- def car_right_down(speed):
- pin1.duty(0) #左前
- pin2.duty(0)
- pin3.duty(0) #左后
- pin4.duty(speed)
- pin5.duty(0) #右前
- pin6.duty(speed)
- pin7.duty(0) #右后
- pin8.duty(0)
-
- # ##################################################
- # 主循环开始!!!
- # ##################################################
- i=1 #循环次数
- speed=400 #初始速度,最高1000. 低于400容易电压太低驱动不了
- print("小车程序开始运行,正在等待PS2遥控器按键(按start停车)")
- try:
- while True:
-
- key_car= ps2ctl.read_once() # 收到的字符格式为 keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
- #print("检测到按键:",key_car)
- key_list= key_car.split(':') # 用:来将字符串进行分割,写入数组key_list中
- # key_list[1] 输入的按键
- # key_list[3] 左摇杆坐标
- # key_list[5] 右摇杆坐标
-
- # 停止 = 遥控器 start = 4
- if key_list[1]=="START" :
- print(key_car," 停止.......")
- car_stop()
-
- # 前进 = 遥控器 左摇杆 上 = 5
- # 前进 = 遥控器 右摇杆 上 = 13
- if key_list[1]=="UP" or key_list[1]=="TRIANGLE":
- print(key_car," 前进")
- car_forward(speed)
-
- # 后退 = 遥控器 左摇杆 下 = 7
- # 后退 = 遥控器 右摇杆 下 = 15
- if key_list[1]=="DOWN" or key_list[1]=="CROSS":
- print(key_car," 后退")
- car_back(speed)
-
- # 左平移 = 遥控器 左摇杆左 = 8
- if key_list[1]=="LEFT":
- print(key_car," 左平移")
- car_left_pingyi(speed)
-
- # 右平移 = 遥控器 左摇杆右 = 6
- if key_list[1]=="RIGHT":
- print(key_car," 右平移")
- car_right_pingyi(speed)
-
- # 左转 = 遥控器 右摇杆 左 = 16
- if key_list[1]=="SQUARE" :
- print(key_car," 左转")
- car_left(speed)
-
- # 右转 = 遥控器 右摇杆 右 = 14
- if key_list[1]=="CIRCLE":
- print(key_car," 右转")
- car_right(speed)
-
- # 左上方 = 遥控器 左L1 = 11
- if key_list[1]=="UP,LEFT":
- print(key_car," 左上方")
- car_left_up(speed)
-
- # 左下方 = 遥控器 左L2 = 9
- if key_list[1]=="DOWN,LEFT":
- print(key_car," 左下方")
- car_left_down(speed)
-
- # 右上方 = 遥控器 右R1 = 12
- if key_list[1]=="UP,RIGHT":
- print(key_car," 右上方")
- car_right_up(speed)
-
- # 右下方 = 遥控器 右R2 = 10
- if key_list[1]=="RIGHT,DOWN":
- print(key_car," 右下方")
- car_right_down(speed)
-
- # L1 加速
- if key_list[1]=="L1" and speed<1000:
- speed=speed+100
- print("当前速度已经加速至:",speed)
-
- # L2 减速
- if key_list[1]=="L2" and speed>400:
- speed=speed-100
- print("当前速度已经降低至:",speed)
-
- # 右侧 三角+X,同时按下,删除main.py 取消自动启动
- if key_list[1]=="TRIANGLE,CROSS" :
- os.remove("main.py")
- print("----------- main.py 已经删除 ----------")
- 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 程序被人为中止....')
- finally:
- pin1.deinit()
- pin2.deinit()
- pin3.deinit()
- pin4.deinit()
- pin5.deinit()
- pin6.deinit()
- pin7.deinit()
- pin8.deinit()
- print('Exit 程序共运行了'+str(i)+'次,程序结束。')
需要用到ps2.py文件,可查看ESP32+PS2 无线手柄转接板+microPython-CSDN博客
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 可以在此处将针脚调整为你自己对应的针脚
- 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 configed,", 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)
-
- #以下为自己添加 ,原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: #注意下面这几行的:和,千万不要修改,后面要他们做标记分割使用!
- out = "keys:" + ','.join(self.KEYS[k] for k in self.pressed_keys) + ": "
- else:
- out = "keys:无:"
- # 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
-
- '''
- # 调用方法,将以下几行代码新建一个文件如: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() # 收到的字符格式为 keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
- #print("检测到按键:",key_car)
- key_list= key_car.split(':') # 用:来将字符串进行分割,写入数组key_list中 key_list[1]输入的按键、key_list[3]左摇杆坐标、key_list[5]右摇杆坐标
- if key_list[1]=="UP":
- print(key_car," 前进")
-
- if key_list[1]=="UP,LEFT":
- print(key_car," 左上方")
- time.sleep(0.2)
- '''