最近有好几个网上的朋友都问到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 motorup 5
#define motordown 6
#define motorleft 9
#define motorright 10
#define center 0x7F
#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 L1 R1 /\ 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 = Left 0xFF = Right
07 idle data Right Joy 0x00 = Up 0xFF = Down
08 idle data Left Joy 0x00 = Left 0xFF = Right
09 idle data Left Joy 0x00 = Up 0xFF = Down
--------------------------------------------------------------------------------
下面是各个按键的名称及具体数值(在库内的源码里面有的)
// Button Hex Representations:
//hat
#define psxLeft 0x0080
#define psxDown 0x0040
#define psxRight 0x0020
#define psxUp 0x0010
#define psxStrt 0x0008
#define psxSlct 0x0001
//buttons
#define psxSqu 0x8000
#define psxX 0x4000
#define psxO 0x2000
#define psxTri 0x1000
#define psxR1 0x0800
#define psxL1 0x0400
#define psxL2 0x0100
#define psxR2 0x0200
#define psxJoyL 0x0002
#define psxJoyR 0x0004
//other defines
#define psxAnalog 0x01
#define psxDigital 0x00
再此感谢大家对本人的支持! 我也会继续努力,和大家分享经验与心得。更多内容请访问我的博客http://blog.sina.com.cn/happys1981
[ 本帖最后由 happys 于 2012-4-18 09:25 编辑 ] |