Created
May 14, 2025 20:35
-
-
Save misspokeycat/160d07d41a2f90325cefef8bf7eca437 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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