When I bought it, I came with a connector. The wire inside this connector is thick, and ordinary DuPont wire cannot be used.
Be sure not to connect the positive and negative poles incorrectly. You can also input 3.3v voltage:
from machine import Pin import time di = Pin(26,Pin.IN,Pin.PULL_UP) # dat/di Connect ESP32 to pin 26 or connect ESP8266’s D5 pin=14 do = Pin(27,Pin.OUT) # cmd/do Connect ESP32 to pin 27 or connect ESP8266’s D6 pin=12 cs = Pin(14,Pin.OUT) # cs ESP32 is connected to pin 14 or D7 pin of ESP8266=13 clk = Pin(12,Pin.OUT) # clk Connect ESP32 to pin 12 or connect ESP8266’s D8 pin=15 def 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 data data[1]=0 for ref in (1,2,4,8,16,32,64,128): if (ref & amp; 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 data globalcomd CS_L() ps2_cmd(comd[0]) ps2_cmd(comd[1]) CS_H() if(data[1]==57): return 0 #red light else: return 1 #not red def ps2_read(): global data globalcomd byte=0 ref=0x01 CS_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():#ok global data for i in range(0,9,1): data[i]=0 def ps2_andata(button): global data return data[button] def ps2_key(): global data global mask ps2_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 & amp;(1<<(mask[index]-1)))==0): return index + 2 return 0 print("Waiting for key press...") while True: if ps2_key(): print(ps2_key()) time.sleep(0.1)
Another version of the PS2 code supports simultaneous detection of multiple keys, which is easier to use:
Thanks to the author, the original code address is as follows: https://github.com/shallwe/micropython_ps2
The following is my modified code to facilitate calling. Can be saved as ps2.py for later use
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) '''
running result:
Original link: https://www.jianshu.com/p/30723e5624ae