happys 发表于 2012-4-18 09:05:05

arduino的PSX手柄库的修正及用法

       最近有好几个网上的朋友都问到PSX手柄程序的问题,就先给大家更新一下arduino中PSx手柄库的用法。

    原本网上下载的PSX库是有问题的,有很多杂牌的PS手柄都不能很好的兼容。经过我详细的查看了PS手柄协议及分析了psx库的程序后,修改了一个库中的错误后,现在我测试了几个牌子的手柄等能很好的兼容。其修改地方如下:

由于psx协议中是 “数据线的逻辑电平在时钟下降沿驱动下触发改变”这说明应该先置位数据,然后再是时钟由高电平跳变到低电平。但库中却是先时钟拉低,再对数据位置位,这就造成了很多山寨手柄的不兼容。具体如下图


Psx库可以自己修改Psx_analog.cpp,也可以下载我修改好的。

下载地址:

115网盘http://115.com/file/be7iodk9#
Psx_analog.zip

http://115.com/file/c2hs6dqh#
索尼+PLAYSTATION手柄原理分析.pdf


接下来就说说PSX库的具体用法



库里面自带了例程,这样用起来就比较方便了。

具体例程如下(里面我加了一些中文的说明)#include "Psx_analog.h"   // Includes the Psx Library
#define dataPin 14   //接线定义,总共需要4根数据线,根据自己的接线更改
#define cmndPin 15
#define attPin 16
#define clockPin 17
#define motorup5
#define motordown 6
#define motorleft9
#define motorright 10
#define center0x7F
#define LEDPin 13

Psx Psx;   // Initializes the library

void setup()
{
Psx.setupPins(dataPin, cmndPin, attPin, clockPin);// Defines what each pin is used
//在这个语句内部有把Motorsmall = 0x00;Motorlarge = 0x00;具体可以查看Psx_analog.cpp源码
Psx.initcontroller(psxAnalog);   
pinMode(LEDPin, OUTPUT);   // Establishes LEDPin as an output so the LED can be seen
//setup motoroutputs
pinMode(motorup, OUTPUT);    // Establishes LEDPin as an output so the LED can be seen
pinMode(motordown, OUTPUT);   // Establishes LEDPin as an output so the LED can be seen
pinMode(motorleft, OUTPUT);   // Establishes LEDPin as an output so the LED can be seen
pinMode(motorright, OUTPUT);    // Establishes LEDPin as an output so the LED can be seen
Serial.begin(9600);
Serial.println("Raw controller values");
// wait for the long string to be sent
delay(100);
}
void loop()
{
Motorsmall = 0xFF;
Motorlarge = 0xFF;//对震动电机震动大小进行赋值,赋值的数值在0x00到0xFF之间,0x00表示不震动,0xFF表示最大震动。
Psx.poll();// Psx.read() initiates the PSX controller and returns
Serial.print("\n");// the button data
Serial.print(Psx.Controller_mode, HEX);    // prints value as string in hexadecimal (base 16)
Serial.print(Psx.digital_buttons, HEX);    // prints value as string in hexadecimal (base 16)
Serial.print(Psx.Right_x, HEX);   // prints value as string in hexadecimal (base 16)   
Serial.print(Psx.Right_y, HEX);   // prints value as string in hexadecimal (base 16)   
Serial.print(Psx.Left_x, HEX);   // prints value as string in hexadecimal (base 16)   
Serial.print(Psx.Left_y, HEX);   // prints value as string in hexadecimal (base 16)   
if (Psx.digital_buttons & psxR2)// If the data anded with a button's hex value is true,
    // it signifies the button is pressed. Hex values for each
    // button can be found in Psx.h
{
    digitalWrite(LEDPin, HIGH);// If button is pressed, turn on the LED
}
else
{
    digitalWrite(LEDPin, LOW);// If the button isn't pressed, turn off the LED
}
delay(100);
}
怕麻烦的可以直接拷贝例程来修改,至于像arduino的语法等等就不用再叙述了,不懂的可以自己找找教程学习。我还要说的是关于手柄震动的问题,在Psx.poll();语句的前面加上对Motorsmall = 0xFF;Motorlarge = 0xFF;的赋值语句就可以使大小电机震动,赋值的数值在0x00到0xFF之间,0x00表示不震动,0xFF表示最大震动。具体震动的数据是在Psx.poll();语句中传给手柄的,详细的可以查看Psx_analog.cpp源码。

顺便把例程里的资料说明也放下面

--------------------------------------------------------------------------------
    Standard Digital Pad

    BYTE    CMND    DATA

   01   0x01    idle
   02   0x42    0x41
   03   idle    0x5A    Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
   04   idle    data    SLCT         STRT UP   RGHT DOWN LEFT
   05   idle    data    L2   R2    L1R1   /\   O    X    |_|

    All Buttons active low.

--------------------------------------------------------------------------------
    Analogue Controller in Red Mode

    BYTE    CMND    DATA

   01   0x01    idle
   02   0x42    0x73
   03   idle    0x5A    Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
   04   idle    data    SLCT JOYR JOYL STRT UP   RGHT DOWN LEFT
   05   idle    data    L2   R2   L1   R1   /\   O    X    |_|
   06   idle    data    Right Joy 0x00 = Left0xFF = Right
   07   idle    data    Right Joy 0x00 = Up    0xFF = Down
   08   idle    data    Left Joy0x00 = Left0xFF = Right
   09   idle    data    Left Joy0x00 = Up    0xFF = Down
--------------------------------------------------------------------------------

下面是各个按键的名称及具体数值(在库内的源码里面有的)// Button Hex Representations:
//hat
#define psxLeft0x0080
#define psxDown0x0040
#define psxRight 0x0020
#define psxUp0x0010
#define psxStrt0x0008
#define psxSlct0x0001

//buttons
#define psxSqu0x8000
#define psxX0x4000
#define psxO0x2000
#define psxTri0x1000
#define psxR10x0800
#define psxL10x0400
#define psxL20x0100
#define psxR20x0200
#define psxJoyL0x0002
#define psxJoyR0x0004
//other defines
#define psxAnalog 0x01
#define psxDigital 0x00再此感谢大家对本人的支持! 我也会继续努力,和大家分享经验与心得。欢迎大家访问我的博客http://blog.sina.com.cn/happys1981


开心就好 发表于 2012-4-19 10:29:21

好贴,顶一个

loneress 发表于 2012-4-19 14:58:00

组合键要手工分离出来,库文件里面好像没有考虑组合键的分离问题。

迷你强 发表于 2012-4-19 22:09:30

:funk:传说中的神贴。。。。

alen 发表于 2014-4-14 15:49:58

你好,我编译之后,出现那种情况请问是为什么
页: [1]
查看完整版本: arduino的PSX手柄库的修正及用法