You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I don't know if this is a bug, or a not-completely implemented feature or if this Dualshock 4 knock-off is just garbage. Probably the latter, but thought I'd ask before I spend money on an official controller.
I can get responses back from everything on the thing except the touch pad. Looking at the code, it looks like it should give me deltaX() and deltaY() values as well as a button values when clicked, but it doesn't respond.
Also, the setColorLED doesn't seem to do anything.
I'm using Bluepad32 version 4.1.0 which is what it gave me when I dowloaded it from the Arduino IDE yesterday.
I don't know if this is meaningful, but the controller reports VendorID 0x054c, Product ID 0x09cc, flags = 0x0005
I also dug through the parser code for ds4 to see why the 2 buttons on the bottom of the controller weren't supported. They're M1 and M2. It turns out they're macro buttons that you can assign to combinations of other buttons.
I have to say though that this package is better than the PS4Controller Arduino library which refused to pair at all, even after following their convoluted instructions to manually set the bluetooth address of the ESP32 on the controller. Yours just pairs the way you'd expect.
Bluepad32 Version
Other
Bluepad32 version custom
Version 4.1.0 which isn't on your dropdown list.
This is the version the Arduino IDE gave me when I installed it.
// Slightly modified version of the sample program. Changed the dumpGamepad function
// to show battery(), deltaX() and deltaY() and to try to cycle the LED color through
// red, green and blue every second.
#include <Bluepad32.h>
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;
}
}
ctl->setColorLED(255, 0, 0);if (!foundController) {
Serial.println("CALLBACK: Controller disconnected, but not found in myControllers");
}
}
long prevMillis;
void dumpGamepad(ControllerPtr ctl) {
Serial.printf(
"idx=%s, dpad: 0x%02x, buttons: 0x%04x, axis L: %4d, %4d, axis R: %4d, %4d, brake: %4d, throttle: %4d, ""misc: 0x%02x, batt:%6d mouse: %d,%d\n",
ctl->getModelName(), // 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->battery(),
ctl->deltaX(),
ctl->deltaY()
);if (millis() > prevMillis + 1000) {
static int colorIdx;
prevMillis = millis();
switch (++(colorIdx) % 3) {
case 0:
// Red
ctl->setColorLED(255, 0, 0);break;case 1:
// Green
ctl->setColorLED(0, 255, 0);break;case 2:
// Blue
ctl->setColorLED(0, 0, 255);break;
}
}
}
void dumpMouse(ControllerPtr ctl) {
Serial.printf("idx=%d, buttons: 0x%04x, scrollWheel=0x%04x, delta X: %4d, delta Y: %4d\n",
ctl->index(), // Controller Index
ctl->buttons(), // bitmask of pressed buttons
ctl->scrollWheel(), // Scroll Wheel
ctl->deltaX(), // (-511 - 512) left X Axis
ctl->deltaY() // (-511 - 512) left Y axis
);
}
void dumpKeyboard(ControllerPtr ctl) {
static const char* key_names[] = {
// clang-format off
// To avoid having too much noise in this file, only a few keys are mapped to strings.
// Starts with "A", which is offset 4.
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
// Special keys
"Enter", "Escape", "Backspace", "Tab", "Spacebar", "Underscore", "Equal", "OpenBracket", "CloseBracket",
"Backslash", "Tilde", "SemiColon", "Quote", "GraveAccent", "Comma", "Dot", "Slash", "CapsLock",
// Function keys
"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
// Cursors and others
"PrintScreen", "ScrollLock", "Pause", "Insert", "Home", "PageUp", "Delete", "End", "PageDown",
"RightArrow", "LeftArrow", "DownArrow", "UpArrow",
// clang-format on
};
static const char* modifier_names[] = {
// clang-format off
// From 0xe0 to 0xe7
"Left Control", "Left Shift", "Left Alt", "Left Meta",
"Right Control", "Right Shift", "Right Alt", "Right Meta",
// clang-format on
};
Serial.printf("idx=%d, Pressed keys: ", ctl->index());
for (int key = Keyboard_A; key <= Keyboard_UpArrow; key++) {
if (ctl->isKeyPressed(static_cast<KeyboardKey>(key))) {
const char* keyName = key_names[key-4];
Serial.printf("%s,", keyName);
}
}
for (int key = Keyboard_LeftControl; key <= Keyboard_RightMeta; key++) {
if (ctl->isKeyPressed(static_cast<KeyboardKey>(key))) {
const char* keyName = modifier_names[key-0xe0];
Serial.printf("%s,", keyName);
}
}
Console.printf("\n");
}
void dumpBalanceBoard(ControllerPtr ctl) {
Serial.printf("idx=%d, TL=%u, TR=%u, BL=%u, BR=%u, temperature=%d\n",
ctl->index(), // Controller Index
ctl->topLeft(), // top-left scale
ctl->topRight(), // top-right scale
ctl->bottomLeft(), // bottom-left scale
ctl->bottomRight(), // bottom-right scale
ctl->temperature() // temperature: used to adjust the scale value's precision );}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... if (ctl->a()) { static int colorIdx = 0; // Some gamepads like DS4 and DualSense support changing the color LED. // It is possible to change it by calling: switch (colorIdx % 3) { case 0: // Red ctl->setColorLED(255, 0, 0); break; case 1: // Green ctl->setColorLED(0, 255, 0); break; case 2: // Blue ctl->setColorLED(0, 0, 255); break; } colorIdx++; } if (ctl->b()) { // Turn on the 4 LED. Each bit represents one LED. static int led = 0; led++; // Some gamepads like the DS3, DualSense, Nintendo Wii, Nintendo Switch // support changing the "Player LEDs": those 4 LEDs that usually indicate // the "gamepad seat". // It is possible to change them by calling: ctl->setPlayerLEDs(led & 0x0f); } if (ctl->x()) { // Some gamepads like DS3, DS4, DualSense, Switch, Xbox One S, Stadia support rumble. // It is possible to set it by calling: // Some controllers have two motors: "strong motor", "weak motor". // It is possible to control them independently. ctl->playDualRumble(0 /* delayedStartMs */, 250 /* durationMs */, 0x80 /* weakMagnitude */, 0x40 /* strongMagnitude */); } // 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 processMouse(ControllerPtr ctl) { // This is just an example. if (ctl->scrollWheel() > 0) { // Do Something } else if (ctl->scrollWheel() < 0) { // Do something else } // See "dumpMouse" for possible things to query. dumpMouse(ctl);}void processKeyboard(ControllerPtr ctl) { if (!ctl->isAnyKeyPressed()) return; // This is just an example. if (ctl->isKeyPressed(Keyboard_A)) { // Do Something Serial.println("Key 'A' pressed"); } // Don't do"else" here.
// Multiple keys can be pressed at the same time.
if (ctl->isKeyPressed(Keyboard_LeftShift)) {
// Do something else
Serial.println("Key 'LEFT SHIFT' pressed");
}
// Don't do "else" here. // Multiple keys can be pressed at the same time. if (ctl->isKeyPressed(Keyboard_LeftArrow)) { // Do something else Serial.println("Key 'Left Arrow' pressed"); } // See "dumpKeyboard" for possible things to query. dumpKeyboard(ctl);}void processBalanceBoard(ControllerPtr ctl) { // This is just an example. if (ctl->topLeft() > 10000) { // Do Something } // See "dumpBalanceBoard" for possible things to query. dumpBalanceBoard(ctl);}void processControllers() { for (auto myController : myControllers) { if (myController && myController->isConnected() && myController->hasData()) { if (myController->isGamepad()) { processGamepad(myController); } else if (myController->isMouse()) { processMouse(myController); } else if (myController->isKeyboard()) { processKeyboard(myController); } else if (myController->isBalanceBoard()) { processBalanceBoard(myController); } else { Serial.println("Unsupported controller"); } } }}// Arduino setup function. Runs in CPU 1void setup() { 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 functionin 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);}
The text was updated successfully, but these errors were encountered:
I just tried that (Windows). Clicking the "home" button on the controller brings up the Steam client.
Windows doesn't see it as a mouse, but the Steam client has a "Test Device Inputs" option.
That seems to see the touchpad just fine.
There's also an option to change the LED color which does nothing. So that must not be implemented on this one.
If bluepad32 was implemented as an Arduino library, I know I could go into the library folder and insert some debugging print statements to see what's going on. I'm not sure how to do that with this though because it seems to be installed as pre-compiled binaries in the Arduino IDE and I don't know how to build them.
If one of your doc files tells how to do that, I can try messing with it this weekend and see what actually comes back.
What happened?
I don't know if this is a bug, or a not-completely implemented feature or if this Dualshock 4 knock-off is just garbage. Probably the latter, but thought I'd ask before I spend money on an official controller.
I can get responses back from everything on the thing except the touch pad. Looking at the code, it looks like it should give me
deltaX()
anddeltaY()
values as well as a button values when clicked, but it doesn't respond.Also, the
setColorLED
doesn't seem to do anything.I'm using Bluepad32 version 4.1.0 which is what it gave me when I dowloaded it from the Arduino IDE yesterday.
I don't know if this is meaningful, but the controller reports VendorID 0x054c, Product ID 0x09cc, flags = 0x0005
I also dug through the parser code for ds4 to see why the 2 buttons on the bottom of the controller weren't supported. They're M1 and M2. It turns out they're macro buttons that you can assign to combinations of other buttons.
I have to say though that this package is better than the PS4Controller Arduino library which refused to pair at all, even after following their convoluted instructions to manually set the bluetooth address of the ESP32 on the controller. Yours just pairs the way you'd expect.
Bluepad32 Version
Other
Bluepad32 version custom
Version 4.1.0 which isn't on your dropdown list.
This is the version the Arduino IDE gave me when I installed it.
Bluepad32 Platform
Arduino IDE
Platform version
Version: 2.3.3
Date: 2024-09-25T09:41:18.242Z
CLI Version: 1.0.4
Controller
A Dualshock 4 clone purchased off Amazon
Microcontroller
ESP32
Microcontroller board
Adafruit ESP32 Feather V2
OS
Windows
Relevant log output
No response
Relevant sketch
The text was updated successfully, but these errors were encountered: