单片机学习小组
直播中

张生

9年用户 785经验值
擅长:光电显示 接口/总线/驱动
私信 关注

如何使用PS2手柄实现远程遥控?

如何使用PS2手柄实现远程遥控?

回帖(1)

陈蓓萤

2022-2-7 10:35:53
PS2遥控手柄

此处使用的是较为低级便宜的PS2遥控手柄,不过可以实现绝大部分的控制基本功能,有想玩更丝滑的无级变速之类的小伙伴可以去买更为高级的手柄~

遥控原理

遥控器端有信号发送装置,接收端具有接收装置,将PS2的接收装置与PYB相连,即可完成接收器与单片机的接线。每当在遥控器端按下一个按键时,接收端即可接收到一个固定的字符串(或数字),代表这个按键,所以通过不同按键对应的数字,我们即可得到这个按键是什么,再对他进行相应的个性化配置即可。
接线

[tr]PS2手柄PYB[/tr]
VCC3V3
GNDGND
DATX18
CMDX19
CSX20
CLKX21

代码
PS2手柄库文件
ps2.py


import pyb
from pyb import Pin
import time


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           = 26
PSS_RX = 5                                  #x
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]


class PS2KEY:
        #使用定义: PS2KEY('X18','X19','X20','X21')
        def __init__(self,_di,_do,_cs,_clk):
               
                self.di=Pin(_di,Pin.IN,Pin.PULL_DOWN)
                self.do=Pin(_do,Pin.OUT_PP)
                self.cs=Pin(_cs,Pin.OUT_PP)
                self.clk=Pin(_clk,Pin.OUT_PP)


                self.ps2_init()
                self.ps2_red()
       
        def ps2_init(self):
                self.clk.value(1)
                self.do.value(1)
                time.sleep_ms(10)
               
        def ps2_cmd(self,cmd):
                global data
                data[1]=0
                for ref in (1,2,4,8,16,32,64,128):
                  if ( ref & cmd):
                   self.do.value(1)
                  else:
                   self.do.value(0)
                  self.clk.value(1)
                  time.sleep_us(10)
                  self.clk.value(0)
                  time.sleep_us(10)
                  self.clk.value(1)
                  if(self.di.value()==1):
                   data[1]=ref|data[1]
                  
        def ps2_red(self):
                global data
                global comd
                self.cs.value(0)
                self.ps2_cmd(comd[0])
                self.ps2_cmd(comd[1])
                self.cs.value(1)
                if(data[1]==57):
                  return 0#red light
                else:
                  return 1#not red
                  
        def ps2_read(self):
                global data
                global comd
                byte=0
                ref=0x01
                self.cs.value(0)
                self.ps2_cmd(comd[0])
                self.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):
                   self.clk.value(1)
                   self.clk.value(0)
                   time.sleep_us(10)
                   self.clk.value(1)
                   if(self.di.value()==1):
                        data[byte]= ref|data[byte]
                  time.sleep_us(10)
                self.cs.value(1)
               
        def ps2_clear(self):#ok
                global data
                for i in range(0,9,1):
                  data=0
       
        #获取摇杆电位值(0-255模拟量)
        def ps2_andata(self,button):
                global data
                return data[button]
       
        #获取按键值
        def ps2_key(self):
                global data
                global mask
                self.ps2_clear()
                self.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+2
                return 0
指令接收主程序
函数解析
获取按键值
ps=ps2.PS2KEY('X18','X19','X20','X21')
key = ps2_key() # 获取按键值key
获取摇杆值
ps=ps2.PS2KEY('X18','X19','X20','X21')
an_key = ps2_andata(5) # 获取按键值key
主程序
# main.py -- put your code here!
import ps2


while True:
      ps=ps2.PS2KEY('X18','X19','X20','X21')
      a=ps.ps2_key()  #读取手柄键值
      if(a==13):              #判断按键执行相关灯的开关
              pyb.LED(1).on()
      elif(a==14):
              pyb.LED(2).on()
      elif(a==15):
              pyb.LED(3).on()
      elif(a==16):
              pyb.LED(4).on()
      elif(a==5):
              pyb.LED(1).off()
      elif(a==6):
              pyb.LED(2).off()
      elif(a==7):
              pyb.LED(3).off()
      elif(a==8):
              pyb.LED(4).off()


按键对应数据图

博主自己测试了整个按键对应的数字编号,读者可以直接使用~

摇杆值对应的数组详解

我在这里测试了一下各个摇杆值对应数组中的值,发现:

data[5]、data[6]、data[7]、data[8]


  • data[8]:左边上下摇杆,中间值为191,向上为128,向下为255
  • data[7]:左边左右摇杆,中间值为192 ,向左为128,向右为255
  • data[6]:右边上下摇杆,中间值为191 ,向上为128,向下为255
  • data[5]:右边左右摇杆,中间值为 192,向左为128,向右为255

举报

更多回帖

×
20
完善资料,
赚取积分