Skip to content

Instantly share code, notes, and snippets.

@misspokeycat
Created May 14, 2025 20:35
Show Gist options
  • Save misspokeycat/160d07d41a2f90325cefef8bf7eca437 to your computer and use it in GitHub Desktop.
Save misspokeycat/160d07d41a2f90325cefef8bf7eca437 to your computer and use it in GitHub Desktop.
#include <Arduino.h>
#include <Ps3Controller.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <ArduinoOTA.h>
#include <ESP32Servo.h>
// used for OTA flashing (will make this much easier to debug!)
// TODO: Fill this in with your wifi credentials
#define WIFI_SSID "myssid"
#define WIFI_PASS "mypass"
WiFiMulti WiFiMulti;
Servo myservo;
int servoPos = 90; // Initial position of the servo
int servoStep = 5; // Step size for servo movement
void onConnect(){
Serial.println("Connected.");
}
void notify()
{
}
void setup() {
Serial.begin(9600);
// DRV8833 motor driver setup
// Set the motor driver pins as outputs
// ESP32 GPIO pins 4,0,2,15
// Use PWM to control the speed of the motors
// 1 kHz frequency, 8-bit resolution
ledcSetup(0, 1000, 8);
ledcSetup(1, 1000, 8);
ledcSetup(2, 1000, 8);
ledcSetup(3, 1000, 8);
// Attach the PWM channels to the motor driver pins
// You may need to flip these around depending on how you have the motors wired
// Rear motors
// Rear (left) motor
ledcAttachPin(4, 0);
ledcAttachPin(0, 1);
// Rear (right) motor
ledcAttachPin(2, 3);
ledcAttachPin(15, 2);
// Front motors
// Front (left) motor
ledcAttachPin(16, 0);
ledcAttachPin(17, 1);
// Front (right) motor
ledcAttachPin(5, 2);
ledcAttachPin(18, 3);
// Attach the servo to pin 19
myservo.attach(19);
// Set the servo to its initial position
myservo.write(servoPos);
// Set all low to stop the motors
ledcWrite(0, 0);
ledcWrite(1, 0);
ledcWrite(2, 0);
ledcWrite(3, 0);
Serial.println("Setup complete. Waiting for PS3 controller...");
// Initialize the PS3 controller
Ps3.attach(notify);
Ps3.attachOnConnect(onConnect);
Ps3.begin("00:00:00:00:00:00"); // Replace with your PS3's MAC address
}
bool dpadUpDownPressed = false;
void loop() {
// Check if the PS3 controller is connected
if (Ps3.isConnected()) {
// Check to see if start + select is pressed
// If so, we will enter OTA mode
if (Ps3.data.button.select && Ps3.data.button.start) {
Serial.println("Entering OTA mode...");
// Stop the motors
ledcWrite(0, 0);
ledcWrite(1, 0);
ledcWrite(2, 0);
ledcWrite(3, 0);
// Disconnect the PS3 controller since we are going to OTA
Ps3.end();
// Connect to WiFi
WiFiMulti.addAP(WIFI_SSID, WIFI_PASS);
Serial.print("\n\nWaiting for WiFi... ");
// WIFI Connection, Reboot after 30 attempts
uint8_t not_connected_counter = 0;
while (WiFiMulti.run() != WL_CONNECTED)
{
Serial.print(".");
delay(100);
not_connected_counter++;
if (not_connected_counter > 30)
{
Serial.println("Resetting due to Wifi not connecting...");
ESP.restart();
}
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("MAC address: ");
Serial.println(WiFi.macAddress());
// OTA Configiration and Enable OTA
Serial.println("\nEnabling OTA Feature");
ArduinoOTA.setPassword("myotapassword");
ArduinoOTA.begin();
// Loop until OTA is complete
while (true) {
// Handle OTA updates
ArduinoOTA.handle();
delay(10);
}
}
// Set the motor speed based on the PS3 controller input
// Left stick Y-axis controls motor A speed
int motorASpeed = map(Ps3.data.analog.stick.ly, -127, 127, -255, 255);
// Right stick Y-axis controls motor B speed
int motorBSpeed = map(Ps3.data.analog.stick.ry, -127, 127, -110, 110);
// Deadzone for the motors
int deadzone = 40; // Adjust this value as needed
if (abs(motorASpeed) < deadzone) {
motorASpeed = 0; // Stop motor A
}
if (abs(motorBSpeed) < deadzone) {
motorBSpeed = 0; // Stop motor B
}
if (motorASpeed < 0) {
// DRV8833 motor driver sends aboslute values to the motor driver in reverse
// to drive the motor in reverse
ledcWrite(0, 0);
ledcWrite(1, abs(motorASpeed));
} else {
ledcWrite(0, motorASpeed);
ledcWrite(1, 0);
}
if (motorBSpeed < 0) {
ledcWrite(3, 0);
ledcWrite(2, abs(motorBSpeed)); // Reverse motor B
} else {
ledcWrite(3, motorBSpeed); // Forward motor B
ledcWrite(2, 0);
}
}
// Adjust servo speed with up/down dpad
// First, check debounce
if (Ps3.data.button.up && !dpadUpDownPressed) {
// Adjust servo step by 1 degree
servoStep += 1; // Adjust the step size as needed
if (servoStep > 10) {
servoStep = 10; // Limit the step size to a maximum value
}
dpadUpDownPressed = true; // Set the flag to indicate that the button is pressed
} else if (Ps3.data.button.down && !dpadUpDownPressed) {
servoStep -= 1;
if (servoStep < 1) {
servoStep = 1;
}
dpadUpDownPressed = true;
} else if (!Ps3.data.button.up && !Ps3.data.button.down) {
dpadUpDownPressed = false; // Reset the flag when both buttons are released
}
// Servo control (left/right dpad)
if (Ps3.data.button.left) {
servoPos += servoStep;
if (servoPos > 180) {
servoPos = 180; // Limit the position to 180 degrees
}
myservo.write(servoPos);
} else if (Ps3.data.button.right) {
servoPos -= servoStep;
if (servoPos < 0) {
servoPos = 0; // Limit the position to 0 degrees
}
myservo.write(servoPos);
}
// sleep for 10ms to avoid overloading the CPU
delay(10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment