Skip to content

Repository files navigation

Sony PS4 DualShock controller demo using ESP32 and STM32 [STM32C562RE]

STM32/MX2/HAL2 Sony PS4 DualShock project

Just another quick exercice for my Students regarding UART RX DMA using MX2/HAL2. Potentially also a future HMI for my contraptions. An ESP32 and STM32 cooperation. Such a combination of two MCU (or an MCU and a SoC) to provide BL/BLE and/or Wi-Fi connectivity is not something unusual - check e.g. Murata, ESP-AT, and X-NUCLEO-67W61M1.

STM32/MX2/HAL2 PS4 DualShock in action with ESP32- STM32/MX2/HAL2 PS4 DualShock in action with ESP32-CAM AI Thinker

Missing files?

Don't worry. Just open the .ioc2 file in STM32CubeMX2 and hit the yellow button to generate the IDE project. Then open the project in STM32CubeIDE for Visual Studio Code and build it.

ESP32 (Arduino framework)

// ESP32-WROVER-DEV:
// https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
// https://sklep.msalamon.pl/produkt/plytka-esp32-z-kamera-esp32-wrover-e-cam-wifi-ble-4-2/
// https://github.com/prusa3d/Prusa-Firmware-ESP32-Cam/issues/105
// https://elektroweb.pl/pl/esp32/1364-esp32-wrover-e-cam-dev-wifi-bluetooth-ble-42-ov2640.html
// #define TXD1 19
// #define RXD1 21

// ESP32-CAM:
// https://randomnerdtutorials.com/esp32-cam-ai-thinker-pinout/
// https://sklep.msalamon.pl/produkt/plytka-esp32-z-kamera-esp32-cam-wifi-ble-4-2-dedykowany-programator/
// https://elektroweb.pl/projekty/jak-podlaczyc-i-programowac-esp32-cam/
#define TXD1 2
#define RXD1 4

#define PAYLOAD_SIZE 64

typedef union {
  uint8_t bytes[PAYLOAD_SIZE];
  struct {
    uint8_t index;
    uint8_t dpad;
    uint16_t buttons;
    int32_t axisX;
    int32_t axisY;
    int32_t axisRX;
    int32_t axisRY;
    int32_t brake;
    int32_t throttle;
    uint16_t miscButtons;
    uint16_t reserved1;  // structure padding!
    int32_t gyroX;
    int32_t gyroY;
    int32_t gyroZ;
    int32_t accelX;
    int32_t accelY;
    int32_t accelZ;
    uint32_t reserved2;
    uint32_t checksum;
  } decode;
} ps4_dualshock_decoder_t;

HardwareSerial ps4Serial(1);

ps4_dualshock_decoder_t txData;

void sendSTM32Gamepad(ControllerPtr ctl) {
  txData.decode.index = ctl->index();
  txData.decode.dpad = ctl->dpad();
  txData.decode.buttons = ctl->buttons();
  txData.decode.axisX = ctl->axisX();
  txData.decode.axisY = ctl->axisY();
  txData.decode.axisRX = ctl->axisRX();
  txData.decode.axisRY = ctl->axisRY();
  txData.decode.brake = ctl->brake();
  txData.decode.throttle = ctl->throttle();
  txData.decode.miscButtons = ctl->miscButtons();
  txData.decode.reserved1 = 0;
  txData.decode.gyroX = ctl->gyroX();
  txData.decode.gyroY = ctl->gyroY();
  txData.decode.gyroZ = ctl->gyroZ();
  txData.decode.accelX = ctl->accelX();
  txData.decode.accelY = ctl->accelY();
  txData.decode.accelZ = ctl->accelZ();
  txData.decode.reserved2 = 0;

  txData.decode.checksum = 0;
  for (uint8_t i = 0; i < (PAYLOAD_SIZE / 4) - 1; i++) {
    txData.decode.checksum += ((uint32_t)(txData.bytes[4 * i]) << 24) | ((uint32_t)(txData.bytes[4 * i + 1]) << 16)
                              | ((uint32_t)(txData.bytes[4 * i + 2]) << 8) | (uint32_t)(txData.bytes[4 * i + 3]);
  }
  
  ps4Serial.write(txData.bytes, PAYLOAD_SIZE);
}

Call to action

Create your own home laboratory/workshop/garage! Get inspired by ControllersTech, DroneBot Workshop, Andreas Spiess, GreatScott!, bitluni's lab, ElectroBOOM, Phil's Lab, atomic14, That Project, Paul McWhorter, Max Imagination, Nikodem Bartnik, Stuff Made Here, Mario's Ideas, Aaed Musa, Haase Industries, and many other professional hobbyists sharing their awesome projects and tutorials! Shout-out/kudos to all of them! Promote README-driven learning.

Warning

STM32C5 series - do try it at home ❕

220+ challenges to start from: Control Engineering for Hobbyists at the Warsaw University of Technology.

Stay tuned!

0xBU

Releases

Packages

Contributors

Languages