• ESP32智能小车+PS2无线遥控器+麦克纳姆轮+microPython


    1. from machine import Pin,PWM
    2. from ps2 import PS2Controller
    3. import time
    4. import os
    5. # #############################################
    6. # PS2 遥控器
    7. # #############################################
    8. ps2ctl = PS2Controller(di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12)
    9. ps2ctl.init()
    10. # #############################################
    11. # 小车轮子控制
    12. # #############################################
    13. pin1=PWM(Pin(19),freq=1000) #左前 红1
    14. pin2=PWM(Pin(18),freq=1000)
    15. pin3=PWM(Pin( 5),freq=1000) #左后 红3
    16. pin4=PWM(Pin(17),freq=1000)
    17. pin5=PWM(Pin(16),freq=1000) #右前 黑5
    18. pin6=PWM(Pin( 4),freq=1000)
    19. pin7=PWM(Pin( 0),freq=1000) #右后 黑7
    20. pin8=PWM(Pin( 2),freq=1000)
    21. #前进
    22. def car_forward(speed):
    23. pin1.duty(speed) #左前
    24. pin2.duty(0)
    25. pin3.duty(speed) #左后
    26. pin4.duty(0)
    27. pin5.duty(speed) #右前
    28. pin6.duty(0)
    29. pin7.duty(speed) #右后
    30. pin8.duty(0)
    31. #后退、倒车、倒转
    32. def car_back(speed):
    33. pin1.duty(0) #左前
    34. pin2.duty(speed)
    35. pin3.duty(0) #左后
    36. pin4.duty(speed)
    37. pin5.duty(0) #右前
    38. pin6.duty(speed)
    39. pin7.duty(0) #右后
    40. pin8.duty(speed)
    41. # 普通左转 = 左前、左后后退, 右前、右后前进
    42. def car_left(speed):
    43. pin1.duty(0) #左前
    44. pin2.duty(speed)
    45. pin3.duty(0) #左后
    46. pin4.duty(speed)
    47. pin5.duty(speed) #右前
    48. pin6.duty(0)
    49. pin7.duty(speed) #右后
    50. pin8.duty(0)
    51. # 普通右转 = 左前、左后前进, 右前、右后后退
    52. def car_right(speed):
    53. pin1.duty(speed) #左前
    54. pin2.duty(0)
    55. pin3.duty(speed) #左后
    56. pin4.duty(0)
    57. pin5.duty(0) #右前
    58. pin6.duty(speed)
    59. pin7.duty(0) #右后
    60. pin8.duty(speed)
    61. #停车、停止
    62. def car_stop():
    63. pin1.duty(0)
    64. pin2.duty(0)
    65. pin3.duty(0)
    66. pin4.duty(0)
    67. pin5.duty(0)
    68. pin6.duty(0)
    69. pin7.duty(0)
    70. pin8.duty(0)
    71. # 左平移=左前倒转、左后前进、右前前进、右后倒转
    72. def car_left_pingyi(speed):
    73. pin1.duty(0) #左前
    74. pin2.duty(speed)
    75. pin3.duty(speed) #左后
    76. pin4.duty(0)
    77. pin5.duty(speed) #右前
    78. pin6.duty(0)
    79. pin7.duty(0) #右后
    80. pin8.duty(speed)
    81. # 右平移=左前前进、左后倒转、右前倒转、右后前进
    82. def car_right_pingyi(speed):
    83. pin1.duty(speed) #左前
    84. pin2.duty(0)
    85. pin3.duty(0) #左后
    86. pin4.duty(speed)
    87. pin5.duty(0) #右前
    88. pin6.duty(speed)
    89. pin7.duty(speed) #右后
    90. pin8.duty(0)
    91. # 左上角 = 左前不动、左后前进、右前前进、右后不动
    92. def car_left_up(speed):
    93. pin1.duty(0) #左前
    94. pin2.duty(0)
    95. pin3.duty(speed) #左后
    96. pin4.duty(0)
    97. pin5.duty(speed) #右前
    98. pin6.duty(0)
    99. pin7.duty(0) #右后
    100. pin8.duty(0)
    101. # 左下角 = 左前倒退、左后不动、右前不动、右后倒退
    102. def car_left_down(speed):
    103. pin1.duty(0) #左前
    104. pin2.duty(speed)
    105. pin3.duty(0) #左后
    106. pin4.duty(0)
    107. pin5.duty(0) #右前
    108. pin6.duty(0)
    109. pin7.duty(0) #右后
    110. pin8.duty(speed)
    111. # 右上角 = 左前前进、左后不动、右前不动、右后前进
    112. def car_right_up(speed):
    113. pin1.duty(speed) #左前
    114. pin2.duty(0)
    115. pin3.duty(0) #左后
    116. pin4.duty(0)
    117. pin5.duty(0) #右前
    118. pin6.duty(0)
    119. pin7.duty(speed) #右后
    120. pin8.duty(0)
    121. # 右下角 = 左前不动、左后倒退、右前倒退、右后不动
    122. def car_right_down(speed):
    123. pin1.duty(0) #左前
    124. pin2.duty(0)
    125. pin3.duty(0) #左后
    126. pin4.duty(speed)
    127. pin5.duty(0) #右前
    128. pin6.duty(speed)
    129. pin7.duty(0) #右后
    130. pin8.duty(0)
    131. # ##################################################
    132. # 主循环开始!!!
    133. # ##################################################
    134. i=1 #循环次数
    135. speed=400 #初始速度,最高1000. 低于400容易电压太低驱动不了
    136. print("小车程序开始运行,正在等待PS2遥控器按键(按start停车)")
    137. try:
    138. while True:
    139. key_car= ps2ctl.read_once() # 收到的字符格式为 keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
    140. #print("检测到按键:",key_car)
    141. key_list= key_car.split(':') # 用:来将字符串进行分割,写入数组key_list中
    142. # key_list[1] 输入的按键
    143. # key_list[3] 左摇杆坐标
    144. # key_list[5] 右摇杆坐标
    145. # 停止 = 遥控器 start = 4
    146. if key_list[1]=="START" :
    147. print(key_car," 停止.......")
    148. car_stop()
    149. # 前进 = 遥控器 左摇杆 上 = 5
    150. # 前进 = 遥控器 右摇杆 上 = 13
    151. if key_list[1]=="UP" or key_list[1]=="TRIANGLE":
    152. print(key_car," 前进")
    153. car_forward(speed)
    154. # 后退 = 遥控器 左摇杆 下 = 7
    155. # 后退 = 遥控器 右摇杆 下 = 15
    156. if key_list[1]=="DOWN" or key_list[1]=="CROSS":
    157. print(key_car," 后退")
    158. car_back(speed)
    159. # 左平移 = 遥控器 左摇杆左 = 8
    160. if key_list[1]=="LEFT":
    161. print(key_car," 左平移")
    162. car_left_pingyi(speed)
    163. # 右平移 = 遥控器 左摇杆右 = 6
    164. if key_list[1]=="RIGHT":
    165. print(key_car," 右平移")
    166. car_right_pingyi(speed)
    167. # 左转 = 遥控器 右摇杆 左 = 16
    168. if key_list[1]=="SQUARE" :
    169. print(key_car," 左转")
    170. car_left(speed)
    171. # 右转 = 遥控器 右摇杆 右 = 14
    172. if key_list[1]=="CIRCLE":
    173. print(key_car," 右转")
    174. car_right(speed)
    175. # 左上方 = 遥控器 左L1 = 11
    176. if key_list[1]=="UP,LEFT":
    177. print(key_car," 左上方")
    178. car_left_up(speed)
    179. # 左下方 = 遥控器 左L2 = 9
    180. if key_list[1]=="DOWN,LEFT":
    181. print(key_car," 左下方")
    182. car_left_down(speed)
    183. # 右上方 = 遥控器 右R1 = 12
    184. if key_list[1]=="UP,RIGHT":
    185. print(key_car," 右上方")
    186. car_right_up(speed)
    187. # 右下方 = 遥控器 右R2 = 10
    188. if key_list[1]=="RIGHT,DOWN":
    189. print(key_car," 右下方")
    190. car_right_down(speed)
    191. # L1 加速
    192. if key_list[1]=="L1" and speed<1000:
    193. speed=speed+100
    194. print("当前速度已经加速至:",speed)
    195. # L2 减速
    196. if key_list[1]=="L2" and speed>400:
    197. speed=speed-100
    198. print("当前速度已经降低至:",speed)
    199. # 右侧 三角+X,同时按下,删除main.py 取消自动启动
    200. if key_list[1]=="TRIANGLE,CROSS" :
    201. os.remove("main.py")
    202. print("----------- main.py 已经删除 ----------")
    203. car_stop()
    204. # SELECT = 1 L3 = 2 R3 = 3 START = 4
    205. # UP = 5 RIGHT = 6 DOWN = 7 LEFT = 8
    206. # L2 = 9 R2 = 10 L1 = 11 R1 = 12
    207. # TRIANGLE = 13 CIRCLE = 14 CROSS = 15 SQUARE = 16
    208. i=i+1
    209. time.sleep(0.1)
    210. except KeyboardInterrupt:
    211. print('KeyboardInterrupt 程序被人为中止....')
    212. finally:
    213. pin1.deinit()
    214. pin2.deinit()
    215. pin3.deinit()
    216. pin4.deinit()
    217. pin5.deinit()
    218. pin6.deinit()
    219. pin7.deinit()
    220. pin8.deinit()
    221. print('Exit 程序共运行了'+str(i)+'次,程序结束。')

    需要用到ps2.py文件,可查看ESP32+PS2 无线手柄转接板+microPython-CSDN博客

     ps2.py

    1. import time
    2. from machine import Pin
    3. class PS2Controller:
    4. # These are our button constants
    5. SELECT = 1
    6. L3 = 2
    7. R3 = 3
    8. START = 4
    9. UP = 5
    10. RIGHT = 6
    11. DOWN = 7
    12. LEFT = 8
    13. L2 = 9
    14. R2 = 10
    15. L1 = 11
    16. R1 = 12
    17. TRIANGLE = 13
    18. CIRCLE = 14
    19. CROSS = 15
    20. SQUARE = 16
    21. KEYS = dict([
    22. (SELECT, "SELECT"), (L3, "L3"), (R3, "R3"), (START, "START"),
    23. (UP, "UP"), (RIGHT, "RIGHT"), (DOWN, "DOWN"), (LEFT, "LEFT"),
    24. (L2, "L2"), (R2, "R2"), (L1, "L1"), (R1, "R1"),
    25. (TRIANGLE, "TRIANGLE"), (CIRCLE, "CIRCLE"), (CROSS, "CROSS"), (SQUARE, "SQUARE") ])
    26. CTRL_CLK = 10
    27. CTRL_BYTE_DELAY = 16
    28. CMD_SHORT_POLL = [0x01, 0x42, 0x00, 0x00, 0x00]
    29. CMD_ENTER_CONFIG = [0x01, 0x43, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
    30. CMD_SET_MODE = [0X01, 0x44, 0x00,
    31. 0x01, # 00 normal; 01 red or analog
    32. 0x03, # 03 lock; ee no lock
    33. 0x00, 0x00, 0x00, 0x00]
    34. CMD_SET_BYTES_LARGE = [0x01, 0x4F, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00]
    35. CMD_EXIT_CONFIG = [0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A]
    36. CMD_ENABLE_RUMBLE = [0x01, 0x4D, 0x00, 0x00, 0x01]
    37. CMD_TYPE_READ = [0x01, 0x45, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A]
    38. CMD_READ_DATA = [0X01, 0X42, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00]
    39. MAX_READ_DELAY = 1500
    40. VALID_MODES = [0X41, 0X73]
    41. def __init__(self, di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12): # DI=DAT、DO=CMD 可以在此处将针脚调整为你自己对应的针脚
    42. self.di_pin_no = di_pin_no
    43. self.do_pin_no = do_pin_no
    44. self.cs_pin_no = cs_pin_no
    45. self.clk_pin_no = clk_pin_no
    46. self.di = Pin(self.di_pin_no, Pin.IN) # DI = DAT
    47. self.do = Pin(self.do_pin_no, Pin.OUT) # DO = CMD
    48. self.cs = Pin(self.cs_pin_no, Pin.OUT)
    49. self.clk = Pin(self.clk_pin_no, Pin.OUT)
    50. self.buff_out = [0x01, 0x42]
    51. self.buff_in = [0] * 9
    52. self.pressed_keys = []
    53. self.read_delay = 1
    54. self.last_read_ms = 0
    55. self.lx = 0
    56. self.ly = 0
    57. self.rx = 0
    58. self.ry = 0
    59. @property
    60. def red_mode(self): # analog mode
    61. return self.buff_in[1] & 0xf0 == 0x70
    62. def do_h(self):
    63. self.do.value(1)
    64. def do_l(self):
    65. self.do.value(0)
    66. def cs_h(self):
    67. self.cs.value(1)
    68. def cs_l(self):
    69. self.cs.value(0)
    70. def clk_h(self):
    71. self.clk.value(1)
    72. def clk_l(self):
    73. self.clk.value(0)
    74. # noinspection PyUnresolvedReferences
    75. def delay_byte(self):
    76. time.sleep_us(self.read_delay)
    77. # noinspection PyUnresolvedReferences
    78. def delay_clk(self):
    79. time.sleep_us(self.CTRL_CLK)
    80. # noinspection PyUnresolvedReferences
    81. def delay_read(self):
    82. time.sleep_us(self.CTRL_BYTE_DELAY)
    83. # time.sleep_ms(self.read_delay)
    84. def cmd(self, cmd):
    85. ret = 0
    86. for i in range(8):
    87. if cmd & 1 << i:
    88. self.do_h()
    89. else:
    90. self.do_l()
    91. self.clk_l()
    92. self.delay_clk()
    93. if self.di.value():
    94. ret |= 1 << i
    95. self.clk_h()
    96. self.do_h()
    97. self.delay_byte()
    98. return ret
    99. """
    100. :param
    101. pure True means not delay
    102. """
    103. def cmd_group(self, cmds):
    104. self.cs_l()
    105. self.delay_byte()
    106. for cmd in cmds:
    107. self.cmd(cmd)
    108. self.cs_h()
    109. self.delay_read()
    110. def init(self):
    111. self.di = Pin(self.di_pin_no, Pin.IN)
    112. self.do = Pin(self.do_pin_no, Pin.OUT)
    113. self.cs = Pin(self.cs_pin_no, Pin.OUT)
    114. self.clk = Pin(self.clk_pin_no, Pin.OUT)
    115. self.do_h()
    116. self.clk_h()
    117. self.read_once()
    118. self.read_once()
    119. #
    120. if self.buff_in[1] not in [0x41, 0x73]:
    121. print("control type not ok, expect 41 73 79, bug get ", "{:02x}".format(self.buff_in[1]))
    122. return 1
    123. self.read_delay = 1
    124. for i in range(10):
    125. # self.cmd_group(self.CMD_SHORT_POLL)
    126. # self.cmd_group(self.CMD_SHORT_POLL)
    127. # self.cmd_group(self.CMD_SHORT_POLL)
    128. self.cmd_group(self.CMD_ENTER_CONFIG)
    129. self.delay_byte()
    130. self.do_h()
    131. self.clk_h()
    132. self.cs_l()
    133. self.delay_byte()
    134. #
    135. temp = [0] * len(self.CMD_TYPE_READ)
    136. for j in range(9):
    137. for cmd in self.CMD_TYPE_READ:
    138. temp[j] = self.cmd(cmd)
    139. self.cs_h()
    140. self.cmd_group(self.CMD_SET_MODE)
    141. # self.cmd_group(self.CMD_ENABLE_RUMBLE)
    142. self.cmd_group(self.CMD_EXIT_CONFIG)
    143. self.read_once()
    144. if self.buff_in[1] in self.VALID_MODES:
    145. print("read_delay configed,", self.read_delay)
    146. break
    147. else:
    148. self.read_delay += 1
    149. print("read_delay++,", self.read_delay)
    150. def reconfig(self):
    151. print("reconfig")
    152. self.cmd_group(self.CMD_ENTER_CONFIG)
    153. self.cmd_group(self.CMD_SET_MODE)
    154. self.cmd_group(self.CMD_EXIT_CONFIG)
    155. def p(self, debug=True):
    156. if debug:
    157. for d in self.buff_in:
    158. print("{:08b}".format(d))
    159. key_raw = (self.buff_in[4] << 8) | self.buff_in[3]
    160. for i in range(1, 17):
    161. if not key_raw & 1 << i - 1:
    162. self.pressed_keys.append(i)
    163. if self.red_mode:
    164. self.rx = self.buff_in[5] - 128
    165. self.ry = self.buff_in[6] - 128
    166. self.lx = self.buff_in[7] - 128
    167. self.ly = self.buff_in[8] - 128
    168. if self.pressed_keys:
    169. out = "keys:" + ','.join(self.KEYS[k] for k in self.pressed_keys) + "; "
    170. else:
    171. out = ""
    172. # for key in self.pressed_keys:
    173. # print(key, self.KEYS[key])
    174. if self.red_mode and (out or any(x != 0 for x in [self.rx, self.ry, self.lx, self.ly])):
    175. out += "pos: (lx,ly):{},{}; (rx,ry): {},{}".format(self.lx, self.ly, self.rx, self.ry)
    176. if out:
    177. print(out)
    178. def read_once(self, debug=False):
    179. now = time.ticks_ms()
    180. delay = now - self.last_read_ms
    181. if delay > self.MAX_READ_DELAY:
    182. print(now, self.last_read_ms, delay)
    183. self.reconfig()
    184. elif delay < self.read_delay:
    185. # noinspection PyUnresolvedReferences
    186. time.sleep_ms(self.read_delay - delay)
    187. self.buff_in = [0] * 9
    188. self.pressed_keys.clear()
    189. for j in range(5):
    190. # for i in range(1):
    191. self.do_h()
    192. self.clk_h()
    193. self.cs_l()
    194. self.delay_byte()
    195. for i, c in enumerate(self.CMD_READ_DATA):
    196. self.buff_in[i] = self.cmd(c)
    197. self.cs_h()
    198. if self.buff_in[1] in self.VALID_MODES:
    199. break
    200. else:
    201. print("mode: {:08b}, retry_J: {}".format(self.buff_in[1], j))
    202. self.reconfig()
    203. self.delay_read()
    204. if self.buff_in[1] not in self.VALID_MODES and self.read_delay < 10:
    205. self.read_delay += 1
    206. self.last_read_ms = time.ticks_ms()
    207. #self.p(debug)
    208. #以下为自己添加 ,原P()内的代码
    209. key_raw = (self.buff_in[4] << 8) | self.buff_in[3]
    210. for i in range(1, 17):
    211. if not key_raw & 1 << i - 1:
    212. self.pressed_keys.append(i)
    213. if self.red_mode:
    214. self.rx = self.buff_in[5] - 128
    215. self.ry = self.buff_in[6] - 128
    216. self.lx = self.buff_in[7] - 128
    217. self.ly = self.buff_in[8] - 128
    218. if self.pressed_keys: #注意下面这几行的:和,千万不要修改,后面要他们做标记分割使用!
    219. out = "keys:" + ','.join(self.KEYS[k] for k in self.pressed_keys) + ": "
    220. else:
    221. out = "keys:无:"
    222. # for key in self.pressed_keys:
    223. # print(key, self.KEYS[key])
    224. if self.red_mode and (out or any(x != 0 for x in [self.rx, self.ry, self.lx, self.ly])):
    225. out += "pos(lx,ly):{},{}: pos(rx,ry):{},{}:".format(self.lx, self.ly, self.rx, self.ry)
    226. if out:
    227. print(out)
    228. #return self.buff_in
    229. return out
    230. '''
    231. # 调用方法,将以下几行代码新建一个文件如:ps2_test.py
    232. from ps2 import PS2Controller
    233. import time
    234. ps2ctl = PS2Controller(di_pin_no=26, do_pin_no=27, cs_pin_no=14, clk_pin_no=12)
    235. ps2ctl.init()
    236. while True:
    237. key_car= ps2ctl.read_once() # 收到的字符格式为 keys:UP,RIGHT: pos(lx,ly):0,-1: pos(rx,ry): 0,-1:
    238. #print("检测到按键:",key_car)
    239. key_list= key_car.split(':') # 用:来将字符串进行分割,写入数组key_list中 key_list[1]输入的按键、key_list[3]左摇杆坐标、key_list[5]右摇杆坐标
    240. if key_list[1]=="UP":
    241. print(key_car," 前进")
    242. if key_list[1]=="UP,LEFT":
    243. print(key_car," 左上方")
    244. time.sleep(0.2)
    245. '''

  • 相关阅读:
    苹果 Vision Pro零售部件成本价格分析
    Postman接口断言&上下游参数传递
    正则匹配以XXX开头的,XXX结束的
    创建java文件 自动添加作者、时间等信息 – IDEA 技巧
    在SpringBoot⼯程连接Redis
    教师资格证面试建议
    【深度学习】分类损失函数解析
    蒟蒻初学单片机的一丢丢笔记
    Java实现栈和队列
    【QT】窗口的大小标题图标设置
  • 原文地址:https://blog.csdn.net/lwpoor123/article/details/134056575