Hello,
The project I’m working on is to move two servos with a PlayStation 4 Controller, and I’m having problems with simultaneous serial connections.
I have both servos connected to a MicroMaestro. The Maestro is connected to my computer, and the servos are powered by an external power supply.
I can move the servos normally from the Maestro Control Center.
I also have an Arduino Uno, with a USB Host Shield attached and a Bluetooth dongle plugged into the USB Host Shield.
(GitHub - felis/USB_Host_Shield_2.0: Revision 2.0 of USB Host Library for Arduino.)
The Maestro serial pins are connected to pin 10 (to maestro TX) and pin 11 (to maestro RX) of the Uno board. Vin and Gnd are also connected between the Uno and Maestro.
I am attempting to combine elements of two examples, Your ‘Basic’ Maestro example and USB Host Shield’s ‘PS4BT’ example. I’m sure the problem is something I don’t understand about these serial connections.
Both examples are working independently. Maestro ‘Basic’ moves the servos.
The PS4BT example uses Serial.begin to connect to the serial monitor at 115200. When you move the analog on the ps4 controller, it begins dumping readings instantly to the Serial Monitor.
Now the problem:
When I add the basic Maestro elements into the program, it introduces a delay in the PS4 readings sent to the Serial Monitor. Now when I move the analog, the readings in the Serial Monitor are delayed by approximately 1 second.
The readings also seem to be coming out of a buffer, because they continue for about 1 second after the analog is released. They also seem to come in at the same 9600 baud rate the MaestroSerial connects at.
If I comment out ‘maestroSerial.begin(9600)’, the delay is gone.
If I change ‘Serial.begin’ to connect at 9600 instead of 115200, the delay is gone.
BUT…I know that isn’t the whole issue, because when I combine the parts, the Maestro Control Center throws a Serial Protocol Error (0x0010) and I can no longer control the servos programmatically.
Here is the code. Any help you can offer would be greatly appreciated.
Jared
#include <PololuMaestro.h>
#include <PS4BT.h>
#include <usbhub.h>
#include <SPI.h>
#include <SoftwareSerial.h>
USB Usb;
BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so
/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
//PS4BT PS4(&Btd, PAIR);
// After that you can simply create the instance like so and then press the PS button on the device
PS4BT PS4(&Btd);
SoftwareSerial maestroSerial(10, 11);
// Next, create a Maestro object using the serial port.
MicroMaestro maestro(maestroSerial);
int Xvalue = 1525;
int Yvalue = 1525;
void setup()
{
Serial.begin(115200);
#if !defined(__MIPSEL__)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); // Halt
}
Serial.print(F("\r\nPS4 Bluetooth Library Started"));
// Set the serial baud rate.
maestroSerial.begin(9600);
}
void loop()
{
Usb.Task();
maestro.setSpeed(0, 0);
maestro.setAcceleration(0, 0);
maestro.setSpeed(1, 0);
maestro.setAcceleration(1, 0);
if (PS4.connected()) {
if (PS4.getButtonClick(PS)) { //Shut down PS4 controller
Serial.print(F("\r\nPS"));
PS4.disconnect();
}
if (PS4.getAnalogHat(RightHatX) > 137 || PS4.getAnalogHat(RightHatX) < 117 || PS4.getAnalogHat(RightHatY) > 137 || PS4.getAnalogHat(RightHatY) < 117) {
//Serial.print(F("\r\nLeftHatX: "));
//Serial.print(PS4.getAnalogHat(LeftHatX));
//Serial.print(F("\tLeftHatY: "));
//Serial.print(PS4.getAnalogHat(LeftHatY));
Serial.print(F("\tRightHatX: "));
Serial.print(PS4.getAnalogHat(RightHatX));
Serial.print(F("\tRightHatY: "));
Serial.print(PS4.getAnalogHat(RightHatY));
Xvalue = map(PS4.getAnalogHat(RightHatX), 0, 255, 5400, 6800); //Map PS4 right analog stick range to acceptable servo min/max
Yvalue = map(PS4.getAnalogHat(RightHatY), 0, 255, 5400, 6800);
Serial.print(F("\r\nServoX: "));
Serial.print(Xvalue); // Correct values appear in serial monitor for X and Y.
Serial.print(F("\r\nServoY: "));
Serial.print(Yvalue);
//maestro.setTarget(0, Xvalue); // This doesn't work, I don't know why.
//maestro.setTarget(1, Yvalue);
}
}
}