How to make stepper motors remember their positions?

Hello! For a school project, I am making a camera slider, using 3 nema 17 motors and an arduino uno. Its going to be controlled trough an MIT app inventor application.
One motor is for the sliding, one is for the pan and one is for the tilt of the camera. I am using the AccelStepper library for them.

Currently i am just making a crude version of the program, which will have a button for the slider to perform a movement to the left ( as you can see, i still have to polish the movements it does, but this is just a test version ), one to the right and a stop button.

I want it to work so that it can remember its position. For example, if i randomly press STOP while its still performing the right movement , it should know where it left off, so if i then press the right button again, it will do the remainder of the steps to that position ( or to the left, if i pressed the left button) .
In order for the program to achieve that, i wrote currentPosition = stepper.currentPosition() for each motor under the loops, does that work?

I am so sorry if this is confusing, i am very unexperienced at this, but thank you so much for any insights!!!!

#include <AccelStepper.h>
#include <SoftwareSerial.h> // library for bluetooth communication


// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 7, 6); // Stepper for sliding
AccelStepper stepper2(1, 5, 4); //Stepper for pan
AccelStepper stepper3(1, 3, 2); //Stepper for tilt
#define RX_PIN 0
#define TX_PIN 1
#define limitSwitchLeft A1



SoftwareSerial bluetoothSerial(0, 1); // RX, TX
String command; // String for storing received commands


// Declare the global variables for storing the current positions of the steppers
long currentPosition1 = 0;
long currentPosition2 = 0;
long currentPosition3 = 0;


void setup() {
  // Set initial seed values for the steppers
  stepper1.setMaxSpeed(3000);
  stepper1.setSpeed(200);
  stepper2.setMaxSpeed(3000);
  stepper2.setSpeed(200);
  stepper3.setMaxSpeed(3000);
  stepper3.setSpeed(200);

 
   // Move the slider to the initial position - homing
  while (digitalRead(limitSwitchLeft) != 0) {                     //loop works until limit switch activated 
    stepper1.setSpeed(3000);                                       //movement speed
    stepper1.runSpeed();                                          // execute movement 
    stepper1.setCurrentPosition(0);      // When limit switch pressed set position to 0 steps
    stepper2.setCurrentPosition(0);
    stepper3.setCurrentPosition(0);
  }
} 

void loop() {

  if (bluetoothSerial.available()) {
    String command = bluetoothSerial.readString();
    if (command == "right") {                                        //if it recevies "right" it will execute this  program
      stepper1.setMaxSpeed(3000);
      stepper1.setSpeed(3000);
      stepper1.moveTo(60000);
      stepper2.setMaxSpeed(2000);
      stepper2.setSpeed(2000);
      stepper2.moveTo(4000);
      stepper3.setMaxSpeed(1000);
      stepper3.setSpeed(1000);
      stepper3.moveTo(2000);
    
      currentPosition1 = stepper1.currentPosition();   // memorising position ( not sure if works)
      currentPosition2 = stepper2.currentPosition();
      currentPosition3 = stepper3.currentPosition();
      
    }
    else if (command == "left") {                                 // if it recevies "left", it will execute this program
      stepper1.setMaxSpeed(3000);
      stepper1.setSpeed(3000);
      stepper1.moveTo(-60000);
      stepper2.setMaxSpeed(2000);
      stepper2.setSpeed(2000);
      stepper2.moveTo(-4000);
      stepper3.setMaxSpeed(1000);
      stepper3.setSpeed(1000);
      stepper3.moveTo(2000);
    
    currentPosition1 = stepper1.currentPosition();
    currentPosition2 = stepper2.currentPosition();
    currentPosition3 = stepper3.currentPosition();
     
    }
       }
    else if (command == "stop") {      // if it recevies "stop" it will stop the execution of "left" or "right"
      stepper1.stop();
      stepper2.stop();
      stepper3.stop();
     currentPosition1 = stepper1.currentPosition();
     currentPosition2 = stepper2.currentPosition();
     currentPosition3 = stepper3.currentPosition();
  }
}

You've made at least one very common mistake. You forgot to mention what type of Arduino you are using.

#include <SoftwareSerial.h> // library for bluetooth communication
...
#define RX_PIN 0
#define TX_PIN 1

On most arduino you can't use pins 0, 1 for software serial or any other purpose because they are already in use for uploading your code and using serial monitor. At the moment, this isn't relevent to your current problem/question. But you asked for help, I read your code and that was the first alarm warning I saw.

2 Likes

These are not good names for the steppers. It would be very easy to make a coding error by forgetting which stepper is tilt and which stepper is slide, for example. Why not call them "slideStepper", "tiltStepper" and "panStepper"? This may seem like trivial advice, but many coding errors are due to simple errors and confusions, so anything that could reduce the chances of an error like that are worthwhile.

1 Like

Oh, the arduino I use is an UNO. The schematic I have says that apparently 0 is RX0 and 1 is TX0 on the UNO, and thats where im supposed to connect the bluetooth module, but ill look into it more! Thank you!!

Thats true lol, thank you, ill change it right away! Forgot thats even a possibility, but makes it much better!

That's true. But it doesn't mean you can easily use them for other things. They are already dedicated to uploading your code and using serial monitor, meaning they are dedicated to communicating with your pc/laptop. With great care, an expert may be able to use them for a second purpose, but not a beginner.

An expert would say to themselves "I need an Arduino with 2 serial (UART) interfaces. One for the PC/laptop and another for the Bluetooth. Uno does not have 2 so I will choose a different type of arduino like Mega or Pro Micro".

3 Likes

You should stop the motor first. Then get currentPosition. To get the current target position, call long targetPos = stepper.targetPositiion() before calling stepper.stop(). The stepper.stop() function calculates how many steps it will take to stop the motor and sets a new target position. After that, use stepper.runToPosition() to complete the stop. Then you can use currentPosition to know where you stopped. You can continue to the previous target with stepper.moveTo(targetPos).

1 Like

You are right, it would be best to get an arduino Mega for this project anyways, given how much pins i require.. Thanks!!

Thank you so much!!

Personally I would not use Mega because of its inconvenient form factor. Pro Micro or maybe Nano Every since both have an available UART.

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