From 64897551849afae8fd9801376576dcf10acf010d Mon Sep 17 00:00:00 2001 From: yanghuaiyuan Date: Sun, 8 Mar 2020 12:45:27 +0800 Subject: [PATCH 01/16] add esp32 --- PS2X_lib/PS2X_lib.cpp => PS2X_lib.cpp | 0 PS2X_lib/PS2X_lib.h => PS2X_lib.h | 0 README.md | 0 .../PS2XMouse/PS2XMouse.ino | 0 .../PS2X_Example/PS2X_Example.ino | 0 examples/PS2X_Example_ESP32/PS2X_Example.ino | 189 ++++++++++++++++++ PS2X_lib/keywords.txt => keywords.txt | 0 7 files changed, 189 insertions(+) rename PS2X_lib/PS2X_lib.cpp => PS2X_lib.cpp (100%) rename PS2X_lib/PS2X_lib.h => PS2X_lib.h (100%) create mode 100644 README.md rename {PS2X_lib/examples => examples}/PS2XMouse/PS2XMouse.ino (100%) rename {PS2X_lib/examples => examples}/PS2X_Example/PS2X_Example.ino (100%) create mode 100644 examples/PS2X_Example_ESP32/PS2X_Example.ino rename PS2X_lib/keywords.txt => keywords.txt (100%) diff --git a/PS2X_lib/PS2X_lib.cpp b/PS2X_lib.cpp similarity index 100% rename from PS2X_lib/PS2X_lib.cpp rename to PS2X_lib.cpp diff --git a/PS2X_lib/PS2X_lib.h b/PS2X_lib.h similarity index 100% rename from PS2X_lib/PS2X_lib.h rename to PS2X_lib.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/PS2X_lib/examples/PS2XMouse/PS2XMouse.ino b/examples/PS2XMouse/PS2XMouse.ino similarity index 100% rename from PS2X_lib/examples/PS2XMouse/PS2XMouse.ino rename to examples/PS2XMouse/PS2XMouse.ino diff --git a/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino b/examples/PS2X_Example/PS2X_Example.ino similarity index 100% rename from PS2X_lib/examples/PS2X_Example/PS2X_Example.ino rename to examples/PS2X_Example/PS2X_Example.ino diff --git a/examples/PS2X_Example_ESP32/PS2X_Example.ino b/examples/PS2X_Example_ESP32/PS2X_Example.ino new file mode 100644 index 0000000..f1c64c8 --- /dev/null +++ b/examples/PS2X_Example_ESP32/PS2X_Example.ino @@ -0,0 +1,189 @@ +#include //for v1.6 + +/****************************************************************** + * set pins connected to PS2 controller: + * - 1e column: original + * - 2e colmun: Stef? + * replace pin numbers by the ones you use + ******************************************************************/ +#define PS2_DAT 13 //14 +#define PS2_CMD 11 //15 +#define PS2_SEL 10 //16 +#define PS2_CLK 12 //17 + +/****************************************************************** + * select modes of PS2 controller: + * - pressures = analog reading of push-butttons + * - rumble = motor rumbling + * uncomment 1 of the lines for each mode selection + ******************************************************************/ +//#define pressures true +#define pressures false +//#define rumble true +#define rumble false + +PS2X ps2x; // create PS2 Controller Class + +//right now, the library does NOT support hot pluggable controllers, meaning +//you must always either restart your Arduino after you connect the controller, +//or call config_gamepad(pins) again after connecting the controller. + +int error = 0; +byte type = 0; +byte vibrate = 0; + +void setup(){ + + Serial.begin(57600); + + delay(300); //added delay to give wireless ps2 module some time to startup, before configuring it + + //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* + + //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); + + if(error == 0){ + Serial.print("Found Controller, configured successful "); + Serial.print("pressures = "); + if (pressures) + Serial.println("true "); + else + Serial.println("false"); + Serial.print("rumble = "); + if (rumble) + Serial.println("true)"); + else + Serial.println("false"); + Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); + Serial.println("holding L1 or R1 will print out the analog stick values."); + Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); + } + else if(error == 1) + Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); + + else if(error == 2) + Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); + + else if(error == 3) + Serial.println("Controller refusing to enter Pressures mode, may not support it. "); + +// Serial.print(ps2x.Analog(1), HEX); + + type = ps2x.readType(); + switch(type) { + case 0: + Serial.print("Unknown Controller type found "); + break; + case 1: + Serial.print("DualShock Controller found "); + break; + case 2: + Serial.print("GuitarHero Controller found "); + break; + case 3: + Serial.print("Wireless Sony DualShock Controller found "); + break; + } +} + +void loop() { + /* You must Read Gamepad to get new values and set vibration values + ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255) + if you don't enable the rumble, use ps2x.read_gamepad(); with no values + You should call this at least once a second + */ + if(error == 1) //skip loop if no controller found + return; + + if(type == 2){ //Guitar Hero Controller + ps2x.read_gamepad(); //read controller + + if(ps2x.ButtonPressed(GREEN_FRET)) + Serial.println("Green Fret Pressed"); + if(ps2x.ButtonPressed(RED_FRET)) + Serial.println("Red Fret Pressed"); + if(ps2x.ButtonPressed(YELLOW_FRET)) + Serial.println("Yellow Fret Pressed"); + if(ps2x.ButtonPressed(BLUE_FRET)) + Serial.println("Blue Fret Pressed"); + if(ps2x.ButtonPressed(ORANGE_FRET)) + Serial.println("Orange Fret Pressed"); + + if(ps2x.ButtonPressed(STAR_POWER)) + Serial.println("Star Power Command"); + + if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed + Serial.println("Up Strum"); + if(ps2x.Button(DOWN_STRUM)) + Serial.println("DOWN Strum"); + + if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed + Serial.println("Start is being held"); + if(ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE + Serial.print("Wammy Bar Position:"); + Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); + } + } + else { //DualShock Controller + ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed + + if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed + Serial.println("Start is being held"); + if(ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed + Serial.print("Up held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); + } + if(ps2x.Button(PSB_PAD_RIGHT)){ + Serial.print("Right held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); + } + if(ps2x.Button(PSB_PAD_LEFT)){ + Serial.print("LEFT held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); + } + if(ps2x.Button(PSB_PAD_DOWN)){ + Serial.print("DOWN held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); + } + + vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button + if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) + if(ps2x.Button(PSB_L3)) + Serial.println("L3 pressed"); + if(ps2x.Button(PSB_R3)) + Serial.println("R3 pressed"); + if(ps2x.Button(PSB_L2)) + Serial.println("L2 pressed"); + if(ps2x.Button(PSB_R2)) + Serial.println("R2 pressed"); + if(ps2x.Button(PSB_TRIANGLE)) + Serial.println("Triangle pressed"); + } + + if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed + Serial.println("Circle just pressed"); + if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released + Serial.println("X just changed"); + if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released + Serial.println("Square just released"); + + if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE + Serial.print("Stick Values:"); + Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX + Serial.print(","); + Serial.print(ps2x.Analog(PSS_LX), DEC); + Serial.print(","); + Serial.print(ps2x.Analog(PSS_RY), DEC); + Serial.print(","); + Serial.println(ps2x.Analog(PSS_RX), DEC); + } + } + delay(50); +} diff --git a/PS2X_lib/keywords.txt b/keywords.txt similarity index 100% rename from PS2X_lib/keywords.txt rename to keywords.txt From 54fe8253b0e5914965dab963cef087d20fe3c8c0 Mon Sep 17 00:00:00 2001 From: yanghuaiyuan Date: Sun, 8 Mar 2020 12:48:27 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PS2X_lib.cpp | 6 +++--- PS2X_lib.h | 4 ++-- README.md | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/PS2X_lib.cpp b/PS2X_lib.cpp index 74ef0f7..2c96697 100644 --- a/PS2X_lib.cpp +++ b/PS2X_lib.cpp @@ -181,7 +181,7 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bo _dat_mask = digitalPinToBitMask(dat); _dat_ireg = portInputRegister(digitalPinToPort(dat)); #else -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) _clk_pin = clk; _cmd_pin = cmd; _att_pin = att; @@ -211,7 +211,7 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bo pinMode(clk, OUTPUT); //configure ports pinMode(att, OUTPUT); pinMode(cmd, OUTPUT); -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) pinMode(dat, INPUT_PULLUP); // enable pull-up #else pinMode(dat, INPUT); @@ -449,7 +449,7 @@ inline bool PS2X::DAT_CHK(void) { } #else -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) // Let's just use digitalWrite() on ESP8266. inline void PS2X::CLK_SET(void) { digitalWrite(_clk_pin, HIGH); diff --git a/PS2X_lib.h b/PS2X_lib.h index 303f0e7..3261fbe 100644 --- a/PS2X_lib.h +++ b/PS2X_lib.h @@ -95,7 +95,7 @@ GNU General Public License for more details. #define CTRL_CLK 4 #define CTRL_BYTE_DELAY 3 #else -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) #define CTRL_CLK 5 #define CTRL_CLK_HIGH 5 #define CTRL_BYTE_DELAY 18 @@ -217,7 +217,7 @@ class PS2X { uint8_t _dat_mask; volatile uint8_t *_dat_ireg; #else - #ifdef ESP8266 + #if defined(ESP8266) || defined(ESP32) int _clk_pin; int _cmd_pin; int _att_pin; diff --git a/README.md b/README.md index e69de29..62287cb 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,16 @@ +## NOTE + +fork from: https://github.com/madsci1016/Arduino-PS2X + +## PS2X 项目 + +之前的项目不支持 ESP32,本来打算用,折腾下ESP32,解决相关兼容问题。 + +调整了下目录结构,直接克隆项目到 /arduino/libraries 目录下。 + +``` +替换: +#ifdef ESP8266 +成: +#if defined(ESP8266) || defined(ESP32) +``` \ No newline at end of file From b63259958c2518f81a0f95917db95b4da9410245 Mon Sep 17 00:00:00 2001 From: yhy Date: Sun, 8 Mar 2020 15:50:17 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 38 ++++ examples/PS2X_Example_ESP32/PS2X_Example.ino | 189 ------------------ .../PS2X_Example_ESP32/PS2X_Example_ESP32.ino | 137 +++++++++++++ 3 files changed, 175 insertions(+), 189 deletions(-) delete mode 100644 examples/PS2X_Example_ESP32/PS2X_Example.ino create mode 100755 examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino diff --git a/README.md b/README.md index 62287cb..d2f1241 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,42 @@ fork from: https://github.com/madsci1016/Arduino-PS2X #ifdef ESP8266 成: #if defined(ESP8266) || defined(ESP32) +``` + +## 修改 setup 函数 + + + +``` + while (error != 0) { + delay(1000);// 1 second wait + //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); + Serial.print("#try config "); + Serial.println(tryNum); + tryNum ++; + } +``` + +使用ESP32 测试: + +https://github.com/MyArduinoLib/Arduino-PS2X-ESP32/blob/master/examples/PS2X_Example_ESP32/PS2X_Example.ino + +启动日志: + +``` +15:41:44.363 -> #try config 1 +15:41:45.392 -> #try config 2 +15:41:45.392 -> 73 +15:41:45.392 -> Controller_type: 3 +15:41:45.392 -> DualShock Controller found +15:41:45.392 -> Start is being held +15:41:45.392 -> Select is being held +15:41:45.392 -> Up held this hard: 0 +15:41:45.392 -> Right held this hard: 0 +15:41:45.392 -> LEFT held this hard: 0 +15:41:45.392 -> DOWN held this hard: 0 +15:41:45.392 -> Stick Values:0,0,0,0 +15:41:45.459 -> × just changed +15:41:45.459 -> □ just released ``` \ No newline at end of file diff --git a/examples/PS2X_Example_ESP32/PS2X_Example.ino b/examples/PS2X_Example_ESP32/PS2X_Example.ino deleted file mode 100644 index f1c64c8..0000000 --- a/examples/PS2X_Example_ESP32/PS2X_Example.ino +++ /dev/null @@ -1,189 +0,0 @@ -#include //for v1.6 - -/****************************************************************** - * set pins connected to PS2 controller: - * - 1e column: original - * - 2e colmun: Stef? - * replace pin numbers by the ones you use - ******************************************************************/ -#define PS2_DAT 13 //14 -#define PS2_CMD 11 //15 -#define PS2_SEL 10 //16 -#define PS2_CLK 12 //17 - -/****************************************************************** - * select modes of PS2 controller: - * - pressures = analog reading of push-butttons - * - rumble = motor rumbling - * uncomment 1 of the lines for each mode selection - ******************************************************************/ -//#define pressures true -#define pressures false -//#define rumble true -#define rumble false - -PS2X ps2x; // create PS2 Controller Class - -//right now, the library does NOT support hot pluggable controllers, meaning -//you must always either restart your Arduino after you connect the controller, -//or call config_gamepad(pins) again after connecting the controller. - -int error = 0; -byte type = 0; -byte vibrate = 0; - -void setup(){ - - Serial.begin(57600); - - delay(300); //added delay to give wireless ps2 module some time to startup, before configuring it - - //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* - - //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error - error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); - - if(error == 0){ - Serial.print("Found Controller, configured successful "); - Serial.print("pressures = "); - if (pressures) - Serial.println("true "); - else - Serial.println("false"); - Serial.print("rumble = "); - if (rumble) - Serial.println("true)"); - else - Serial.println("false"); - Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); - Serial.println("holding L1 or R1 will print out the analog stick values."); - Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); - } - else if(error == 1) - Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); - - else if(error == 2) - Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); - - else if(error == 3) - Serial.println("Controller refusing to enter Pressures mode, may not support it. "); - -// Serial.print(ps2x.Analog(1), HEX); - - type = ps2x.readType(); - switch(type) { - case 0: - Serial.print("Unknown Controller type found "); - break; - case 1: - Serial.print("DualShock Controller found "); - break; - case 2: - Serial.print("GuitarHero Controller found "); - break; - case 3: - Serial.print("Wireless Sony DualShock Controller found "); - break; - } -} - -void loop() { - /* You must Read Gamepad to get new values and set vibration values - ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255) - if you don't enable the rumble, use ps2x.read_gamepad(); with no values - You should call this at least once a second - */ - if(error == 1) //skip loop if no controller found - return; - - if(type == 2){ //Guitar Hero Controller - ps2x.read_gamepad(); //read controller - - if(ps2x.ButtonPressed(GREEN_FRET)) - Serial.println("Green Fret Pressed"); - if(ps2x.ButtonPressed(RED_FRET)) - Serial.println("Red Fret Pressed"); - if(ps2x.ButtonPressed(YELLOW_FRET)) - Serial.println("Yellow Fret Pressed"); - if(ps2x.ButtonPressed(BLUE_FRET)) - Serial.println("Blue Fret Pressed"); - if(ps2x.ButtonPressed(ORANGE_FRET)) - Serial.println("Orange Fret Pressed"); - - if(ps2x.ButtonPressed(STAR_POWER)) - Serial.println("Star Power Command"); - - if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed - Serial.println("Up Strum"); - if(ps2x.Button(DOWN_STRUM)) - Serial.println("DOWN Strum"); - - if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed - Serial.println("Start is being held"); - if(ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); - - if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE - Serial.print("Wammy Bar Position:"); - Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); - } - } - else { //DualShock Controller - ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed - - if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed - Serial.println("Start is being held"); - if(ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); - - if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed - Serial.print("Up held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); - } - if(ps2x.Button(PSB_PAD_RIGHT)){ - Serial.print("Right held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); - } - if(ps2x.Button(PSB_PAD_LEFT)){ - Serial.print("LEFT held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); - } - if(ps2x.Button(PSB_PAD_DOWN)){ - Serial.print("DOWN held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); - } - - vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button - if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) - if(ps2x.Button(PSB_L3)) - Serial.println("L3 pressed"); - if(ps2x.Button(PSB_R3)) - Serial.println("R3 pressed"); - if(ps2x.Button(PSB_L2)) - Serial.println("L2 pressed"); - if(ps2x.Button(PSB_R2)) - Serial.println("R2 pressed"); - if(ps2x.Button(PSB_TRIANGLE)) - Serial.println("Triangle pressed"); - } - - if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed - Serial.println("Circle just pressed"); - if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released - Serial.println("X just changed"); - if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released - Serial.println("Square just released"); - - if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE - Serial.print("Stick Values:"); - Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX - Serial.print(","); - Serial.print(ps2x.Analog(PSS_LX), DEC); - Serial.print(","); - Serial.print(ps2x.Analog(PSS_RY), DEC); - Serial.print(","); - Serial.println(ps2x.Analog(PSS_RX), DEC); - } - } - delay(50); -} diff --git a/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino b/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino new file mode 100755 index 0000000..737fbeb --- /dev/null +++ b/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino @@ -0,0 +1,137 @@ +#include //for v1.6 + +/****************************************************************** + * set pins connected to PS2 controller: + * - 1e column: original + * - 2e colmun: Stef? + * replace pin numbers by the ones you use + ******************************************************************/ + +// ESP32 pin +// https://github.com/espressif/arduino-esp32/blob/master/docs/esp32_pinmap.png + +#define PS2_DAT 19 //MISO 19 +#define PS2_CMD 23 //MOSI 23 +#define PS2_SEL 5 //SS 5 +#define PS2_CLK 18 //SLK 18 + +/****************************************************************** + * select modes of PS2 controller: + * - pressures = analog reading of push-butttons + * - rumble = motor rumbling + * uncomment 1 of the lines for each mode selection + ******************************************************************/ +#define pressures false +#define rumble false + +PS2X ps2x; // create PS2 Controller Class + +//right now, the library does NOT support hot pluggable controllers, meaning +//you must always either restart your Arduino after you connect the controller, +//or call config_gamepad(pins) again after connecting the controller. + +int error = -1; +byte type = 0; +byte vibrate = 0; +int tryNum = 1; + +void setup(){ + + // 115200 + Serial.begin(115200); + + //added delay to give wireless ps2 module some time to startup, before configuring it + //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* + + while (error != 0) { + delay(1000);// 1 second wait + //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); + Serial.print("#try config "); + Serial.println(tryNum); + tryNum ++; + } + + Serial.println(ps2x.Analog(1), HEX); + + type = ps2x.readType(); + switch(type) { + case 0: + Serial.println(" Unknown Controller type found "); + break; + case 1: + Serial.println(" DualShock Controller found "); + break; + case 2: + Serial.println(" GuitarHero Controller found "); + break; + case 3: + Serial.println(" Wireless Sony DualShock Controller found "); + break; + } +} + +void loop() { + + if(type == 1){ //DualShock Controller + ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed + + //will be TRUE as long as button is pressed + if(ps2x.Button(PSB_START)) + Serial.println("Start is being held"); + if(ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + //will be TRUE as long as button is pressed + if(ps2x.Button(PSB_PAD_UP)) { + Serial.print("Up held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); + } + if(ps2x.Button(PSB_PAD_RIGHT)){ + Serial.print("Right held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); + } + if(ps2x.Button(PSB_PAD_LEFT)){ + Serial.print("LEFT held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); + } + if(ps2x.Button(PSB_PAD_DOWN)){ + Serial.print("DOWN held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); + } + + vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button + if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) + if(ps2x.Button(PSB_L3)) + Serial.println("L3 pressed"); + if(ps2x.Button(PSB_R3)) + Serial.println("R3 pressed"); + if(ps2x.Button(PSB_L2)) + Serial.println("L2 pressed"); + if(ps2x.Button(PSB_R2)) + Serial.println("R2 pressed"); + if(ps2x.Button(PSB_TRIANGLE)) + Serial.println("△ pressed"); + } + //△□○× + if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed + Serial.println("○ just pressed"); + if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released + Serial.println("× just changed"); + if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released + Serial.println("□ just released"); + + if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE + Serial.print("Stick Values:"); + Serial.print(ps2x.Analog(PSS_LY)); //Left stick, Y axis. Other options: LX, RY, RX + Serial.print(","); + Serial.print(ps2x.Analog(PSS_LX), DEC); + Serial.print(","); + Serial.print(ps2x.Analog(PSS_RY), DEC); + Serial.print(","); + Serial.println(ps2x.Analog(PSS_RX), DEC); + } + + } + delay(50); +} \ No newline at end of file From 73b932da37f519afebb3862d3d535bf840ba4e19 Mon Sep 17 00:00:00 2001 From: yhy Date: Sun, 8 Mar 2020 16:58:50 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2f1241..8e3cba7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ fork from: https://github.com/madsci1016/Arduino-PS2X 之前的项目不支持 ESP32,本来打算用,折腾下ESP32,解决相关兼容问题。 -调整了下目录结构,直接克隆项目到 /arduino/libraries 目录下。 +调整了下目录结构,https://github.com/MyArduinoLib/Arduino-PS2X-ESP32 直接克隆项目到 /arduino/libraries 目录下。 ``` 替换: @@ -32,7 +32,7 @@ fork from: https://github.com/madsci1016/Arduino-PS2X 使用ESP32 测试: -https://github.com/MyArduinoLib/Arduino-PS2X-ESP32/blob/master/examples/PS2X_Example_ESP32/PS2X_Example.ino +https://github.com/MyArduinoLib/Arduino-PS2X-ESP32/blob/master/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino 启动日志: From ef7692149c0788ff735628b950c2d22120d3de5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anh=20T=C3=BA=20Dang?= Date: Sat, 7 May 2022 20:57:38 +0700 Subject: [PATCH 05/16] init commit --- README.md | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8e3cba7..88f6dd9 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,15 @@ -## NOTE +## Giới thiệu -fork from: https://github.com/madsci1016/Arduino-PS2X +Thư viện tay cầm PS2 dành cho mạch VIA Makerbot ESP32 +Thư viện này giúp các bạn có thể sử dụng tay cầm PS2 cho mạch VIA Makerbot -## PS2X 项目 +Thư viện này là 1 bản sao thư viện tay cầm PS2 của 2 tác giả [madsci1016](https://github.com/madsci1016/Arduino-PS2X) và [MyArduinoLib](https://github.com/MyArduinoLib/Arduino-PS2X-ESP32) được chỉnh sửa lại để sử dụng với mạch VIA Makerbot ESP32 -之前的项目不支持 ESP32,本来打算用,折腾下ESP32,解决相关兼容问题。 +## Sử dụng thư viện PSX2 với mạch Makerbot BANHMI -调整了下目录结构,https://github.com/MyArduinoLib/Arduino-PS2X-ESP32 直接克隆项目到 /arduino/libraries 目录下。 -``` -替换: -#ifdef ESP8266 -成: -#if defined(ESP8266) || defined(ESP32) -``` -## 修改 setup 函数 +## Khởi tạo thư viện: @@ -30,11 +24,11 @@ fork from: https://github.com/madsci1016/Arduino-PS2X } ``` -使用ESP32 测试: +Ví dụ chạy với mạch VIA Makerbot BANHMI: https://github.com/MyArduinoLib/Arduino-PS2X-ESP32/blob/master/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino -启动日志: +Thông tin hiện ra trên Serial monitor Khi chạy ví dụ trên: ``` 15:41:44.363 -> #try config 1 @@ -51,4 +45,5 @@ https://github.com/MyArduinoLib/Arduino-PS2X-ESP32/blob/master/examples/PS2X_Exa 15:41:45.392 -> Stick Values:0,0,0,0 15:41:45.459 -> × just changed 15:41:45.459 -> □ just released -``` \ No newline at end of file +``` + From 195b7cc99759f763f82b7b0d2bef0fc4072f63c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anh=20T=C3=BA=20Dang?= Date: Sat, 7 May 2022 21:20:03 +0700 Subject: [PATCH 06/16] changes pin definition --- .../PS2X_Example_ESP32/PS2X_Example_ESP32.ino | 137 ---------------- .../PS2X_Example_VIA_Makerbot_ESP32.ino | 147 ++++++++++++++++++ 2 files changed, 147 insertions(+), 137 deletions(-) delete mode 100755 examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino create mode 100644 examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino diff --git a/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino b/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino deleted file mode 100755 index 737fbeb..0000000 --- a/examples/PS2X_Example_ESP32/PS2X_Example_ESP32.ino +++ /dev/null @@ -1,137 +0,0 @@ -#include //for v1.6 - -/****************************************************************** - * set pins connected to PS2 controller: - * - 1e column: original - * - 2e colmun: Stef? - * replace pin numbers by the ones you use - ******************************************************************/ - -// ESP32 pin -// https://github.com/espressif/arduino-esp32/blob/master/docs/esp32_pinmap.png - -#define PS2_DAT 19 //MISO 19 -#define PS2_CMD 23 //MOSI 23 -#define PS2_SEL 5 //SS 5 -#define PS2_CLK 18 //SLK 18 - -/****************************************************************** - * select modes of PS2 controller: - * - pressures = analog reading of push-butttons - * - rumble = motor rumbling - * uncomment 1 of the lines for each mode selection - ******************************************************************/ -#define pressures false -#define rumble false - -PS2X ps2x; // create PS2 Controller Class - -//right now, the library does NOT support hot pluggable controllers, meaning -//you must always either restart your Arduino after you connect the controller, -//or call config_gamepad(pins) again after connecting the controller. - -int error = -1; -byte type = 0; -byte vibrate = 0; -int tryNum = 1; - -void setup(){ - - // 115200 - Serial.begin(115200); - - //added delay to give wireless ps2 module some time to startup, before configuring it - //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* - - while (error != 0) { - delay(1000);// 1 second wait - //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error - error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); - Serial.print("#try config "); - Serial.println(tryNum); - tryNum ++; - } - - Serial.println(ps2x.Analog(1), HEX); - - type = ps2x.readType(); - switch(type) { - case 0: - Serial.println(" Unknown Controller type found "); - break; - case 1: - Serial.println(" DualShock Controller found "); - break; - case 2: - Serial.println(" GuitarHero Controller found "); - break; - case 3: - Serial.println(" Wireless Sony DualShock Controller found "); - break; - } -} - -void loop() { - - if(type == 1){ //DualShock Controller - ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed - - //will be TRUE as long as button is pressed - if(ps2x.Button(PSB_START)) - Serial.println("Start is being held"); - if(ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); - - //will be TRUE as long as button is pressed - if(ps2x.Button(PSB_PAD_UP)) { - Serial.print("Up held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); - } - if(ps2x.Button(PSB_PAD_RIGHT)){ - Serial.print("Right held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); - } - if(ps2x.Button(PSB_PAD_LEFT)){ - Serial.print("LEFT held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); - } - if(ps2x.Button(PSB_PAD_DOWN)){ - Serial.print("DOWN held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); - } - - vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button - if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) - if(ps2x.Button(PSB_L3)) - Serial.println("L3 pressed"); - if(ps2x.Button(PSB_R3)) - Serial.println("R3 pressed"); - if(ps2x.Button(PSB_L2)) - Serial.println("L2 pressed"); - if(ps2x.Button(PSB_R2)) - Serial.println("R2 pressed"); - if(ps2x.Button(PSB_TRIANGLE)) - Serial.println("△ pressed"); - } - //△□○× - if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed - Serial.println("○ just pressed"); - if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released - Serial.println("× just changed"); - if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released - Serial.println("□ just released"); - - if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE - Serial.print("Stick Values:"); - Serial.print(ps2x.Analog(PSS_LY)); //Left stick, Y axis. Other options: LX, RY, RX - Serial.print(","); - Serial.print(ps2x.Analog(PSS_LX), DEC); - Serial.print(","); - Serial.print(ps2x.Analog(PSS_RY), DEC); - Serial.print(","); - Serial.println(ps2x.Analog(PSS_RX), DEC); - } - - } - delay(50); -} \ No newline at end of file diff --git a/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino b/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino new file mode 100644 index 0000000..758a80e --- /dev/null +++ b/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino @@ -0,0 +1,147 @@ +#include //for v1.6 + +/****************************************************************** + * Cài đặt thư chân cho thư viện : + * - Trên mạch Motorshield của VIA Makerbot BANHMI, có header 6 chân + * được thiết kế để cắm tay cầm PS2. + * Sơ đồ chân header và sơ đồ GPIO tương ứng: + * MOSI | MISO | GND | 3.3V | CS | CLK + * 12 13 GND 3.3V 15 14 + * + ******************************************************************/ + +#define PS2_DAT 12 // MISO +#define PS2_CMD 13 // MOSI +#define PS2_SEL 15 // SS +#define PS2_CLK 14 // SLK + +/****************************************************************** + * Lựa chọn chế độ cho tay cầm PS2 : + * - pressures = đọc giá trị analog từ các nút bấm + * - rumble = bật/tắt chế độ rung + * uncomment 1 of the lines for each mode selection + ******************************************************************/ +#define pressures false +#define rumble false + +PS2X ps2x; // create PS2 Controller Class + +// right now, the library does NOT support hot pluggable controllers, meaning +// you must always either restart your Arduino after you connect the controller, +// or call config_gamepad(pins) again after connecting the controller. + +int error = -1; +byte type = 0; +byte vibrate = 0; +int tryNum = 1; + +void setup() +{ + + // 115200 + Serial.begin(115200); + + // added delay to give wireless ps2 module some time to startup, before configuring it + // CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* + + while (error != 0) + { + delay(1000); // 1 second wait + // setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); + Serial.print("#try config "); + Serial.println(tryNum); + tryNum++; + } + + Serial.println(ps2x.Analog(1), HEX); + + type = ps2x.readType(); + switch (type) + { + case 0: + Serial.println(" Unknown Controller type found "); + break; + case 1: + Serial.println(" DualShock Controller found "); + break; + case 2: + Serial.println(" GuitarHero Controller found "); + break; + case 3: + Serial.println(" Wireless Sony DualShock Controller found "); + break; + } +} + +void loop() +{ + + if (type == 1) + { // DualShock Controller + ps2x.read_gamepad(false, vibrate); // read controller and set large motor to spin at 'vibrate' speed + + // will be TRUE as long as button is pressed + if (ps2x.Button(PSB_START)) + Serial.println("Start is being held"); + if (ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + // will be TRUE as long as button is pressed + if (ps2x.Button(PSB_PAD_UP)) + { + Serial.print("Up held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); + } + if (ps2x.Button(PSB_PAD_RIGHT)) + { + Serial.print("Right held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); + } + if (ps2x.Button(PSB_PAD_LEFT)) + { + Serial.print("LEFT held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); + } + if (ps2x.Button(PSB_PAD_DOWN)) + { + Serial.print("DOWN held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); + } + + vibrate = ps2x.Analog(PSAB_CROSS); // this will set the large motor vibrate speed based on how hard you press the blue (X) button + if (ps2x.NewButtonState()) + { // will be TRUE if any button changes state (on to off, or off to on) + if (ps2x.Button(PSB_L3)) + Serial.println("L3 pressed"); + if (ps2x.Button(PSB_R3)) + Serial.println("R3 pressed"); + if (ps2x.Button(PSB_L2)) + Serial.println("L2 pressed"); + if (ps2x.Button(PSB_R2)) + Serial.println("R2 pressed"); + if (ps2x.Button(PSB_TRIANGLE)) + Serial.println("△ pressed"); + } + //△□○× + if (ps2x.ButtonPressed(PSB_CIRCLE)) // will be TRUE if button was JUST pressed + Serial.println("○ just pressed"); + if (ps2x.NewButtonState(PSB_CROSS)) // will be TRUE if button was JUST pressed OR released + Serial.println("× just changed"); + if (ps2x.ButtonReleased(PSB_SQUARE)) // will be TRUE if button was JUST released + Serial.println("□ just released"); + + if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) + { // print stick values if either is TRUE + Serial.print("Stick Values:"); + Serial.print(ps2x.Analog(PSS_LY)); // Left stick, Y axis. Other options: LX, RY, RX + Serial.print(","); + Serial.print(ps2x.Analog(PSS_LX), DEC); + Serial.print(","); + Serial.print(ps2x.Analog(PSS_RY), DEC); + Serial.print(","); + Serial.println(ps2x.Analog(PSS_RX), DEC); + } + } + delay(50); +} \ No newline at end of file From db9514081b5dc1fa2d22408d0a1ab013f91d3ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anh=20T=C3=BA=20Dang?= Date: Sat, 7 May 2022 23:42:03 +0700 Subject: [PATCH 07/16] update example --- .../PS2X_Example_VIA_Makerbot_ESP32.ino | 170 ++++++++---------- 1 file changed, 72 insertions(+), 98 deletions(-) diff --git a/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino b/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino index 758a80e..dd1fae6 100644 --- a/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino +++ b/examples/PS2X_Example_VIA_Makerbot_ESP32/PS2X_Example_VIA_Makerbot_ESP32.ino @@ -1,13 +1,11 @@ -#include //for v1.6 - +#include /****************************************************************** - * Cài đặt thư chân cho thư viện : + * Cài đặt chân cho thư viện : * - Trên mạch Motorshield của VIA Makerbot BANHMI, có header 6 chân * được thiết kế để cắm tay cầm PS2. * Sơ đồ chân header và sơ đồ GPIO tương ứng: * MOSI | MISO | GND | 3.3V | CS | CLK * 12 13 GND 3.3V 15 14 - * ******************************************************************/ #define PS2_DAT 12 // MISO @@ -19,129 +17,105 @@ * Lựa chọn chế độ cho tay cầm PS2 : * - pressures = đọc giá trị analog từ các nút bấm * - rumble = bật/tắt chế độ rung - * uncomment 1 of the lines for each mode selection ******************************************************************/ #define pressures false #define rumble false -PS2X ps2x; // create PS2 Controller Class - -// right now, the library does NOT support hot pluggable controllers, meaning -// you must always either restart your Arduino after you connect the controller, -// or call config_gamepad(pins) again after connecting the controller. - -int error = -1; -byte type = 0; -byte vibrate = 0; -int tryNum = 1; +PS2X ps2x; // khởi tạo class PS2x void setup() { - - // 115200 Serial.begin(115200); + Serial.print("Ket noi voi tay cam PS2:"); - // added delay to give wireless ps2 module some time to startup, before configuring it - // CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* - - while (error != 0) + int error = -1; + for (int i = 0; i < 10; i++) // thử kết nối với tay cầm ps2 trong 10 lần { - delay(1000); // 1 second wait - // setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error + delay(1000); // đợi 1 giây + // cài đặt chân và các chế độ: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); - Serial.print("#try config "); - Serial.println(tryNum); - tryNum++; + Serial.print("."); } - Serial.println(ps2x.Analog(1), HEX); - - type = ps2x.readType(); - switch (type) + switch (error) // kiểm tra lỗi nếu sau 10 lần không kết nối được { case 0: - Serial.println(" Unknown Controller type found "); + Serial.println(" Ket noi tay cam PS2 thanh cong"); break; case 1: - Serial.println(" DualShock Controller found "); + Serial.println(" LOI: Khong tim thay tay cam, hay kiem tra day ket noi vơi tay cam "); break; case 2: - Serial.println(" GuitarHero Controller found "); + Serial.println(" LOI: khong gui duoc lenh"); break; case 3: - Serial.println(" Wireless Sony DualShock Controller found "); + Serial.println(" LOI: Khong vao duoc Pressures mode "); break; } } void loop() { + ps2x.read_gamepad(false, false); // gọi hàm để đọc tay điều khiển - if (type == 1) - { // DualShock Controller - ps2x.read_gamepad(false, vibrate); // read controller and set large motor to spin at 'vibrate' speed - - // will be TRUE as long as button is pressed - if (ps2x.Button(PSB_START)) - Serial.println("Start is being held"); - if (ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); + // các trả về giá trị TRUE (1) khi nút được giữ + if (ps2x.Button(PSB_START)) // nếu nút Start được giữ, in ra Serial monitor + Serial.println("Start is being held"); + if (ps2x.Button(PSB_SELECT)) // nếu nút Select được giữ, in ra Serial monitor + Serial.println("Select is being held"); - // will be TRUE as long as button is pressed - if (ps2x.Button(PSB_PAD_UP)) - { - Serial.print("Up held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); - } - if (ps2x.Button(PSB_PAD_RIGHT)) - { - Serial.print("Right held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); - } - if (ps2x.Button(PSB_PAD_LEFT)) - { - Serial.print("LEFT held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); - } - if (ps2x.Button(PSB_PAD_DOWN)) - { - Serial.print("DOWN held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); - } - - vibrate = ps2x.Analog(PSAB_CROSS); // this will set the large motor vibrate speed based on how hard you press the blue (X) button - if (ps2x.NewButtonState()) - { // will be TRUE if any button changes state (on to off, or off to on) - if (ps2x.Button(PSB_L3)) - Serial.println("L3 pressed"); - if (ps2x.Button(PSB_R3)) - Serial.println("R3 pressed"); - if (ps2x.Button(PSB_L2)) - Serial.println("L2 pressed"); - if (ps2x.Button(PSB_R2)) - Serial.println("R2 pressed"); - if (ps2x.Button(PSB_TRIANGLE)) - Serial.println("△ pressed"); - } - //△□○× - if (ps2x.ButtonPressed(PSB_CIRCLE)) // will be TRUE if button was JUST pressed - Serial.println("○ just pressed"); - if (ps2x.NewButtonState(PSB_CROSS)) // will be TRUE if button was JUST pressed OR released - Serial.println("× just changed"); - if (ps2x.ButtonReleased(PSB_SQUARE)) // will be TRUE if button was JUST released - Serial.println("□ just released"); + if (ps2x.Button(PSB_PAD_UP)) // tương tự như trên kiểm tra nút Lên (PAD UP) + { + Serial.print("Up held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); // đọc giá trị analog ở nút này, xem nút này được bấm mạnh hay nhẹ + } + if (ps2x.Button(PSB_PAD_RIGHT)) + { + Serial.print("Right held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); + } + if (ps2x.Button(PSB_PAD_LEFT)) + { + Serial.print("LEFT held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); + } + if (ps2x.Button(PSB_PAD_DOWN)) + { + Serial.print("DOWN held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); + } - if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) - { // print stick values if either is TRUE - Serial.print("Stick Values:"); - Serial.print(ps2x.Analog(PSS_LY)); // Left stick, Y axis. Other options: LX, RY, RX - Serial.print(","); - Serial.print(ps2x.Analog(PSS_LX), DEC); - Serial.print(","); - Serial.print(ps2x.Analog(PSS_RY), DEC); - Serial.print(","); - Serial.println(ps2x.Analog(PSS_RX), DEC); - } + if (ps2x.NewButtonState()) + { // Trả về giá trị TRUE khi nút được thay đổi trạng thái (bật sang tắt, or tắt sang bật) + if (ps2x.Button(PSB_L3)) + Serial.println("L3 pressed"); + if (ps2x.Button(PSB_R3)) + Serial.println("R3 pressed"); + if (ps2x.Button(PSB_L2)) + Serial.println("L2 pressed"); + if (ps2x.Button(PSB_R2)) + Serial.println("R2 pressed"); + if (ps2x.Button(PSB_TRIANGLE)) + Serial.println("△ pressed"); + } + //△□○× + if (ps2x.ButtonPressed(PSB_CIRCLE)) // Trả về giá trị TRUE khi nút được ấn (từ tắt sang bật) + Serial.println("○ just pressed"); + if (ps2x.NewButtonState(PSB_CROSS)) // Trả về giá trị TRUE khi nút được thay đổi trạng thái + Serial.println("× just changed"); + if (ps2x.ButtonReleased(PSB_SQUARE)) // Trả về giá trị TRUE khi nút được ấn (từ tắt sang bật) + Serial.println("□ just released"); + + if (ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) // các trả về giá trị TRUE khi nút được giữ + { // Đọc giá trị 2 joystick khi nút L1 hoặc R1 được giữ + Serial.print("Stick Values:"); + Serial.print(ps2x.Analog(PSS_LY)); // đọc trục Y của joystick bên trái. Other options: LX, RY, RX + Serial.print(","); + Serial.print(ps2x.Analog(PSS_LX), DEC); + Serial.print(","); + Serial.print(ps2x.Analog(PSS_RY), DEC); + Serial.print(","); + Serial.println(ps2x.Analog(PSS_RX), DEC); } delay(50); -} \ No newline at end of file +} From 7598fe81528090001c7c3b297fc4f518642fec44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anh=20T=C3=BA=20Dang?= Date: Sat, 7 May 2022 23:42:56 +0700 Subject: [PATCH 08/16] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88f6dd9..49bf132 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Thư viện này là 1 bản sao thư viện tay cầm PS2 của 2 tác giả [m } ``` -Ví dụ chạy với mạch VIA Makerbot BANHMI: + From 41c7975a3ba80b34cf854cf69e0e5c39dd6ec20a Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Sun, 28 Aug 2022 11:41:12 +0700 Subject: [PATCH 09/16] Added hardware SPI (SPIClass) support --- PS2X_lib/PS2X_lib.cpp | 249 ++++++++++++------ PS2X_lib/PS2X_lib.h | 126 ++++++--- .../examples/PS2X_Example/PS2X_Example.ino | 92 ++++--- 3 files changed, 311 insertions(+), 156 deletions(-) diff --git a/PS2X_lib/PS2X_lib.cpp b/PS2X_lib/PS2X_lib.cpp index 74ef0f7..0afecf4 100644 --- a/PS2X_lib/PS2X_lib.cpp +++ b/PS2X_lib/PS2X_lib.cpp @@ -56,7 +56,9 @@ byte PS2X::Analog(byte button) { /****************************************************************************************/ unsigned char PS2X::_gamepad_shiftinout (char byte) { - unsigned char tmp = 0; + if(_spi == NULL) { + /* software SPI */ + unsigned char tmp = 0; for(unsigned char i=0;i<8;i++) { if(CHK(byte,i)) CMD_SET(); else CMD_CLR(); @@ -68,13 +70,16 @@ unsigned char PS2X::_gamepad_shiftinout (char byte) { if(DAT_CHK()) bitSet(tmp,i); CLK_SET(); -#if CTRL_CLK_HIGH - delayMicroseconds(CTRL_CLK_HIGH); -#endif + delayMicroseconds(CTRL_CLK); } CMD_SET(); delayMicroseconds(CTRL_BYTE_DELAY); return tmp; + } else { + unsigned char tmp = _spi->transfer(byte); // hardware SPI + delayMicroseconds(CTRL_BYTE_DELAY); + return tmp; + } } /****************************************************************************************/ @@ -100,11 +105,7 @@ boolean PS2X::read_gamepad(boolean motor1, byte motor2) { // Try a few times to get valid data... for (byte RetryCnt = 0; RetryCnt < 5; RetryCnt++) { - CMD_SET(); - CLK_SET(); - ATT_CLR(); // low enable joystick - - delayMicroseconds(CTRL_BYTE_DELAY); + BEGIN_SPI(); //Send the command to send button and joystick data; for (int i = 0; i<9; i++) { PS2data[i] = _gamepad_shiftinout(dword[i]); @@ -116,7 +117,7 @@ boolean PS2X::read_gamepad(boolean motor1, byte motor2) { } } - ATT_SET(); // HI disable joystick + END_SPI(); // Check to see if we received valid data or not. // We should be in analog mode for our data to be valid (analog == 0x7_) if ((PS2data[1] & 0xf0) == 0x70) @@ -168,61 +169,91 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat) { /****************************************************************************************/ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bool pressures, bool rumble) { - - byte temp[sizeof(type_read)]; - -#ifdef __AVR__ - _clk_mask = digitalPinToBitMask(clk); - _clk_oreg = portOutputRegister(digitalPinToPort(clk)); - _cmd_mask = digitalPinToBitMask(cmd); - _cmd_oreg = portOutputRegister(digitalPinToPort(cmd)); - _att_mask = digitalPinToBitMask(att); - _att_oreg = portOutputRegister(digitalPinToPort(att)); - _dat_mask = digitalPinToBitMask(dat); - _dat_ireg = portInputRegister(digitalPinToPort(dat)); -#else -#ifdef ESP8266 - _clk_pin = clk; - _cmd_pin = cmd; - _att_pin = att; - _dat_pin = dat; -#else +#if defined(HAVE_PORTREG_IO) + _clk_mask = (port_mask_t) digitalPinToBitMask(clk); + _clk_oreg = (port_reg_t*) portOutputRegister(digitalPinToPort(clk)); + _cmd_mask = (port_mask_t) digitalPinToBitMask(cmd); + _cmd_oreg = (port_reg_t*) portOutputRegister(digitalPinToPort(cmd)); + _att_mask = (port_mask_t) digitalPinToBitMask(att); + _att_oreg = (port_reg_t*) portOutputRegister(digitalPinToPort(att)); + _dat_mask = (port_mask_t) digitalPinToBitMask(dat); + _dat_ireg = (port_reg_t*) portInputRegister(digitalPinToPort(dat)); +#elif defined(HAVE_PORTREG_SC) // well it seems that this varies from platform to platform so... +#if defined(__PIC32__) uint32_t lport; // Port number for this pin - _clk_mask = digitalPinToBitMask(clk); + _clk_mask = (port_mask_t) digitalPinToBitMask(clk); lport = digitalPinToPort(clk); - _clk_lport_set = portOutputRegister(lport) + 2; - _clk_lport_clr = portOutputRegister(lport) + 1; + _clk_lport_set = (port_reg_t*) portOutputRegister(lport) + 2; + _clk_lport_clr = (port_reg_t*) portOutputRegister(lport) + 1; - _cmd_mask = digitalPinToBitMask(cmd); + _cmd_mask = (port_mask_t) digitalPinToBitMask(cmd); lport = digitalPinToPort(cmd); - _cmd_lport_set = portOutputRegister(lport) + 2; - _cmd_lport_clr = portOutputRegister(lport) + 1; + _cmd_lport_set = (port_reg_t*) portOutputRegister(lport) + 2; + _cmd_lport_clr = (port_reg_t*) portOutputRegister(lport) + 1; - _att_mask = digitalPinToBitMask(att); + _att_mask = (port_mask_t) digitalPinToBitMask(att); lport = digitalPinToPort(att); - _att_lport_set = portOutputRegister(lport) + 2; - _att_lport_clr = portOutputRegister(lport) + 1; + _att_lport_set = (port_reg_t*) portOutputRegister(lport) + 2; + _att_lport_clr = (port_reg_t*) portOutputRegister(lport) + 1; - _dat_mask = digitalPinToBitMask(dat); - _dat_lport = portInputRegister(digitalPinToPort(dat)); + _dat_mask = (port_mask_t) digitalPinToBitMask(dat); + _dat_lport = (port_reg_t*) portInputRegister(digitalPinToPort(dat)); #endif +#else + _clk_pin = clk; + _cmd_pin = cmd; + _att_pin = att; + _dat_pin = dat; #endif pinMode(clk, OUTPUT); //configure ports - pinMode(att, OUTPUT); + pinMode(att, OUTPUT); ATT_SET(); pinMode(cmd, OUTPUT); -#ifdef ESP8266 pinMode(dat, INPUT_PULLUP); // enable pull-up + + // CMD_SET(); // SET(*_cmd_oreg,_cmd_mask); + CLK_SET(); + + return config_gamepad_stub(pressures, rumble); +} + +byte PS2X::config_gamepad(SPIClass* spi, uint8_t att) { + return config_gamepad(spi, att, false, false); +} + +byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool pressures, bool rumble) { + _spi = spi; + #if defined(HAVE_PORTREG_IO) + _att_mask = (port_mask_t) digitalPinToBitMask(att); + _att_oreg = (port_reg_t*) portOutputRegister(digitalPinToPort(att)); +#elif defined(HAVE_PORTREG_SC) // well it seems that this varies from platform to platform so... +#if defined(__PIC32__) + uint32_t lport; // Port number for this pin + _att_mask = (port_mask_t) digitalPinToBitMask(att); + lport = digitalPinToPort(att); + _att_lport_set = (port_reg_t*) portOutputRegister(lport) + 2; + _att_lport_clr = (port_reg_t*) portOutputRegister(lport) + 1; +#endif #else - pinMode(dat, INPUT); + _att_pin = att; #endif -#if defined(__AVR__) - digitalWrite(dat, HIGH); //enable pull-up + pinMode(att, OUTPUT); ATT_SET(); + +#if defined(SPI_HAS_TRANSACTION) + _spi_settings = SPISettings(CTRL_BITRATE, LSBFIRST, SPI_MODE2); #endif - CMD_SET(); // SET(*_cmd_oreg,_cmd_mask); - CLK_SET(); + /* some hardware SPI implementations incorrectly hold CLK low before the first transaction, so we'll try to fix that */ + BEGIN_SPI_NOATT(); + _spi->transfer(0x55); // anything will work here + END_SPI_NOATT(); + + return config_gamepad_stub(pressures, rumble); +} + +byte PS2X::config_gamepad_stub(bool pressures, bool rumble) { + byte temp[sizeof(type_read)]; //new error checking. First, read gamepad a few times to see if it's talking read_gamepad(); @@ -248,17 +279,14 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bo //read type delayMicroseconds(CTRL_BYTE_DELAY); - CMD_SET(); - CLK_SET(); - ATT_CLR(); // low enable joystick - - delayMicroseconds(CTRL_BYTE_DELAY); + //CLK_SET(); // CLK should've been set to HIGH already + BEGIN_SPI(); for (int i = 0; i<9; i++) { temp[i] = _gamepad_shiftinout(type_read[i]); } - ATT_SET(); // HI disable joystick + END_SPI(); controller_type = temp[3]; @@ -296,13 +324,12 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bo void PS2X::sendCommandString(byte string[], byte len) { #ifdef PS2X_COM_DEBUG byte temp[len]; - ATT_CLR(); // low enable joystick - delayMicroseconds(CTRL_BYTE_DELAY); + BEGIN_SPI(); for (int y=0; y < len; y++) temp[y] = _gamepad_shiftinout(string[y]); - ATT_SET(); //high disable joystick + END_SPI(); delay(read_delay); //wait a few Serial.println("OUT:IN Configure"); @@ -314,11 +341,10 @@ void PS2X::sendCommandString(byte string[], byte len) { } Serial.println(""); #else - ATT_CLR(); // low enable joystick - delayMicroseconds(CTRL_BYTE_DELAY); + BEGIN_SPI(); for (int y=0; y < len; y++) _gamepad_shiftinout(string[y]); - ATT_SET(); //high disable joystick + END_SPI(); delay(read_delay); //wait a few #endif } @@ -401,112 +427,179 @@ void PS2X::reconfig_gamepad(){ } /****************************************************************************************/ -#ifdef __AVR__ +#if defined(HAVE_PORTREG_IO) inline void PS2X::CLK_SET(void) { +#if defined(__AVR__) // there should be a platform-independent way to do this register uint8_t old_sreg = SREG; cli(); +#endif *_clk_oreg |= _clk_mask; +#if defined(__AVR__) SREG = old_sreg; +#endif } inline void PS2X::CLK_CLR(void) { +#if defined(__AVR__) register uint8_t old_sreg = SREG; cli(); +#endif *_clk_oreg &= ~_clk_mask; +#if defined(__AVR__) SREG = old_sreg; +#endif } inline void PS2X::CMD_SET(void) { +#if defined(__AVR__) register uint8_t old_sreg = SREG; cli(); +#endif *_cmd_oreg |= _cmd_mask; // SET(*_cmd_oreg,_cmd_mask); +#if defined(__AVR__) SREG = old_sreg; +#endif } inline void PS2X::CMD_CLR(void) { +#if defined(__AVR__) register uint8_t old_sreg = SREG; cli(); +#endif *_cmd_oreg &= ~_cmd_mask; // SET(*_cmd_oreg,_cmd_mask); +#if defined(__AVR__) SREG = old_sreg; +#endif } inline void PS2X::ATT_SET(void) { +#if defined(__AVR__) register uint8_t old_sreg = SREG; cli(); +#endif *_att_oreg |= _att_mask ; +#if defined(__AVR__) SREG = old_sreg; +#endif } inline void PS2X::ATT_CLR(void) { +#if defined(__AVR__) register uint8_t old_sreg = SREG; cli(); +#endif *_att_oreg &= ~_att_mask; +#if defined(__AVR__) SREG = old_sreg; +#endif } inline bool PS2X::DAT_CHK(void) { return (*_dat_ireg & _dat_mask) ? true : false; } -#else -#ifdef ESP8266 -// Let's just use digitalWrite() on ESP8266. +#elif defined(HAVE_PORTREG_SC) inline void PS2X::CLK_SET(void) { - digitalWrite(_clk_pin, HIGH); + *_clk_lport_set |= _clk_mask; } inline void PS2X::CLK_CLR(void) { - digitalWrite(_clk_pin, LOW); + *_clk_lport_clr |= _clk_mask; } inline void PS2X::CMD_SET(void) { - digitalWrite(_cmd_pin, HIGH); + *_cmd_lport_set |= _cmd_mask; } inline void PS2X::CMD_CLR(void) { - digitalWrite(_cmd_pin, LOW); + *_cmd_lport_clr |= _cmd_mask; } inline void PS2X::ATT_SET(void) { - digitalWrite(_att_pin, HIGH); + *_att_lport_set |= _att_mask; } inline void PS2X::ATT_CLR(void) { - digitalWrite(_att_pin, LOW); + *_att_lport_clr |= _att_mask; } inline bool PS2X::DAT_CHK(void) { - return digitalRead(_dat_pin) ? true : false; + return (*_dat_lport & _dat_mask) ? true : false; } #else -// On pic32, use the set/clr registers to make them atomic... inline void PS2X::CLK_SET(void) { - *_clk_lport_set |= _clk_mask; + digitalWrite(_clk_pin, HIGH); } inline void PS2X::CLK_CLR(void) { - *_clk_lport_clr |= _clk_mask; + digitalWrite(_clk_pin, LOW); } inline void PS2X::CMD_SET(void) { - *_cmd_lport_set |= _cmd_mask; + digitalWrite(_cmd_pin, HIGH); } inline void PS2X::CMD_CLR(void) { - *_cmd_lport_clr |= _cmd_mask; + digitalWrite(_cmd_pin, LOW); } inline void PS2X::ATT_SET(void) { - *_att_lport_set |= _att_mask; + digitalWrite(_att_pin, HIGH); } inline void PS2X::ATT_CLR(void) { - *_att_lport_clr |= _att_mask; + digitalWrite(_att_pin, LOW); } inline bool PS2X::DAT_CHK(void) { - return (*_dat_lport & _dat_mask) ? true : false; + return digitalRead(_dat_pin) ? true : false; } #endif + +inline void PS2X::BEGIN_SPI_NOATT(void) { + if(_spi != NULL) { +#if defined(SPI_HAS_TRANSACTION) + _spi->beginTransaction(_spi_settings); +#else + // _spi->begin(); + _spi->setBitOrder(LSBFIRST); + _spi->setDataMode(SPI_MODE2); +#if defined(__AVR__) + _spi->setClockDivider(CTRL_DIVIDER); +#elif defined(__SAM3X8E__) + _spi->setClockDivider(F_CPU / CTRL_BITRATE); +#else + #error Unsupported method of setting clock divider without transaction, please update this library to support this platform, update the platform code to support SPI transaction, or use software SPI. +#endif +#endif + } else { + CMD_CLR(); + CLK_SET(); + } +} + +inline void PS2X::BEGIN_SPI(void) { + BEGIN_SPI_NOATT(); + ATT_CLR(); // low enable joystick + delayMicroseconds(CTRL_BYTE_DELAY); +} + +inline void PS2X::END_SPI_NOATT(void) { + if(_spi != NULL) { +#if defined(SPI_HAS_TRANSACTION) + _spi->endTransaction(); +#else + // _spi->end(); #endif + } else { + CMD_CLR(); + CLK_SET(); + } +} + +inline void PS2X::END_SPI(void) { + ATT_SET(); + END_SPI_NOATT(); + delayMicroseconds(CTRL_BYTE_DELAY); +} diff --git a/PS2X_lib/PS2X_lib.h b/PS2X_lib/PS2X_lib.h index 303f0e7..91837aa 100644 --- a/PS2X_lib/PS2X_lib.h +++ b/PS2X_lib/PS2X_lib.h @@ -89,23 +89,53 @@ GNU General Public License for more details. #include #include #include -#ifdef __AVR__ - // AVR - #include - #define CTRL_CLK 4 - #define CTRL_BYTE_DELAY 3 +#include + +/* SPI timing configuration */ +#define CTRL_BITRATE 50000UL // SPI bitrate (Hz). Please note that on AVR Arduinos, the lowest bitrate possible is 125kHz. +#if (1000000UL / (2 * CTRL_BITRATE) > 0) +#define CTRL_CLK (1000000UL / (2 * CTRL_BITRATE)) // delay duration between SCK high and low #else -#ifdef ESP8266 - #define CTRL_CLK 5 - #define CTRL_CLK_HIGH 5 - #define CTRL_BYTE_DELAY 18 +#define CTRL_CLK 1 +#endif +#define CTRL_BYTE_DELAY 20 // delay duration between byte reads +#if !defined(SPI_HAS_TRANSACTION) && defined(__AVR__) +// SPI divider for AVR +#if (F_CPU / CTRL_BITRATE < 3) +#define CTRL_DIVIDER SPI_CLOCK_DIV2 +#elif (F_CPU / CTRL_BITRATE < 6) +#define CTRL_DIVIDER SPI_CLOCK_DIV4 +#elif (F_CPU / CTRL_BITRATE < 12) +#define CTRL_DIVIDER SPI_CLOCK_DIV8 +#elif (F_CPU / CTRL_BITRATE < 24) +#define CTRL_DIVIDER SPI_CLOCK_DIV16 +#elif (F_CPU / CTRL_BITRATE < 48) +#define CTRL_DIVIDER SPI_CLOCK_DIV32 +#elif (F_CPU / CTRL_BITRATE < 96) +#define CTRL_DIVIDER SPI_CLOCK_DIV64 #else - // Pic32... - #include - #define CTRL_CLK 5 - #define CTRL_CLK_HIGH 5 - #define CTRL_BYTE_DELAY 4 -#endif +#define CTRL_DIVIDER SPI_CLOCK_DIV128 +#endif +#endif + +/* port register data types */ +#if defined(__AVR__) +typedef volatile uint8_t port_reg_t; +typedef uint8_t port_mask_t; +#define HAVE_PORTREG_IO +#elif defined(__SAM3X8E__) +typedef volatile RwReg port_reg_t; +typedef uint32_t port_mask_t; +#define HAVE_PORTREG_IO +#elif defined(__PIC32__) // TODO: is this how we're supposed to detect ESP32? +typedef volatile uint32_t port_reg_t; +typedef uint16_t port_mask_t; +#define HAVE_PORTREG_SC +#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \ + !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040) +typedef volatile uint32_t port_reg_t; +typedef uint32_t port_mask_t; +#define HAVE_PORTREG_IO #endif //These are our button constants @@ -183,8 +213,12 @@ class PS2X { void read_gamepad(); boolean read_gamepad(boolean, byte); byte readType(); + /* config_gamepad for software SPI */ byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t); byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t, bool, bool); + /* config_gamepad for hardware SPI */ + byte config_gamepad(SPIClass*, uint8_t); + byte config_gamepad(SPIClass*, uint8_t, bool, bool); void enableRumble(); bool enablePressures(); byte Analog(byte); @@ -198,44 +232,54 @@ class PS2X { inline void ATT_SET(void); inline void ATT_CLR(void); inline bool DAT_CHK(void); + + inline void BEGIN_SPI_NOATT(void); + inline void END_SPI_NOATT(void); + + inline void BEGIN_SPI(void); + inline void END_SPI(void); + byte config_gamepad_stub(bool, bool); // common gamepad initialization sequence unsigned char _gamepad_shiftinout (char); unsigned char PS2data[21]; void sendCommandString(byte*, byte); unsigned char i; unsigned int last_buttons; unsigned int buttons; - - #ifdef __AVR__ - uint8_t maskToBitNum(uint8_t); - uint8_t _clk_mask; - volatile uint8_t *_clk_oreg; - uint8_t _cmd_mask; - volatile uint8_t *_cmd_oreg; - uint8_t _att_mask; - volatile uint8_t *_att_oreg; - uint8_t _dat_mask; - volatile uint8_t *_dat_ireg; - #else - #ifdef ESP8266 + + /* pin I/O configuration, mostly relevant to software SPI support (except ATT which is used in both software and hardware SPI) */ + #if defined(HAVE_PORTREG_IO) // platform has port registers in input/output configuration (eg. AVR, STM32) + port_mask_t _clk_mask; + port_reg_t *_clk_oreg; + port_mask_t _cmd_mask; + port_reg_t *_cmd_oreg; + port_mask_t _att_mask; + port_reg_t *_att_oreg; + port_mask_t _dat_mask; + port_reg_t *_dat_ireg; + #elif defined(HAVE_PORTREG_SC) // platform has port registers in set/clear configuration (eg. PIC32) + port_mask_t _clk_mask; + port_reg_t *_clk_lport_set; + port_reg_t *_clk_lport_clr; + port_mask_t _cmd_mask; + port_reg_t *_cmd_lport_set; + port_reg_t *_cmd_lport_clr; + port_mask_t _att_mask; + port_reg_t *_att_lport_set; + port_reg_t *_att_lport_clr; + port_mask_t _dat_mask; + port_reg_t *_dat_lport; + #else // platform does not have port registers (eg. ESP8266, ESP32) int _clk_pin; int _cmd_pin; int _att_pin; int _dat_pin; - #else - uint8_t maskToBitNum(uint8_t); - uint16_t _clk_mask; - volatile uint32_t *_clk_lport_set; - volatile uint32_t *_clk_lport_clr; - uint16_t _cmd_mask; - volatile uint32_t *_cmd_lport_set; - volatile uint32_t *_cmd_lport_clr; - uint16_t _att_mask; - volatile uint32_t *_att_lport_set; - volatile uint32_t *_att_lport_clr; - uint16_t _dat_mask; - volatile uint32_t *_dat_lport; #endif + + /* SPI configuration */ + SPIClass* _spi; // hardware SPI class (null = software SPI) + #if defined(SPI_HAS_TRANSACTION) + SPISettings _spi_settings; // hardware SPI transaction settings #endif unsigned long last_read; diff --git a/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino b/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino index f1c64c8..0032b43 100644 --- a/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino +++ b/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino @@ -1,15 +1,17 @@ #include //for v1.6 +#include // for hardware SPI support /****************************************************************** * set pins connected to PS2 controller: * - 1e column: original * - 2e colmun: Stef? + * - 3e column: itsmevjnk (for ESP32 HSPI) * replace pin numbers by the ones you use ******************************************************************/ -#define PS2_DAT 13 //14 -#define PS2_CMD 11 //15 -#define PS2_SEL 10 //16 -#define PS2_CLK 12 //17 +#define PS2_DAT 13 //14 12 +#define PS2_CMD 11 //15 13 +#define PS2_SEL 10 //16 15 +#define PS2_CLK 12 //17 14 /****************************************************************** * select modes of PS2 controller: @@ -35,41 +37,57 @@ byte vibrate = 0; void setup(){ Serial.begin(57600); - - delay(300); //added delay to give wireless ps2 module some time to startup, before configuring it - - //CHANGES for v1.6 HERE!!! **************PAY ATTENTION************* - - //setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error - error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); - - if(error == 0){ - Serial.print("Found Controller, configured successful "); - Serial.print("pressures = "); - if (pressures) - Serial.println("true "); - else - Serial.println("false"); - Serial.print("rumble = "); - if (rumble) - Serial.println("true)"); - else - Serial.println("false"); + + /* support more flexible waiting times for wireless PS2 module to start up */ + unsigned long t_start = millis(); + Serial.println("Initializing PS2 controller."); + while(1) { + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); // software SPI initialization + /* For hardware SPI, use these commands instead: + * SPI.begin(); // needed for SPI initialization + * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble); + * Please note that the above command MAY NOT work on platforms with multiple SPI buses (such as ESP32). + * For reference, this is how to use the ESP32's HSPI bus on its default pins (for VSPI the above commands will suffice, and more detailed example is available on Espressif's SPI bus example: https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino) + * SPIClass* hspi = new SPIClass(HSPI); + * hspi->begin(); + * error = ps2x.config_gamepad(hspi, PS2_SEL, pressures, rumble); + * Additionally, pressures and rumble can be omitted from config_gamepad(), indicating that we will not be using those functions. + */ + + if(error == 0){ + Serial.print("Found Controller, configured successful after "); + Serial.print(millis() - t_start, DEC); + Serial.print("ms (pressures = "); + if (pressures) + Serial.print("true"); + else + Serial.print("false"); + Serial.print(", rumble = "); + if (rumble) + Serial.println("true)"); + else + Serial.println("false"); Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); Serial.println("holding L1 or R1 will print out the analog stick values."); Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); - } - else if(error == 1) - Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); - - else if(error == 2) - Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); + break; + } + else if(error == 1) { + Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); + continue; + } + + else if(error == 2) { + Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); + continue; + } + + else if(error == 3) { + Serial.println("Controller refusing to enter Pressures mode, may not support it. "); + break; // non-fatal error + } + } - else if(error == 3) - Serial.println("Controller refusing to enter Pressures mode, may not support it. "); - -// Serial.print(ps2x.Analog(1), HEX); - type = ps2x.readType(); switch(type) { case 0: @@ -81,10 +99,10 @@ void setup(){ case 2: Serial.print("GuitarHero Controller found "); break; - case 3: + case 3: Serial.print("Wireless Sony DualShock Controller found "); break; - } + } } void loop() { From 0e1016f23d174bcdb4dae0cfefc049c4a01fc24b Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Sun, 28 Aug 2022 11:44:49 +0700 Subject: [PATCH 10/16] Moved library to root for ease of library importation --- PS2X_lib/PS2X_lib.cpp => PS2X_lib.cpp | 0 PS2X_lib/PS2X_lib.h => PS2X_lib.h | 0 .../PS2XMouse/PS2XMouse.ino | 2 +- .../PS2X_Example/PS2X_Example.ino | 414 +++++++++--------- PS2X_lib/keywords.txt => keywords.txt | 0 5 files changed, 208 insertions(+), 208 deletions(-) rename PS2X_lib/PS2X_lib.cpp => PS2X_lib.cpp (100%) rename PS2X_lib/PS2X_lib.h => PS2X_lib.h (100%) rename {PS2X_lib/examples => examples}/PS2XMouse/PS2XMouse.ino (99%) rename {PS2X_lib/examples => examples}/PS2X_Example/PS2X_Example.ino (97%) rename PS2X_lib/keywords.txt => keywords.txt (100%) diff --git a/PS2X_lib/PS2X_lib.cpp b/PS2X_lib.cpp similarity index 100% rename from PS2X_lib/PS2X_lib.cpp rename to PS2X_lib.cpp diff --git a/PS2X_lib/PS2X_lib.h b/PS2X_lib.h similarity index 100% rename from PS2X_lib/PS2X_lib.h rename to PS2X_lib.h diff --git a/PS2X_lib/examples/PS2XMouse/PS2XMouse.ino b/examples/PS2XMouse/PS2XMouse.ino similarity index 99% rename from PS2X_lib/examples/PS2XMouse/PS2XMouse.ino rename to examples/PS2XMouse/PS2XMouse.ino index c50a7cb..6ceb1c6 100644 --- a/PS2X_lib/examples/PS2XMouse/PS2XMouse.ino +++ b/examples/PS2XMouse/PS2XMouse.ino @@ -147,4 +147,4 @@ int readAxis(int thisAxis) { // return the distance for this axis: return distance; -} +} diff --git a/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino b/examples/PS2X_Example/PS2X_Example.ino similarity index 97% rename from PS2X_lib/examples/PS2X_Example/PS2X_Example.ino rename to examples/PS2X_Example/PS2X_Example.ino index 0032b43..816b507 100644 --- a/PS2X_lib/examples/PS2X_Example/PS2X_Example.ino +++ b/examples/PS2X_Example/PS2X_Example.ino @@ -1,207 +1,207 @@ -#include //for v1.6 -#include // for hardware SPI support - -/****************************************************************** - * set pins connected to PS2 controller: - * - 1e column: original - * - 2e colmun: Stef? - * - 3e column: itsmevjnk (for ESP32 HSPI) - * replace pin numbers by the ones you use - ******************************************************************/ -#define PS2_DAT 13 //14 12 -#define PS2_CMD 11 //15 13 -#define PS2_SEL 10 //16 15 -#define PS2_CLK 12 //17 14 - -/****************************************************************** - * select modes of PS2 controller: - * - pressures = analog reading of push-butttons - * - rumble = motor rumbling - * uncomment 1 of the lines for each mode selection - ******************************************************************/ -//#define pressures true -#define pressures false -//#define rumble true -#define rumble false - -PS2X ps2x; // create PS2 Controller Class - -//right now, the library does NOT support hot pluggable controllers, meaning -//you must always either restart your Arduino after you connect the controller, -//or call config_gamepad(pins) again after connecting the controller. - -int error = 0; -byte type = 0; -byte vibrate = 0; - -void setup(){ - - Serial.begin(57600); - - /* support more flexible waiting times for wireless PS2 module to start up */ - unsigned long t_start = millis(); - Serial.println("Initializing PS2 controller."); - while(1) { - error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); // software SPI initialization - /* For hardware SPI, use these commands instead: - * SPI.begin(); // needed for SPI initialization - * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble); - * Please note that the above command MAY NOT work on platforms with multiple SPI buses (such as ESP32). - * For reference, this is how to use the ESP32's HSPI bus on its default pins (for VSPI the above commands will suffice, and more detailed example is available on Espressif's SPI bus example: https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino) - * SPIClass* hspi = new SPIClass(HSPI); - * hspi->begin(); - * error = ps2x.config_gamepad(hspi, PS2_SEL, pressures, rumble); - * Additionally, pressures and rumble can be omitted from config_gamepad(), indicating that we will not be using those functions. - */ - - if(error == 0){ - Serial.print("Found Controller, configured successful after "); - Serial.print(millis() - t_start, DEC); - Serial.print("ms (pressures = "); - if (pressures) - Serial.print("true"); - else - Serial.print("false"); - Serial.print(", rumble = "); - if (rumble) - Serial.println("true)"); - else - Serial.println("false"); - Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); - Serial.println("holding L1 or R1 will print out the analog stick values."); - Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); - break; - } - else if(error == 1) { - Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); - continue; - } - - else if(error == 2) { - Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); - continue; - } - - else if(error == 3) { - Serial.println("Controller refusing to enter Pressures mode, may not support it. "); - break; // non-fatal error - } - } - - type = ps2x.readType(); - switch(type) { - case 0: - Serial.print("Unknown Controller type found "); - break; - case 1: - Serial.print("DualShock Controller found "); - break; - case 2: - Serial.print("GuitarHero Controller found "); - break; - case 3: - Serial.print("Wireless Sony DualShock Controller found "); - break; - } -} - -void loop() { - /* You must Read Gamepad to get new values and set vibration values - ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255) - if you don't enable the rumble, use ps2x.read_gamepad(); with no values - You should call this at least once a second - */ - if(error == 1) //skip loop if no controller found - return; - - if(type == 2){ //Guitar Hero Controller - ps2x.read_gamepad(); //read controller - - if(ps2x.ButtonPressed(GREEN_FRET)) - Serial.println("Green Fret Pressed"); - if(ps2x.ButtonPressed(RED_FRET)) - Serial.println("Red Fret Pressed"); - if(ps2x.ButtonPressed(YELLOW_FRET)) - Serial.println("Yellow Fret Pressed"); - if(ps2x.ButtonPressed(BLUE_FRET)) - Serial.println("Blue Fret Pressed"); - if(ps2x.ButtonPressed(ORANGE_FRET)) - Serial.println("Orange Fret Pressed"); - - if(ps2x.ButtonPressed(STAR_POWER)) - Serial.println("Star Power Command"); - - if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed - Serial.println("Up Strum"); - if(ps2x.Button(DOWN_STRUM)) - Serial.println("DOWN Strum"); - - if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed - Serial.println("Start is being held"); - if(ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); - - if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE - Serial.print("Wammy Bar Position:"); - Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); - } - } - else { //DualShock Controller - ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed - - if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed - Serial.println("Start is being held"); - if(ps2x.Button(PSB_SELECT)) - Serial.println("Select is being held"); - - if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed - Serial.print("Up held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); - } - if(ps2x.Button(PSB_PAD_RIGHT)){ - Serial.print("Right held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); - } - if(ps2x.Button(PSB_PAD_LEFT)){ - Serial.print("LEFT held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); - } - if(ps2x.Button(PSB_PAD_DOWN)){ - Serial.print("DOWN held this hard: "); - Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); - } - - vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button - if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) - if(ps2x.Button(PSB_L3)) - Serial.println("L3 pressed"); - if(ps2x.Button(PSB_R3)) - Serial.println("R3 pressed"); - if(ps2x.Button(PSB_L2)) - Serial.println("L2 pressed"); - if(ps2x.Button(PSB_R2)) - Serial.println("R2 pressed"); - if(ps2x.Button(PSB_TRIANGLE)) - Serial.println("Triangle pressed"); - } - - if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed - Serial.println("Circle just pressed"); - if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released - Serial.println("X just changed"); - if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released - Serial.println("Square just released"); - - if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE - Serial.print("Stick Values:"); - Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX - Serial.print(","); - Serial.print(ps2x.Analog(PSS_LX), DEC); - Serial.print(","); - Serial.print(ps2x.Analog(PSS_RY), DEC); - Serial.print(","); - Serial.println(ps2x.Analog(PSS_RX), DEC); - } - } - delay(50); -} +#include //for v1.6 +#include // for hardware SPI support + +/****************************************************************** + * set pins connected to PS2 controller: + * - 1e column: original + * - 2e colmun: Stef? + * - 3e column: itsmevjnk (for ESP32 HSPI) + * replace pin numbers by the ones you use + ******************************************************************/ +#define PS2_DAT 13 //14 12 +#define PS2_CMD 11 //15 13 +#define PS2_SEL 10 //16 15 +#define PS2_CLK 12 //17 14 + +/****************************************************************** + * select modes of PS2 controller: + * - pressures = analog reading of push-butttons + * - rumble = motor rumbling + * uncomment 1 of the lines for each mode selection + ******************************************************************/ +//#define pressures true +#define pressures false +//#define rumble true +#define rumble false + +PS2X ps2x; // create PS2 Controller Class + +//right now, the library does NOT support hot pluggable controllers, meaning +//you must always either restart your Arduino after you connect the controller, +//or call config_gamepad(pins) again after connecting the controller. + +int error = 0; +byte type = 0; +byte vibrate = 0; + +void setup(){ + + Serial.begin(57600); + + /* support more flexible waiting times for wireless PS2 module to start up */ + unsigned long t_start = millis(); + Serial.println("Initializing PS2 controller."); + while(1) { + error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); // software SPI initialization + /* For hardware SPI, use these commands instead: + * SPI.begin(); // needed for SPI initialization + * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble); + * Please note that the above command MAY NOT work on platforms with multiple SPI buses (such as ESP32). + * For reference, this is how to use the ESP32's HSPI bus on its default pins (for VSPI the above commands will suffice, and more detailed example is available on Espressif's SPI bus example: https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino) + * SPIClass* hspi = new SPIClass(HSPI); + * hspi->begin(); + * error = ps2x.config_gamepad(hspi, PS2_SEL, pressures, rumble); + * Additionally, pressures and rumble can be omitted from config_gamepad(), indicating that we will not be using those functions. + */ + + if(error == 0){ + Serial.print("Found Controller, configured successful after "); + Serial.print(millis() - t_start, DEC); + Serial.print("ms (pressures = "); + if (pressures) + Serial.print("true"); + else + Serial.print("false"); + Serial.print(", rumble = "); + if (rumble) + Serial.println("true)"); + else + Serial.println("false"); + Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;"); + Serial.println("holding L1 or R1 will print out the analog stick values."); + Serial.println("Note: Go to www.billporter.info for updates and to report bugs."); + break; + } + else if(error == 1) { + Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips"); + continue; + } + + else if(error == 2) { + Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips"); + continue; + } + + else if(error == 3) { + Serial.println("Controller refusing to enter Pressures mode, may not support it. "); + break; // non-fatal error + } + } + + type = ps2x.readType(); + switch(type) { + case 0: + Serial.print("Unknown Controller type found "); + break; + case 1: + Serial.print("DualShock Controller found "); + break; + case 2: + Serial.print("GuitarHero Controller found "); + break; + case 3: + Serial.print("Wireless Sony DualShock Controller found "); + break; + } +} + +void loop() { + /* You must Read Gamepad to get new values and set vibration values + ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255) + if you don't enable the rumble, use ps2x.read_gamepad(); with no values + You should call this at least once a second + */ + if(error == 1) //skip loop if no controller found + return; + + if(type == 2){ //Guitar Hero Controller + ps2x.read_gamepad(); //read controller + + if(ps2x.ButtonPressed(GREEN_FRET)) + Serial.println("Green Fret Pressed"); + if(ps2x.ButtonPressed(RED_FRET)) + Serial.println("Red Fret Pressed"); + if(ps2x.ButtonPressed(YELLOW_FRET)) + Serial.println("Yellow Fret Pressed"); + if(ps2x.ButtonPressed(BLUE_FRET)) + Serial.println("Blue Fret Pressed"); + if(ps2x.ButtonPressed(ORANGE_FRET)) + Serial.println("Orange Fret Pressed"); + + if(ps2x.ButtonPressed(STAR_POWER)) + Serial.println("Star Power Command"); + + if(ps2x.Button(UP_STRUM)) //will be TRUE as long as button is pressed + Serial.println("Up Strum"); + if(ps2x.Button(DOWN_STRUM)) + Serial.println("DOWN Strum"); + + if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed + Serial.println("Start is being held"); + if(ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + if(ps2x.Button(ORANGE_FRET)) { // print stick value IF TRUE + Serial.print("Wammy Bar Position:"); + Serial.println(ps2x.Analog(WHAMMY_BAR), DEC); + } + } + else { //DualShock Controller + ps2x.read_gamepad(false, vibrate); //read controller and set large motor to spin at 'vibrate' speed + + if(ps2x.Button(PSB_START)) //will be TRUE as long as button is pressed + Serial.println("Start is being held"); + if(ps2x.Button(PSB_SELECT)) + Serial.println("Select is being held"); + + if(ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed + Serial.print("Up held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC); + } + if(ps2x.Button(PSB_PAD_RIGHT)){ + Serial.print("Right held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC); + } + if(ps2x.Button(PSB_PAD_LEFT)){ + Serial.print("LEFT held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC); + } + if(ps2x.Button(PSB_PAD_DOWN)){ + Serial.print("DOWN held this hard: "); + Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC); + } + + vibrate = ps2x.Analog(PSAB_CROSS); //this will set the large motor vibrate speed based on how hard you press the blue (X) button + if (ps2x.NewButtonState()) { //will be TRUE if any button changes state (on to off, or off to on) + if(ps2x.Button(PSB_L3)) + Serial.println("L3 pressed"); + if(ps2x.Button(PSB_R3)) + Serial.println("R3 pressed"); + if(ps2x.Button(PSB_L2)) + Serial.println("L2 pressed"); + if(ps2x.Button(PSB_R2)) + Serial.println("R2 pressed"); + if(ps2x.Button(PSB_TRIANGLE)) + Serial.println("Triangle pressed"); + } + + if(ps2x.ButtonPressed(PSB_CIRCLE)) //will be TRUE if button was JUST pressed + Serial.println("Circle just pressed"); + if(ps2x.NewButtonState(PSB_CROSS)) //will be TRUE if button was JUST pressed OR released + Serial.println("X just changed"); + if(ps2x.ButtonReleased(PSB_SQUARE)) //will be TRUE if button was JUST released + Serial.println("Square just released"); + + if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) { //print stick values if either is TRUE + Serial.print("Stick Values:"); + Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX + Serial.print(","); + Serial.print(ps2x.Analog(PSS_LX), DEC); + Serial.print(","); + Serial.print(ps2x.Analog(PSS_RY), DEC); + Serial.print(","); + Serial.println(ps2x.Analog(PSS_RX), DEC); + } + } + delay(50); +} diff --git a/PS2X_lib/keywords.txt b/keywords.txt similarity index 100% rename from PS2X_lib/keywords.txt rename to keywords.txt From bc9c6d98dd5a5fcc23b35e55647d5096ba60b974 Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Mon, 29 Aug 2022 13:36:21 +0700 Subject: [PATCH 11/16] Added .gitignore to skip VSCode junk --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbe9c82 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vscode/ \ No newline at end of file From 2bbc21fdcbd192dacf837240def1975627a52359 Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Mon, 29 Aug 2022 14:20:34 +0700 Subject: [PATCH 12/16] Added more initialization options to make PS2X more beginner-friendly --- PS2X_lib.cpp | 59 +++++++++++++++++++++++++- PS2X_lib.h | 25 +++++++++-- examples/PS2X_Example/PS2X_Example.ino | 38 ++++++++++++----- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/PS2X_lib.cpp b/PS2X_lib.cpp index 0afecf4..019f25f 100644 --- a/PS2X_lib.cpp +++ b/PS2X_lib.cpp @@ -218,10 +218,18 @@ byte PS2X::config_gamepad(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bo } byte PS2X::config_gamepad(SPIClass* spi, uint8_t att) { - return config_gamepad(spi, att, false, false); + return config_gamepad(spi, att, false, false, true); +} + +byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool begin) { + return config_gamepad(spi, att, false, false, begin); } byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool pressures, bool rumble) { + return config_gamepad(spi, att, pressures, rumble, true); +} + +byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool pressures, bool rumble, bool begin) { _spi = spi; #if defined(HAVE_PORTREG_IO) _att_mask = (port_mask_t) digitalPinToBitMask(att); @@ -244,6 +252,8 @@ byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool pressures, bool rumbl _spi_settings = SPISettings(CTRL_BITRATE, LSBFIRST, SPI_MODE2); #endif + if(begin) _spi->begin(); // begin SPI with default settings + /* some hardware SPI implementations incorrectly hold CLK low before the first transaction, so we'll try to fix that */ BEGIN_SPI_NOATT(); _spi->transfer(0x55); // anything will work here @@ -603,3 +613,50 @@ inline void PS2X::END_SPI(void) { END_SPI_NOATT(); delayMicroseconds(CTRL_BYTE_DELAY); } + +/****************************************************************************************/ +byte PS2X::config_gamepad_arduino_spi(uint8_t att) { + return config_gamepad_arduino_spi(att, false, false); +} + +byte PS2X::config_gamepad_arduino_spi(uint8_t att, bool pressures, bool rumble) { + return config_gamepad(&SPI, att, pressures, rumble); +} + +#if defined(ESP32) +byte PS2X::config_gamepad_esp32_hspi(uint8_t att) { + return config_gamepad_esp32_hspi(att, false, false); +} + +byte PS2X::config_gamepad_esp32_hspi(uint8_t att, bool pressures, bool rumble) { + return config_gamepad(new SPIClass(HSPI), att, pressures, rumble); +} + +byte PS2X::config_gamepad_esp32_hspi(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat) { + return config_gamepad_esp32_hspi(clk, cmd, att, dat, false, false); +} + +byte PS2X::config_gamepad_esp32_hspi(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bool pressures, bool rumble) { + SPIClass* spi_class = new SPIClass(HSPI); + spi_class->begin(clk, dat, cmd, att); + return config_gamepad(spi_class, att, pressures, rumble, false); +} + +byte PS2X::config_gamepad_esp32_vspi(uint8_t att) { + return config_gamepad_esp32_vspi(att, false, false); +} + +byte PS2X::config_gamepad_esp32_vspi(uint8_t att, bool pressures, bool rumble) { + return config_gamepad(new SPIClass(VSPI), att, pressures, rumble); +} + +byte PS2X::config_gamepad_esp32_vspi(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat) { + return config_gamepad_esp32_vspi(clk, cmd, att, dat, false, false); +} + +byte PS2X::config_gamepad_esp32_vspi(uint8_t clk, uint8_t cmd, uint8_t att, uint8_t dat, bool pressures, bool rumble) { + SPIClass* spi_class = new SPIClass(VSPI); + spi_class->begin(clk, dat, cmd, att); + return config_gamepad(spi_class, att, pressures, rumble, false); +} +#endif \ No newline at end of file diff --git a/PS2X_lib.h b/PS2X_lib.h index 91837aa..5f5793c 100644 --- a/PS2X_lib.h +++ b/PS2X_lib.h @@ -214,11 +214,28 @@ class PS2X { boolean read_gamepad(boolean, byte); byte readType(); /* config_gamepad for software SPI */ - byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t); - byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t, bool, bool); + byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t); // specify pins, pressure and rumble disabled + byte config_gamepad(uint8_t, uint8_t, uint8_t, uint8_t, bool, bool); // specify pins AND pressure&rumble mode /* config_gamepad for hardware SPI */ - byte config_gamepad(SPIClass*, uint8_t); - byte config_gamepad(SPIClass*, uint8_t, bool, bool); + byte config_gamepad(SPIClass*, uint8_t); // specify SPIClass and ATT pin, begins SPI by itself + byte config_gamepad(SPIClass*, uint8_t, bool); // specify SPIClass and ATT pin, as well as whether to begin SPI + byte config_gamepad(SPIClass*, uint8_t, bool, bool); // specify SPIClass, ATT pin and pressure&rumble mode, begins SPI by itself + byte config_gamepad(SPIClass*, uint8_t, bool, bool, bool); // specify SPIClass, ATT pin, pressure&rumble mode, and whether to begin SPI + // ready-to-use config functions for select boards (right now only supports Arduino with default SPI port and ESP32 HSPI and VSPI) + byte config_gamepad_arduino_spi(uint8_t); // specify ATT pin. please note that using this on ESP32 is functionally similar to config_gamepad_esp32_vspi(uint8_t) + byte config_gamepad_arduino_spi(uint8_t, bool, bool); // specify ATT pin and pressure&rumble mode. please note that using this on ESP32 is functionally similar to config_gamepad_esp32_vspi(uint8_t, bool, bool) +#if defined(ESP32) + // HSPI + byte config_gamepad_esp32_hspi(uint8_t); // use HSPI with custom ATT pin + byte config_gamepad_esp32_hspi(uint8_t, bool, bool); // use HSPI with custom ATT pin, also specify whether to enable pressure and rumble + byte config_gamepad_esp32_hspi(uint8_t, uint8_t, uint8_t, uint8_t); // use HSPI with custom pins + byte config_gamepad_esp32_hspi(uint8_t, uint8_t, uint8_t, uint8_t, bool, bool); // use HSPI with custom pins, also specify whether to enable pressure and rumble + // VSPI + byte config_gamepad_esp32_vspi(uint8_t); // use VSPI with custom ATT pin + byte config_gamepad_esp32_vspi(uint8_t, bool, bool); // use VSPI with custom ATT pin, also specify whether to enable pressure and rumble + byte config_gamepad_esp32_vspi(uint8_t, uint8_t, uint8_t, uint8_t); // use VSPI with custom pins + byte config_gamepad_esp32_vspi(uint8_t, uint8_t, uint8_t, uint8_t, bool, bool); // use VSPI with custom pins, also specify whether to enable pressure and rumble +#endif void enableRumble(); bool enablePressures(); byte Analog(byte); diff --git a/examples/PS2X_Example/PS2X_Example.ino b/examples/PS2X_Example/PS2X_Example.ino index 816b507..a017162 100644 --- a/examples/PS2X_Example/PS2X_Example.ino +++ b/examples/PS2X_Example/PS2X_Example.ino @@ -42,17 +42,35 @@ void setup(){ unsigned long t_start = millis(); Serial.println("Initializing PS2 controller."); while(1) { + /* + * There are multiple ways to initialize the gamepad, which can be categorized into three levels: + * Level 1: Beginner + * The gamepad can be initialized using these ready-to-use functions, which make use of the platform's hardware SPI bus: + * error = ps2x.config_gamepad_arduino_spi(PS2_SEL); // please note that unless specified with the pressures and rumble arguments, these features will not be used + * error = ps2x.config_gamepad_arduino_spi(PS2_SEL, pressures, rumble); + * A few other functions are available exclusively for the ESP32 to make use of its HSPI and VSPI buses (the examples shown below are for HSPI, to use VSPI just change hspi to vspi): + * error = ps2x.config_gamepad_esp32_hspi(PS2_SEL); + * error = ps2x.config_gamepad_esp32_hspi(PS2_SEL, pressures, rumble); + * error = ps2x.config_gamepad_esp32_hspi(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT); // this and the below function use ESP32's SPI pin routing features so that connection is not just limited to the designated pins + * error = ps2x.config_gamepad_esp32_hspi(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); + * If hardware SPI is not available, this library also provides a software (bitbanged) SPI solution. To use it, use one of these functions: + * error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT); + * error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); // used below + * Level 2: Intermediate + * Alternatively, if you choose to use a custom SPI class (e.g. software SPI library), or you want to tinker with pointers, these functions are available: + * error = ps2x.config_gamepad(&SPI, PS2_SEL); + * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble); + * If you're using something other than the default SPI bus, make sure that you replace &SPI with a pointer (SPIClass*) pointing to the SPI class of your choice. + * Please note that the above functions automatically initialize the SPI class using its begin() function. If you are looking for functions that don't do so, check out Level 3. + * NOTE: On ESP32, the default SPI class refers to the VSPI bus. If you're using HSPI, you have to change &SPI to `new SPIClass(HSPI)` (without the backticks). + * Level 3: Advanced + * Some SPI class implementations (e.g. ESP32) allows for custom configuration in their begin() function (e.g. pin routing). If you wish to be in control of this configuration, use one of these instead: + * error = ps2x.config_gamepad(&SPI, PS2_SEL, false); + * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble, false); + * Note the `false` argument at the end. + * You MUST run the SPI class' begin() function (e.g. SPI.begin() in the above example) prior to running the functions above, otherwise initialization will fail. + */ error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble); // software SPI initialization - /* For hardware SPI, use these commands instead: - * SPI.begin(); // needed for SPI initialization - * error = ps2x.config_gamepad(&SPI, PS2_SEL, pressures, rumble); - * Please note that the above command MAY NOT work on platforms with multiple SPI buses (such as ESP32). - * For reference, this is how to use the ESP32's HSPI bus on its default pins (for VSPI the above commands will suffice, and more detailed example is available on Espressif's SPI bus example: https://github.com/espressif/arduino-esp32/blob/master/libraries/SPI/examples/SPI_Multiple_Buses/SPI_Multiple_Buses.ino) - * SPIClass* hspi = new SPIClass(HSPI); - * hspi->begin(); - * error = ps2x.config_gamepad(hspi, PS2_SEL, pressures, rumble); - * Additionally, pressures and rumble can be omitted from config_gamepad(), indicating that we will not be using those functions. - */ if(error == 0){ Serial.print("Found Controller, configured successful after "); From 265793a111526cb38ef84d6f18538e11cc495f2a Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Sat, 3 Sep 2022 15:15:50 +0700 Subject: [PATCH 13/16] Made PS2 controller protocol compliant with playstation.txt notes --- PS2X_lib.cpp | 4 +++- PS2X_lib.h | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/PS2X_lib.cpp b/PS2X_lib.cpp index 019f25f..245ab9c 100644 --- a/PS2X_lib.cpp +++ b/PS2X_lib.cpp @@ -283,6 +283,7 @@ byte PS2X::config_gamepad_stub(bool pressures, bool rumble) { //try setting mode, increasing delays if need be. read_delay = 1; + t_last_att = millis() + CTRL_PACKET_DELAY; // start reading right away for(int y = 0; y <= 10; y++) { sendCommandString(enter_config, sizeof(enter_config)); //start config run @@ -591,6 +592,7 @@ inline void PS2X::BEGIN_SPI_NOATT(void) { inline void PS2X::BEGIN_SPI(void) { BEGIN_SPI_NOATT(); + while(millis() - t_last_att < CTRL_PACKET_DELAY); ATT_CLR(); // low enable joystick delayMicroseconds(CTRL_BYTE_DELAY); } @@ -611,7 +613,7 @@ inline void PS2X::END_SPI_NOATT(void) { inline void PS2X::END_SPI(void) { ATT_SET(); END_SPI_NOATT(); - delayMicroseconds(CTRL_BYTE_DELAY); + t_last_att = millis(); } /****************************************************************************************/ diff --git a/PS2X_lib.h b/PS2X_lib.h index 5f5793c..c5f1076 100644 --- a/PS2X_lib.h +++ b/PS2X_lib.h @@ -92,13 +92,14 @@ GNU General Public License for more details. #include /* SPI timing configuration */ -#define CTRL_BITRATE 50000UL // SPI bitrate (Hz). Please note that on AVR Arduinos, the lowest bitrate possible is 125kHz. +#define CTRL_BITRATE 250000UL // SPI bitrate (Hz). Please note that on AVR Arduinos, the lowest bitrate possible is 125kHz. #if (1000000UL / (2 * CTRL_BITRATE) > 0) #define CTRL_CLK (1000000UL / (2 * CTRL_BITRATE)) // delay duration between SCK high and low #else #define CTRL_CLK 1 #endif -#define CTRL_BYTE_DELAY 20 // delay duration between byte reads +#define CTRL_BYTE_DELAY 10 // delay duration between byte reads (uS) +#define CTRL_PACKET_DELAY 16 // delay duration between packets (mS) - according to playstation.txt this should be set to 16mS, but it seems that it can go down to 4mS without problems #if !defined(SPI_HAS_TRANSACTION) && defined(__AVR__) // SPI divider for AVR #if (F_CPU / CTRL_BITRATE < 3) @@ -127,7 +128,7 @@ typedef uint8_t port_mask_t; typedef volatile RwReg port_reg_t; typedef uint32_t port_mask_t; #define HAVE_PORTREG_IO -#elif defined(__PIC32__) // TODO: is this how we're supposed to detect ESP32? +#elif defined(__PIC32__) // TODO: is this how we're supposed to detect PIC32? typedef volatile uint32_t port_reg_t; typedef uint16_t port_mask_t; #define HAVE_PORTREG_SC @@ -298,6 +299,8 @@ class PS2X { #if defined(SPI_HAS_TRANSACTION) SPISettings _spi_settings; // hardware SPI transaction settings #endif + + volatile unsigned long t_last_att; // time since last ATT inactive unsigned long last_read; byte read_delay; From 8485c6a82a62692b51d0b92e01ee0c7e60d45056 Mon Sep 17 00:00:00 2001 From: Thanh-Vinh Nguyen Date: Wed, 1 Mar 2023 16:02:52 +0700 Subject: [PATCH 14/16] fixed SPI mode, hopefully it works fine now --- PS2X_lib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PS2X_lib.cpp b/PS2X_lib.cpp index e248feb..d10e3c3 100644 --- a/PS2X_lib.cpp +++ b/PS2X_lib.cpp @@ -253,7 +253,7 @@ byte PS2X::config_gamepad(SPIClass* spi, uint8_t att, bool pressures, bool rumbl pinMode(att, OUTPUT); ATT_SET(); #if defined(SPI_HAS_TRANSACTION) - _spi_settings = SPISettings(CTRL_BITRATE, LSBFIRST, SPI_MODE2); + _spi_settings = SPISettings(CTRL_BITRATE, LSBFIRST, SPI_MODE0); #endif if(begin) _spi->begin(); // begin SPI with default settings From 42226b706ba3f0bc8de33ed06d4879b2ebbce5e7 Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 3 Jul 2023 20:01:42 +0800 Subject: [PATCH 15/16] Compatible with ESP32C3 and ESP32S3 --- PS2X_lib.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PS2X_lib.cpp b/PS2X_lib.cpp index d10e3c3..6c18740 100644 --- a/PS2X_lib.cpp +++ b/PS2X_lib.cpp @@ -636,7 +636,10 @@ byte PS2X::config_gamepad_arduino_spi(uint8_t att, bool pressures, bool rumble) return config_gamepad(&SPI, att, pressures, rumble); } -#if defined(ESP32) +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 +#define VSPI FSPI +#endif +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 byte PS2X::config_gamepad_esp32_hspi(uint8_t att) { return config_gamepad_esp32_hspi(att, false, false); } From a6b2f16a6785e2930e825b5f371a9a7d53e5e325 Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 3 Jul 2023 20:45:30 +0800 Subject: [PATCH 16/16] Compatible with ESP32C3 and ESP32S3 --- PS2X_lib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PS2X_lib.h b/PS2X_lib.h index 821c128..e440cc2 100644 --- a/PS2X_lib.h +++ b/PS2X_lib.h @@ -226,7 +226,7 @@ class PS2X { // ready-to-use config functions for select boards (right now only supports Arduino with default SPI port and ESP32 HSPI and VSPI) byte config_gamepad_arduino_spi(uint8_t); // specify ATT pin. please note that using this on ESP32 is functionally similar to config_gamepad_esp32_vspi(uint8_t) byte config_gamepad_arduino_spi(uint8_t, bool, bool); // specify ATT pin and pressure&rumble mode. please note that using this on ESP32 is functionally similar to config_gamepad_esp32_vspi(uint8_t, bool, bool) -#if defined(ESP32) +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 // HSPI byte config_gamepad_esp32_hspi(uint8_t); // use HSPI with custom ATT pin byte config_gamepad_esp32_hspi(uint8_t, bool, bool); // use HSPI with custom ATT pin, also specify whether to enable pressure and rumble @@ -290,7 +290,7 @@ class PS2X { port_reg_t *_att_lport_clr; port_mask_t _dat_mask; port_reg_t *_dat_lport; - #else // platform does not have port registers (eg. ESP8266, ESP32) +#else // platform does not have port registers (eg. ESP8266, ESP32, ESP32C3, ESP32S3) int _clk_pin; int _cmd_pin;