手柄转接板+microPython"/>
ESP32+PS2 无线手柄转接板+microPython
from machine import Pin
import timedi = Pin(26,Pin.IN,Pin.PULL_UP) # dat/di ESP32接26脚 或 接ESP8266的D5脚=14
do = Pin(27,Pin.OUT) # cmd/do ESP32接27脚 或 接ESP8266的D6脚=12
cs = Pin(14,Pin.OUT) # cs ESP32接14脚 或 接ESP8266的D7脚=13
clk = Pin(12,Pin.OUT) # clk ESP32接12脚 或 接ESP8266的D8脚=15def DO_H():do.value(1)
def DO_L():do.value(0)
def CS_H ():cs.value(1)
def CS_L():cs.value(0)
def CLK_H ():clk.value(1)
def CLK_L():clk.value(0)
#These are our button constants
PSB_SELECT = 1
PSB_L3 = 2
PSB_R3 = 3
PSB_START = 4
PSB_PAD_UP = 5
PSB_PAD_RIGHT = 6
PSB_PAD_DOWN = 7
PSB_PAD_LEFT = 8
PSB_L2 = 9
PSB_R2 = 10
PSB_L1 = 11
PSB_R1 = 12
PSB_GREEN = 13
PSB_RED = 14
PSB_BLUE = 15
PSB_PINK = 16
PSB_TRIANGLE = 13
PSB_CIRCLE = 14
PSB_CROSS = 15
PSB_SQUARE = 16
PSS_RX = 5
PSS_RY = 6
PSS_LX = 7
PSS_LY = 8
mask=[PSB_SELECT,PSB_L3,PSB_R3 ,PSB_START,PSB_PAD_UP,PSB_PAD_RIGHT,PSB_PAD_DOWN,PSB_PAD_LEFT,PSB_L2,PSB_R2,PSB_L1,PSB_R1 ,PSB_GREEN,PSB_RED,PSB_BLUE,PSB_PINK ]
comd=[0x01,0x42]
data=[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]def ps2_init():CLK_H()DO_H()time.sleep_ms(100)def ps2_cmd(cmd):global datadata[1]=0for ref in (1,2,4,8,16,32,64,128):if ( ref & cmd):DO_H()else:DO_L()CLK_H ()time.sleep_us(50)CLK_L()time.sleep_us(50)CLK_H ()if(di.value()==1):data[1]=ref|data[1]def ps2_red():global dataglobal comdCS_L()ps2_cmd(comd[0])ps2_cmd(comd[1])CS_H()if(data[1]==57):return 0 #red lightelse:return 1 #not reddef ps2_read():global dataglobal comdbyte=0ref=0x01CS_L()ps2_cmd(comd[0])ps2_cmd(comd[1])for byte in (2,3,4,5,6,7,8):for ref in (1,2,4,8,16,32,64,128):CLK_H ()CLK_L()time.sleep_us(50)CLK_H ()if(di.value()==1):data[byte]= ref|data[byte]time.sleep_us(50)CS_H ()def ps2_clear():#okglobal datafor i in range(0,9,1):data[i]=0def ps2_andata(button):global datareturn data[button]def ps2_key():global dataglobal maskps2_clear()ps2_read()handkey=(data[4]<<8)|data[3]for index in (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15):if (( handkey&(1<<(mask[index]-1)))==0):return index+2return 0print("等待按键中......")
while True:if ps2_key():print(ps2_key())time.sleep(0.1)
另一个版本的PS2代码,支持多按键同时检测,比较好用:
感谢作者,原代码地址如下:
以下为我修改后的代码,方便了调用。 可以保存为ps2.py,以备调用
import time
from machine import Pinclass PS2Controller:# These are our button constantsSELECT = 1L3 = 2R3 = 3START = 4UP = 5RIGHT = 6DOWN = 7LEFT = 8L2 = 9R2 = 10L1 = 11R1 = 12TRIANGLE = 13CIRCLE = 14CROSS = 15SQUARE = 16KEYS = 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 = 10CTRL_BYTE_DELAY = 16CMD_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 analog0x03, # 03 lock; ee no lock0x00, 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 = 1500VALID_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_noself.do_pin_no = do_pin_noself.cs_pin_no = cs_pin_noself.clk_pin_no = clk_pin_noself.di = Pin(self.di_pin_no, Pin.IN) # DI = DATself.do = Pin(self.do_pin_no, Pin.OUT) # DO = CMDself.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] * 9self.pressed_keys = []self.read_delay = 1self.last_read_ms = 0self.lx = 0self.ly = 0self.rx = 0self.ry = 0@propertydef red_mode(self): # analog modereturn self.buff_in[1] & 0xf0 == 0x70def 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 PyUnresolvedReferencesdef delay_byte(self):time.sleep_us(self.read_delay)# noinspection PyUnresolvedReferencesdef delay_clk(self):time.sleep_us(self.CTRL_CLK)# noinspection PyUnresolvedReferencesdef delay_read(self):time.sleep_us(self.CTRL_BYTE_DELAY)# time.sleep_ms(self.read_delay)def cmd(self, cmd):ret = 0for 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 << iself.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 1self.read_delay = 1for 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)breakelse:self.read_delay += 1print("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] - 128self.ry = self.buff_in[6] - 128self.lx = self.buff_in[7] - 128self.ly = self.buff_in[8] - 128if 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_msif delay > self.MAX_READ_DELAY:print(now, self.last_read_ms, delay)self.reconfig()elif delay < self.read_delay:# noinspection PyUnresolvedReferencestime.sleep_ms(self.read_delay - delay)self.buff_in = [0] * 9self.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:breakelse: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 += 1self.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] - 128self.ry = self.buff_in[6] - 128self.lx = self.buff_in[7] - 128self.ly = self.buff_in[8] - 128if 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_inreturn 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)
'''
原文链接:
更多推荐
ESP32+PS2 无线手柄转接板+microPython
发布评论