0

I am trying to combine two input sources that are recognized as a single gamepad/controller. For that purpose, I am using an Arduino Leonardo that can be easily transformed into an HID device using the Joystick.h library. As inputs, I am using (1) a PS2 Controller with the PS2x library and (2) Bluetooth serial data coming from an HC-05 working in master mode.

I have built a separate sketch to read and parse the Bluetooth data, and even managed to forward it via the Joystick.h library to the PC.

At the same time, in order to use the PS2 controller, I have linked the PS2 to USB using the same Arduino Leonardo. However, when I tried to combine these two sketches (to combine two inputs from BT and PS2), something does not work.

I figured out that PS2_lib used for reading values from PS2 controller prevents Arduino from reading BTSerial data or vise-versa.

Here is the sketch, when ReadOneByte() is called, nothing works.

byte ReadOneByte() {
  int ByteRead;
  while(!BTSerial.available());
  ByteRead = BTSerial.read();
  return ByteRead;
}

If I comment out the while loop, the PS2 and gamepad works.

The full sketch:

#include <PS2X_lib.h>  //for v1.6
#include "Joystick.h"
#include<SoftwareSerial.h>


Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
    12, 2, // Button Count, Hat Switch Count
    true, true, true, // X and Y, but no Z Axis
    false, false, true, // No Rx, Ry, or Rz
    false, false, // No rudder or throttle
    false, false, false);  // No accelerator, brake, or steering

#define PS2_DAT        3  //14    
#define PS2_CMD        2  //15
#define PS2_SEL        12  //16
#define PS2_CLK        13  //17

//#define pressures true
#define pressures false
//#define rumble true
#define rumble false

const bool testAutoSendMode = false;
SoftwareSerial BTSerial(11, 10);
PS2X ps2x;

int error = 0;
byte type = 0;
byte vibrate = 0;

void setup() {
  SoftwareSerial BTSerial(11, 10);
  BTSerial.begin(57600);
  Serial.begin(57600);
  delay(300);
  Joystick.begin();
  //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, true, false);
  type = ps2x.readType();
  Joystick.setXAxisRange(0, 255);
  Joystick.setZAxisRange(0, 255);
  Joystick.setYAxisRange(0, 255);
  Joystick.setRzAxisRange(0, 255);
}

byte ReadOneByte() {
  int ByteRead;
  while (!BTSerial.available());
  ByteRead = BTSerial.read();
  return ByteRead;
}

void loop() {
  ReadOneByte() ;
  // Always be getting fresh data
  if (error == 1) //skip loop if no controller found
    return;
  error = ps2x.config_gamepad(PS2_CLK, PS2_CMD, PS2_SEL, PS2_DAT, pressures, rumble);
  ps2x.read_gamepad(false, 0);
  Joystick.setButton(0, ps2x.Button(PSB_TRIANGLE));
  Joystick.setButton(1, ps2x.Button(PSB_CIRCLE));
  Joystick.setButton(2, ps2x.Button(PSB_CROSS));
  Joystick.setButton(3, ps2x.Button(PSB_SQUARE));
  Joystick.setButton(4, ps2x.Button(PSB_L2));
  Joystick.setButton(5, ps2x.Button(PSB_R2));
  Joystick.setButton(6, ps2x.Button(PSB_L1));
  Joystick.setButton(7, ps2x.Button(PSB_R1));
  Joystick.setButton(8, ps2x.Button(PSB_SELECT));
  Joystick.setButton(9, ps2x.Button(PSB_START));
  Joystick.setButton(10, ps2x.Button(PSB_L3));
  Joystick.setButton(11, ps2x.Button(PSB_R3));
  Joystick.setXAxis(ps2x.Analog(PSS_LX));
  Joystick.setYAxis(ps2x.Analog(PSS_LY));
  Joystick.setZAxis(ps2x.Analog(PSS_RY));
  Joystick.setRzAxis(ps2x.Analog(PSS_RX));
  if (ps2x.Button(PSB_PAD_UP)) { //will be TRUE as long as button is pressed
    Joystick.setYAxis(0);
  }
  if (ps2x.Button(PSB_PAD_RIGHT)) {
    Joystick.setXAxis(255);
  }
  if (ps2x.Button(PSB_PAD_LEFT)) {
    Joystick.setXAxis(0);
  }
  if (ps2x.Button(PSB_PAD_DOWN)) {
    Joystick.setYAxis(255);
  }
}
Machavity
  • 30,841
  • 27
  • 92
  • 100
Aleks
  • 78
  • 1
  • 8
  • Seems like a lot of trouble to do the same as the [scpToolkit](https://github.com/nefarius/ScpToolkit) – Grifplex Jul 06 '17 at 02:47
  • Well, I don't know about scpToolkit, but I need BT connection too, where I receive some biofeedback data. The device (hardware) needs to be portable and work plug&play virtually with any PC as HID Gamepad/Joystick – Aleks Jul 06 '17 at 09:15
  • I figured out that both Joystick.setButton(bttn,boolean) and ps2x.Button(button) are resource demanding, thus when none of the buttons were pressed, a lot of "release" commands have been passing through creating a lot of overhead and computational demands. As result of this overhead, the loop() cycle has been slowed down, preventing serial data from Bluetooth to be read properly. I solved this problem by setting a boolean variable (e.g. xButtonReleased), so I call only respective commands when it is necessary. – Aleks Jul 11 '17 at 13:37

0 Answers0