Im having a coding issue with the dpad on a PS4 remote. I can get the down and right to work but the left and up doesnt. I am trying to run two motors off of the dpad using left and up for one direction and down and right for the opposite direction.
include <Bluepad32.h>
int builtInLed = 2;
//Boom Extention Motor
int BoomExtPin1 = 23;
int BoomExtPin2 = 22;
//Boom Lift Motor PINS WORK
int BoomLiftPin1 = 21;
int BoomLiftPin2 = 19;
//Carrier Motor PINS WORK
int CarrierPin1 = 25;
int CarrierPin2 = 26;
//Winch 1 Motor PINS WORK
int Winch1Pin1 = 16;
int Winch1Pin2 = 17;
//Winch 2 Motor PINS WORK
int Winch2Pin1 = 12;
int Winch2Pin2 = 13;
ControllerPtr myControllers[BP32_MAX_GAMEPADS];
// This callback gets called any time a new gamepad is connected.
// Up to 4 gamepads can be connected at the same time.
void onConnectedController(ControllerPtr ctl) {
bool foundEmptySlot = false;
for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
if (myControllers[i] == nullptr) {
Serial.printf("CALLBACK: Controller is connected, index=%d\n", i);
// Additionally, you can get certain gamepad properties like:
// Model, VID, PID, BTAddr, flags, etc.
ControllerProperties properties = ctl->getProperties();
Serial.printf("Controller model: %s, VID=0x%04x, PID=0x%04x\n", ctl->getModelName().c_str(), properties.vendor_id,
properties.product_id);
myControllers[i] = ctl;
foundEmptySlot = true;
break;
}
}
if (!foundEmptySlot) {
Serial.println("CALLBACK: Controller connected, but could not found empty slot");
}
}
void onDisconnectedController(ControllerPtr ctl) {
bool foundController = false;
for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
if (myControllers[i] == ctl) {
Serial.printf("CALLBACK: Controller disconnected from index=%d\n", i);
myControllers[i] = nullptr;
foundController = true;
break;
}
}
if (!foundController) {
Serial.println("CALLBACK: Controller disconnected, but not found in myControllers");
}
}
void dumpGamepad(ControllerPtr ctl) {
Serial.printf(
"idx=%d, dpad: 0x%02x, buttons: 0x%04x, axis L: %4d, %4d, axis R: %4d, %4d, brake: %4d, throttle: %4d, "
"misc: 0x%02x, gyro x:%6d y:%6d z:%6d, accel x:%6d y:%6d z:%6d\n",
ctl->index(), // Controller Index
ctl->dpad(), // D-pad
ctl->buttons(), // bitmask of pressed buttons
ctl->axisX(), // (-511 - 512) left X Axis
ctl->axisY(), // (-511 - 512) left Y axis
ctl->axisRX(), // (-511 - 512) right X axis
ctl->axisRY(), // (-511 - 512) right Y axis
ctl->brake(), // (0 - 1023): brake button
ctl->throttle(), // (0 - 1023): throttle (AKA gas) button
ctl->miscButtons(), // bitmask of pressed "misc" buttons
ctl->gyroX(), // Gyro X
ctl->gyroY(), // Gyro Y
ctl->gyroZ(), // Gyro Z
ctl->accelX(), // Accelerometer X
ctl->accelY(), // Accelerometer Y
ctl->accelZ() // Accelerometer Z
);
}
void processGamepad(ControllerPtr ctl) {
// There are different ways to query whether a button is pressed.
// By query each button individually:
// a(), b(), x(), y(), l1(), etc...
//== PS4 X button = 0x0001 ==//
if (ctl->buttons() == 0x0001) {
digitalWrite(builtInLed, HIGH);
}
if (ctl->buttons() != 0x0001) {
digitalWrite(builtInLed, LOW);
}
//== PS4 dpad up = 0x01 ==//
if (ctl->dpad() == 0x01) {
int PWM = map(ctl->dpad(), 0, 0, 0, 255);
digitalWrite(Winch1Pin1, PWM);
digitalWrite(Winch1Pin2, LOW);
}
if (ctl->dpad() != 0x01) {
int PWM = map(ctl->dpad(), 0, 0, 0, 0);
digitalWrite(Winch1Pin1, LOW);
digitalWrite(Winch1Pin2, LOW);
}
//== PS4 dpad down = 0x02 ==//
if (ctl->dpad() == 0x02) {
int PWM = map(ctl->dpad(), 0, 0, 0, 255);
digitalWrite(Winch1Pin1, LOW);
digitalWrite(Winch1Pin2, PWM);
}
if (ctl->dpad() != 0x02) {
int PWM = map(ctl->dpad(), 0, 0, 0, 0);
digitalWrite(Winch1Pin1, LOW);
digitalWrite(Winch1Pin2, LOW);
}
//== PS4 dpad left = 0x08 ==//
if (ctl->dpad() == 0x08) {
int PWM = map(ctl->dpad(), 0, 0, 0, 255);
digitalWrite(Winch2Pin1, PWM);
digitalWrite(Winch2Pin2, LOW);
}
if (ctl->dpad() != 0x08) {
int PWM = map(ctl->dpad(), 0, 0, 0, 0);
digitalWrite(Winch2Pin1, LOW);
digitalWrite(Winch2Pin2, LOW);
}
//== PS4 dpad right = 0x04 ==//
if (ctl->dpad() == 0x04) {
int PWM = map(ctl->dpad(), 0, 0, 0, 255);
digitalWrite(Winch2Pin1, LOW);
digitalWrite(Winch2Pin2, PWM);
}
if (ctl->dpad() != 0x04) {
int PWM = map(ctl->dpad(), 0, 0, 0, 0);
digitalWrite(Winch2Pin1, LOW);
digitalWrite(Winch2Pin2, LOW);
}
//== PS4 LEFT JOYSTICK - UP ==//
if (ctl->axisY() <= -300) {
int PWM = map(ctl->axisY(), -300, -508, 30, 255);
digitalWrite(BoomExtPin1, PWM);
digitalWrite(BoomExtPin2, LOW);
}
//== PS4 LEFT JOYSTICK - DOWN ==//
if (ctl->axisY() >= 300) {
int PWM = map(ctl->axisY(), 300, 512, 30, 255);
digitalWrite(BoomExtPin1, LOW);
digitalWrite(BoomExtPin2, PWM);
}
//== PS4 LEFT JOYSTICK - LEFT ==//
if (ctl->axisX() <= -300) {
int PWM = map(ctl->axisX(), -300, -508, 30, 255);
digitalWrite(BoomLiftPin1, PWM);
digitalWrite(BoomLiftPin2, LOW);
}
//== PS4 LEFT JOYSTICK - RIGHT ==//
if (ctl->axisX() >= 300) {
int PWM = map(ctl->axisX(), 300, 512, 30, 255);
digitalWrite(BoomLiftPin1, LOW);
digitalWrite(BoomLiftPin2, PWM);
}
//== PS4 LEFT JOYSTICK DEADZONE ==//
if (ctl->axisY() > -300 && ctl->axisY() < 300 && ctl->axisX() > -300 && ctl->axisX() < 300) {
// code for when left joystick is at idle
digitalWrite(BoomExtPin1, LOW);
digitalWrite(BoomExtPin2, LOW);
digitalWrite(BoomLiftPin1, LOW);
digitalWrite(BoomLiftPin2, LOW);
}
//== PS4 RIGHT JOYSTICK - UP ==//
if (ctl->axisRY() <= -300) {
int PWM = map(ctl->axisRY(), -300, -508, 30, 255);
digitalWrite(CarrierPin1, PWM);
digitalWrite(CarrierPin2, LOW);
}
//== PS4 RIGHT JOYSTICK - DOWN ==//
if (ctl->axisRY() >= 300) {
int PWM = map(ctl->axisRY(), 300, 512, 30, 255);
digitalWrite(CarrierPin1, LOW);
digitalWrite(CarrierPin2, PWM);
}
//== PS4 RIGHT JOYSTICK - LEFT ==//
if (ctl->axisRX() <= -300) {
int PWM = map(ctl->axisRX(), -300, -508, 30, 255);
}
//== PS4 RIGHT JOYSTICK - RIGHT ==//
if (ctl->axisRX() >= 300) {
int PWM = map(ctl->axisRX(), 300, 512, 30, 255);
}
//== PS4 RIGHT JOYSTICK DEADZONE ==//
if (ctl->axisRY() > -300 && ctl->axisRY() < 300 && ctl->axisRX() > -300 && ctl->axisRX() < 300) {
// code for when left joystick is at idle
digitalWrite(CarrierPin1, LOW);
digitalWrite(CarrierPin2, LOW);
}
// Another way to query controller data is by getting the buttons() function.
// See how the different "dump*" functions dump the Controller info.
dumpGamepad(ctl);
}
void processControllers() {
for (auto myController : myControllers) {
if (myController && myController->isConnected() && myController->hasData()) {
if (myController->isGamepad()) {
processGamepad(myController);
} else {
Serial.println("Unsupported controller");
}
}
}
}
// Arduino setup function. Runs in CPU 1
void setup() {
//sets the pins as outputs
pinMode(BoomExtPin1, OUTPUT);
pinMode(BoomExtPin2, OUTPUT);
pinMode(BoomLiftPin1, OUTPUT);
pinMode(BoomLiftPin2, OUTPUT);
pinMode(CarrierPin1, OUTPUT);
pinMode(CarrierPin2, OUTPUT);
pinMode(Winch1Pin1, OUTPUT);
pinMode(Winch1Pin2, OUTPUT);
pinMode(Winch2Pin1, OUTPUT);
pinMode(Winch2Pin2, OUTPUT);
Serial.begin(115200);
Serial.printf("Firmware: %s\n", BP32.firmwareVersion());
const uint8_t* addr = BP32.localBdAddress();
Serial.printf("BD Addr: %2X:%2X:%2X:%2X:%2X:%2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
// Setup the Bluepad32 callbacks
BP32.setup(&onConnectedController, &onDisconnectedController);
// "forgetBluetoothKeys()" should be called when the user performs
// a "device factory reset", or similar.
// Calling "forgetBluetoothKeys" in setup() just as an example.
// Forgetting Bluetooth keys prevents "paired" gamepads to reconnect.
// But it might also fix some connection / re-connection issues.
BP32.forgetBluetoothKeys();
// Enables mouse / touchpad support for gamepads that support them.
// When enabled, controllers like DualSense and DualShock4 generate two connected devices:
// - First one: the gamepad
// - Second one, which is a "virtual device", is a mouse.
// By default, it is disabled.
BP32.enableVirtualDevice(false);
}
// Arduino loop function. Runs in CPU 1.
void loop() {
// This call fetches all the controllers' data.
// Call this function in your main loop.
bool dataUpdated = BP32.update();
if (dataUpdated)
processControllers();
// The main loop must have some kind of "yield to lower priority task" event.
// Otherwise, the watchdog will get triggered.
// If your main loop doesn't have one, just add a simple vTaskDelay(1).
// Detailed info here:
// https://stackoverflow.com/questions/66278271/task-watchdog-got-triggered-the-tasks-did-not-reset-the-watchdog-in-time
// vTaskDelay(1);
delay(150);
}
Sketch uses 714997 bytes (54%) of program storage space. Maximum is 1310720 bytes.
Global variables use 87092 bytes (26%) of dynamic memory, leaving 240588 bytes for local variables. Maximum is 327680 bytes.
esptool.py v4.5.1
Serial port COM4
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 00:4b:12:ec:38:78
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Im having a coding issue with the dpad on a PS4 remote. I can get the down and right to work but the left and up doesnt. I am trying to run two motors off of the dpad using left and up for one direction and down and right for the opposite direction.
include <Bluepad32.h>
int builtInLed = 2;
//Boom Extention Motor
int BoomExtPin1 = 23;
int BoomExtPin2 = 22;
//Boom Lift Motor PINS WORK
int BoomLiftPin1 = 21;
int BoomLiftPin2 = 19;
//Carrier Motor PINS WORK
int CarrierPin1 = 25;
int CarrierPin2 = 26;
//Winch 1 Motor PINS WORK
int Winch1Pin1 = 16;
int Winch1Pin2 = 17;
//Winch 2 Motor PINS WORK
int Winch2Pin1 = 12;
int Winch2Pin2 = 13;
ControllerPtr myControllers[BP32_MAX_GAMEPADS];
// This callback gets called any time a new gamepad is connected.
// Up to 4 gamepads can be connected at the same time.
void onConnectedController(ControllerPtr ctl) {
bool foundEmptySlot = false;
for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
if (myControllers[i] == nullptr) {
Serial.printf("CALLBACK: Controller is connected, index=%d\n", i);
// Additionally, you can get certain gamepad properties like:
// Model, VID, PID, BTAddr, flags, etc.
ControllerProperties properties = ctl->getProperties();
Serial.printf("Controller model: %s, VID=0x%04x, PID=0x%04x\n", ctl->getModelName().c_str(), properties.vendor_id,
properties.product_id);
myControllers[i] = ctl;
foundEmptySlot = true;
break;
}
}
if (!foundEmptySlot) {
Serial.println("CALLBACK: Controller connected, but could not found empty slot");
}
}
void onDisconnectedController(ControllerPtr ctl) {
bool foundController = false;
for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
if (myControllers[i] == ctl) {
Serial.printf("CALLBACK: Controller disconnected from index=%d\n", i);
myControllers[i] = nullptr;
foundController = true;
break;
}
}
if (!foundController) {
Serial.println("CALLBACK: Controller disconnected, but not found in myControllers");
}
}
void dumpGamepad(ControllerPtr ctl) {
Serial.printf(
"idx=%d, dpad: 0x%02x, buttons: 0x%04x, axis L: %4d, %4d, axis R: %4d, %4d, brake: %4d, throttle: %4d, "
"misc: 0x%02x, gyro x:%6d y:%6d z:%6d, accel x:%6d y:%6d z:%6d\n",
ctl->index(), // Controller Index
ctl->dpad(), // D-pad
ctl->buttons(), // bitmask of pressed buttons
ctl->axisX(), // (-511 - 512) left X Axis
ctl->axisY(), // (-511 - 512) left Y axis
ctl->axisRX(), // (-511 - 512) right X axis
ctl->axisRY(), // (-511 - 512) right Y axis
ctl->brake(), // (0 - 1023): brake button
ctl->throttle(), // (0 - 1023): throttle (AKA gas) button
ctl->miscButtons(), // bitmask of pressed "misc" buttons
ctl->gyroX(), // Gyro X
ctl->gyroY(), // Gyro Y
ctl->gyroZ(), // Gyro Z
ctl->accelX(), // Accelerometer X
ctl->accelY(), // Accelerometer Y
ctl->accelZ() // Accelerometer Z
);
}
void processGamepad(ControllerPtr ctl) {
// There are different ways to query whether a button is pressed.
// By query each button individually:
// a(), b(), x(), y(), l1(), etc...
//== PS4 X button = 0x0001 ==//
if (ctl->buttons() == 0x0001) {
digitalWrite(builtInLed, HIGH);
}
if (ctl->buttons() != 0x0001) {
digitalWrite(builtInLed, LOW);
}
//== PS4 dpad up = 0x01 ==//
if (ctl->dpad() == 0x01) {
}
if (ctl->dpad() != 0x01) {
}
//== PS4 dpad down = 0x02 ==//
if (ctl->dpad() == 0x02) {
}
if (ctl->dpad() != 0x02) {
}
//== PS4 dpad left = 0x08 ==//
if (ctl->dpad() == 0x08) {
}
if (ctl->dpad() != 0x08) {
}
//== PS4 dpad right = 0x04 ==//
if (ctl->dpad() == 0x04) {
int PWM = map(ctl->dpad(), 0, 0, 0, 255);
}
if (ctl->dpad() != 0x04) {
}
//== PS4 LEFT JOYSTICK - UP ==//
if (ctl->axisY() <= -300) {
}
//== PS4 LEFT JOYSTICK - DOWN ==//
if (ctl->axisY() >= 300) {
}
//== PS4 LEFT JOYSTICK - LEFT ==//
if (ctl->axisX() <= -300) {
}
//== PS4 LEFT JOYSTICK - RIGHT ==//
if (ctl->axisX() >= 300) {
}
//== PS4 LEFT JOYSTICK DEADZONE ==//
if (ctl->axisY() > -300 && ctl->axisY() < 300 && ctl->axisX() > -300 && ctl->axisX() < 300) {
}
//== PS4 RIGHT JOYSTICK - UP ==//
if (ctl->axisRY() <= -300) {
}
//== PS4 RIGHT JOYSTICK - DOWN ==//
if (ctl->axisRY() >= 300) {
}
//== PS4 RIGHT JOYSTICK - LEFT ==//
if (ctl->axisRX() <= -300) {
}
//== PS4 RIGHT JOYSTICK - RIGHT ==//
if (ctl->axisRX() >= 300) {
}
//== PS4 RIGHT JOYSTICK DEADZONE ==//
if (ctl->axisRY() > -300 && ctl->axisRY() < 300 && ctl->axisRX() > -300 && ctl->axisRX() < 300) {
// code for when left joystick is at idle
}
// Another way to query controller data is by getting the buttons() function.
// See how the different "dump*" functions dump the Controller info.
dumpGamepad(ctl);
}
void processControllers() {
for (auto myController : myControllers) {
if (myController && myController->isConnected() && myController->hasData()) {
if (myController->isGamepad()) {
processGamepad(myController);
}
}
// Arduino setup function. Runs in CPU 1
void setup() {
//sets the pins as outputs
pinMode(BoomExtPin1, OUTPUT);
pinMode(BoomExtPin2, OUTPUT);
pinMode(BoomLiftPin1, OUTPUT);
pinMode(BoomLiftPin2, OUTPUT);
pinMode(CarrierPin1, OUTPUT);
pinMode(CarrierPin2, OUTPUT);
pinMode(Winch1Pin1, OUTPUT);
pinMode(Winch1Pin2, OUTPUT);
pinMode(Winch2Pin1, OUTPUT);
pinMode(Winch2Pin2, OUTPUT);
Serial.begin(115200);
Serial.printf("Firmware: %s\n", BP32.firmwareVersion());
const uint8_t* addr = BP32.localBdAddress();
Serial.printf("BD Addr: %2X:%2X:%2X:%2X:%2X:%2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
// Setup the Bluepad32 callbacks
BP32.setup(&onConnectedController, &onDisconnectedController);
// "forgetBluetoothKeys()" should be called when the user performs
// a "device factory reset", or similar.
// Calling "forgetBluetoothKeys" in setup() just as an example.
// Forgetting Bluetooth keys prevents "paired" gamepads to reconnect.
// But it might also fix some connection / re-connection issues.
BP32.forgetBluetoothKeys();
// Enables mouse / touchpad support for gamepads that support them.
// When enabled, controllers like DualSense and DualShock4 generate two connected devices:
// - First one: the gamepad
// - Second one, which is a "virtual device", is a mouse.
// By default, it is disabled.
BP32.enableVirtualDevice(false);
}
// Arduino loop function. Runs in CPU 1.
void loop() {
// This call fetches all the controllers' data.
// Call this function in your main loop.
bool dataUpdated = BP32.update();
if (dataUpdated)
processControllers();
// The main loop must have some kind of "yield to lower priority task" event.
// Otherwise, the watchdog will get triggered.
// If your main loop doesn't have one, just add a simple
vTaskDelay(1).// Detailed info here:
// https://stackoverflow.com/questions/66278271/task-watchdog-got-triggered-the-tasks-did-not-reset-the-watchdog-in-time
// vTaskDelay(1);
delay(150);
}
Sketch uses 714997 bytes (54%) of program storage space. Maximum is 1310720 bytes.
Global variables use 87092 bytes (26%) of dynamic memory, leaving 240588 bytes for local variables. Maximum is 327680 bytes.
esptool.py v4.5.1
Serial port COM4
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 00:4b:12:ec:38:78
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...