AccelstepperLibrary help?

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.

stepper1.run() will only move one step at a time. The normal way to use accelstepper is to put the *.run()s into loop(){} so they can handle the acceleration and stepping as needed. Your loop has a call to controlStepperMotors() that looks like it would use runSpeed() to operate the steppers in constant speed mode and ignore position.

I think there's some logic/design issue that is unclear to me. If the joysticks are set at zero (or at some other speed), what do you expect the motors to do when you target the motors to the recalled position?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.