Bluetooth Soft Serial and PS2 controller on Arduino Leonardo

588 Views Asked by At

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);
  }
}
0

There are 0 best solutions below