Hey guys! I've been trying to setup a program that allows me to control stepper motors over http requests. Right now using a PS4 controller to do so. It works great so far.
Im new to programming so my code is probably super disorganized and improper.
I want to add the feature to store motor positions and recall them. I've tried to do it for the past few days but haven't had success.
In my clientPrint, the positions are displayed when I save them, but recallmotorpositions won't move the motors. My logic is probably wrong.
Can anyone recommend how I should move forward? Here is my code.
#include <AccelStepper.h>
#include <Ethernet.h>
// Define the Ethernet settings
byte mac[] = {0xA8, 0x61, 0x0A, 0xAE, 0x03, 0x30}; // Your MAC address
IPAddress ip(192, 168, 0, 236); // IP address of your Arduino
EthernetServer server(44158);
// Connections to A4988 for first motor
const int stepPin1 = 3; // Step
const int dirPin1 = 2; // Direction
const int ms1Pin1 = 10; // Microstep
const int ms2Pin1 = 11; // Microstep
const int ms3Pin1 = 12; // Microstep
// Connections to A4988 for second motor
const int stepPin2 = 31; // Step for second motor
const int dirPin2 = 30; // Direction for second motor
const int ms1Pin2 = 32; // Microstep for second motor
const int ms2Pin2 = 33; // Microstep for second motor
const int ms3Pin2 = 34; // Microstep for second motor
AccelStepper stepper1(AccelStepper::DRIVER, stepPin1, dirPin1);
AccelStepper stepper2(AccelStepper::DRIVER, stepPin2, dirPin2);
float x_axis_value_left; // Variable to store X-axis value from left stick
float x_axis_value_right; // Variable to store X-axis value from right stick
// Variables to store motor positions
int saved_position1 = 0;
int saved_position2 = 0;
// Function to handle HTTP request and retrieve axis value
void handleSetJoystickInputRequest() {
EthernetClient client = server.available();
if (client) {
if (client.connected()) {
String request = client.readStringUntil('\r');
client.flush();
if (request.indexOf("GET /setJoystickInput") != -1) {
// Parse the x_axis value from the request parameters
float x_axis_left = parseFloatParameter(request, "x_axis");
// Store the x_axis value
x_axis_value_left = x_axis_left;
// Parse the x_axis value from the request parameters for right stick
float x_axis_right = parseFloatParameter(request, "x_axis_right");
// Store the x_axis value for right stick
x_axis_value_right = x_axis_right;
// Send a response to the client
int motor_speed_left = map(x_axis_left, -1, 1, -400, 400); // Adjust mapping as needed
int motor_speed_right = map(x_axis_right, -1, 1, -400, 400); // Adjust mapping as needed
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<h1>X-axis value (Left stick) received:</h1> ");
client.print(x_axis_left);
client.print("<br>");
client.print("<h1>Motor Speed (Left motor):</h1> ");
client.print(motor_speed_left);
client.print("<br>");
client.print("<h1>X-axis value (Right stick) received:</h1> ");
client.print(x_axis_right);
client.print("<br>");
client.print("<h1>Motor Speed (Right motor):</h1> ");
client.print(motor_speed_right);
// Print the current motor positions
client.print("<br>");
client.print("<h1>Current Motor Positions:</h1> ");
client.print("<br>");
client.print("Motor 1: ");
client.print(stepper1.currentPosition());
client.print("<br>");
client.print("Motor 2: ");
client.print(stepper2.currentPosition());
client.println();
client.stop();
}
if (request.indexOf("GET /saveMotorPositions") != -1) {
saveMotorPositions();
// Send response to the client
// Your response code here
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<h1>Motor positions saved.</h1>");
client.println();
client.print("Motor 1: ");
client.print(stepper1.currentPosition());
client.print("<br>");
client.print("Motor 2: ");
client.print(stepper2.currentPosition());
client.print("<h1>Motor positions saved: </h1>");
client.println(saved_position1);
client.println(saved_position2);
client.stop();
}
if (request.indexOf("GET /recallMotorPositions") != -1) {
recallMotorPositions();
// Send response to the client
// Your response code here
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("<h1>Motor positions recalled.</h1>");
client.println();
client.stop();
}
}
}
}
// Function to control the stepper motors based on joystick input
void controlStepperMotors() {
// Read the latest values of x_axis from the variables
float x_axis_left = x_axis_value_left;
float x_axis_right = x_axis_value_right;
// Adjust motor speed and direction based on x_axis value from left stick
int motor_speed_left = map(x_axis_left * 100, -100, 100, -400, 400); // Adjust mapping as needed
int motor_direction_left = (motor_speed_left >= 0) ? 1 : -1;
motor_speed_left = abs(motor_speed_left);
// Adjust motor speed and direction based on x_axis value from right stick
int motor_speed_right = map(x_axis_right * 100, -100, 100, -400, 400); // Adjust mapping as needed
int motor_direction_right = (motor_speed_right >= 0) ? 1 : -1;
motor_speed_right = abs(motor_speed_right);
// Control the first stepper motor (left motor)
stepper1.setMaxSpeed(motor_speed_left);
stepper1.setSpeed(motor_speed_left * motor_direction_left);
stepper1.runSpeed();
// Control the second stepper motor (right motor)
stepper2.setMaxSpeed(motor_speed_right);
stepper2.setSpeed(motor_speed_right * motor_direction_right);
stepper2.runSpeed();
}
// Function to save current motor positions
void saveMotorPositions() {
saved_position1 = stepper1.currentPosition();
saved_position2 = stepper2.currentPosition();
}
// Function to recall saved motor positions
void recallMotorPositions() {
stepper1.setMaxSpeed(1000); // Adjust as needed
stepper1.setAcceleration(500); // Adjust as needed
stepper2.setMaxSpeed(1000); // Adjust as needed
stepper2.setAcceleration(500); // Adjust as needed
delay(100);
stepper1.moveTo(saved_position1);
stepper2.moveTo(saved_position2);
stepper1.run();
stepper2.run();
}
// Function to parse float parameter value from HTTP request
float parseFloatParameter(String request, String parameterName) {
int startIndex = request.indexOf(parameterName);
if (startIndex == -1) {
return 0.0; // Parameter not found
}
startIndex += parameterName.length() + 1; // Skip parameter name and '=' character
int endIndex = request.indexOf('&', startIndex); // Find end of parameter value
if (endIndex == -1) {
endIndex = request.indexOf(' ', startIndex); // If no '&' character, find end of request
}
String valueStr = request.substring(startIndex, endIndex); // Extract parameter value
return valueStr.toFloat(); // Convert parameter value to float
}
void setup() {
pinMode(ms1Pin1, OUTPUT);
pinMode(ms2Pin1, OUTPUT);
pinMode(ms3Pin1, OUTPUT);
pinMode(ms1Pin2, OUTPUT);
pinMode(ms2Pin2, OUTPUT);
pinMode(ms3Pin2, OUTPUT);
digitalWrite(ms1Pin1, HIGH);
digitalWrite(ms2Pin1, HIGH);
digitalWrite(ms3Pin1, HIGH);
digitalWrite(ms1Pin2, HIGH);
digitalWrite(ms2Pin2, HIGH);
digitalWrite(ms3Pin2, HIGH);
// Initialize Serial communication
Serial.begin(9600);
while (!Serial) {
; // Wait for Serial port to connect
}
// Initialize Ethernet and wait for a DHCP address.
Ethernet.begin(mac, ip);
// Start the server
server.begin();
// Set the maximum speed and acceleration
stepper1.setMaxSpeed(400); // Adjust as needed
stepper1.setAcceleration(1000); // Adjust as needed
stepper2.setMaxSpeed(400); // Adjust as needed
stepper2.setAcceleration(1000); // Adjust as needed
}
void loop() {
handleSetJoystickInputRequest(); // Handle HTTP request to set joystick input
controlStepperMotors(); // Control the stepper motors based on joystick input
}
here is the code in action.