Stepper motor position control

Hello,

In my code I set an integer ‘StepperPos’ to the position I want it to be. This should always be between a minimum of 0 and a maximum of 5000. I want this loop pasted below to detect the StepperPos when I set the move to 1. I’m doing something wrong I believe when the temporary position becomes negative?

Extra information, StepperPos / ActStepperPos / TempPos all start at 0; in the big code. But I figured I only post this loop to make it easier to read.

Should I make the negative values positive instead somehow first? Don’t mind the serial print temppos X, I added this to see where the code is running. I believe the biggest issue is that my StepperActPos doesn’t get updated properly due negative integer or something.

  if ((StepperMove == 1) && (StepperPos < StepperActPos))
  {
    Serial.println("StepperPos < StepperActPos");
    TempPos = (StepperPos - StepperActPos);
    Serial.print("TempPos 1: ");
    Serial.println(TempPos);
    if (TempPos < 0)
    {
      StepperActPos = (StepperActPos - TempPos);
      myStepper.step(-TempPos);
      Serial.print("TempPos 7: ");
      Serial.println(TempPos);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActPos);
      StepperMove = 0;
    }
    else
    {
      myStepper.step(-TempPos);
      StepperActPos = (StepperActPos - TempPos);
      Serial.print("TempPos 2: ");
      Serial.println(TempPos);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActPos);
      StepperMove = 0;
    }
  }


  if ((StepperMove == 1) && (StepperPos > StepperActPos))
  {
    Serial.println("StepperPos > StepperActPos");
    TempPos = (StepperPos + StepperActPos);
    Serial.print("TempPos 3: ");
    Serial.println(TempPos);
    if (TempPos > 5000)
    {
      TempPos = (5000 - StepperActPos);
      Serial.print("TempPos 4: ");
      Serial.println(TempPos);
      StepperActPos = TempPos;
      myStepper.step(StepperActPos);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActPos);
      StepperMove = 0;
    }

    else
    {
      TempPos = (StepperPos - StepperActPos);
      Serial.print("TempPos 5: ");
      Serial.println(TempPos);
      StepperActPos = TempPos;
      myStepper.step(StepperActPos);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActPos);
      StepperMove = 0;
    }
  }

If your intended position is 400 and your actual position is 800 that suggests to me that you need to move -400 steps and that is what the line

TempPos = (StepperPos - StepperActPos);

will give.

But later you have

myStepper.step(-TempPos);

which seems to me to take it from 800 to 1200 rather than back to 400.

If you have meaningful names for your variables I suspect you will find the logic easier to figure out. For example

stepsToCorrectPosition = desiredPosition - actualPosition;

If that doe not make sense then please explain the problem in more detail with some examples of the output from the program.

And post the complete program.

...R
Stepper Motor Basics
Simple Stepper Code

Dear Robin, I did a F&R on the integers and pasted the full code below. Code seemed to big with the post (9000 char limit). I attached the file but also updated the loop code below.

So the goal is the integer ‘StepperDesiredPosition’ is the only integer that gets changed outside the ‘stepper loop part’ I posted earlier. Then this loop is supposed to detected if the ‘StepperDesiredPosition’ is either higher or lower then the ‘StepperActualPosition’.

Depending on it’s outcome, it will then first detect if it’s not below or above 0 - 5000 using the StepperTempCalc calculation. Then we either move it positive or negative, depending of the StepperDesiredPosition was greater or lesser then the original StepperActualPosition.

Keep in mind, I’m quite positive I change the ‘StepperDesiredPosition’ as I want in the other code surrounding. The issue seems to be especially in the negative part. I’ve tried running through it in Notepad++ adding real numerical values to the integers but I’m just too stupid it seems.

Honestly, as stated earlier, this is my first project and I’m hitting a wall every week. But I’m almost there now…

  /* ############################################################
                START Set stepper to its position
    ############################################################  */
  if ((StepperMove == 1) && (StepperDesiredPosition < StepperActualPosition))
  {
    Serial.println("StepperDesiredPosition < StepperActualPosition");
    StepperTempCalc = (StepperDesiredPosition - StepperActualPosition);
    Serial.print("StepperTempCalc 1: ");
    Serial.println(StepperTempCalc);
    if (StepperTempCalc < 0)
    {
      StepperActualPosition = (StepperActualPosition - StepperTempCalc);
      myStepper.step(-StepperTempCalc);
      Serial.print("StepperTempCalc 2: ");
      Serial.println(StepperTempCalc);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
    else
    {
      myStepper.step(-StepperTempCalc);
      StepperActualPosition = (StepperActualPosition - StepperTempCalc);
      Serial.print("StepperTempCalc 3: ");
      Serial.println(StepperTempCalc);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
  }


  if ((StepperMove == 1) && (StepperDesiredPosition > StepperActualPosition))
  {
    Serial.println("StepperDesiredPosition > StepperActualPosition");
    StepperTempCalc = (StepperDesiredPosition + StepperActualPosition);
    Serial.print("StepperTempCalc 4: ");
    Serial.println(StepperTempCalc);
    if (StepperTempCalc > 5000)
    {
      StepperTempCalc = (5000 - StepperActualPosition);
      Serial.print("StepperTempCalc 5: ");
      Serial.println(StepperTempCalc);
      StepperActualPosition = StepperTempCalc;
      myStepper.step(StepperActualPosition);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }

    else
    {
      StepperTempCalc = (StepperDesiredPosition - StepperActualPosition);
      Serial.print("StepperTempCalc 6: ");
      Serial.println(StepperTempCalc);
      StepperActualPosition = StepperTempCalc;
      myStepper.step(StepperActualPosition);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
  }

  /* ############################################################
                END Set stepper to its position
    ############################################################  */

ScaleSimSource.ino (12.6 KB)

Mahoke:
So the goal is the integer 'StepperDesiredPosition' is the only integer that gets changed outside the 'stepper loop part' I posted earlier. Then this loop is supposed to detected if the 'StepperDesiredPosition' is either higher or lower then the 'StepperActualPosition'.

Depending on it's outcome, it will then first detect if it's not below or above 0 - 5000 using the StepperTempCalc calculation. Then we either move it positive or negative, depending of the StepperDesiredPosition was greater or lesser then the original StepperActualPosition.

That is not as clear to me as it may be to you. For example what does the highlighted "it's" refer to?

If you provide an example with numbers I may be better able to understand.

...R

Hello,

So the ‘StepperDesiredPosition’ is updated outside the loop. Let’s say I want to put it at 2000.
But the ‘StepperActualPosition’ is at a position aswell, at startup this is 0. But after use this could be anywhere between 0 and 5000.

So we have to check, is ‘StepperDesiredPosition’ < or > then ‘StepperActualPosition’ ?
Let’s say ‘StepperActualPosition’ is higher then the ‘StepperDesiredPosition’. Then we have to see, if we take ‘StepperDesiredPosition’ of the ‘StepperActualPosition’ would it go below zero? If so we just have to go to zero. So thats moving a negative ‘StepperActualPosition’ and we set the ‘StepperActualPosition’ to zero.

If it’s higher, we get to the other part in the loop. So ‘StepperDesiredPosition’ is > then ‘StepperActualPosition’. Then we have to see is ‘StepperDesiredPosition’ + ‘StepperActualPosition’ is below 5000. If it’s not, we move (‘StepperDesiredPosition’ - ‘StepperActualPosition’). And this value makes the new ‘StepperActualPosition’.

By typing it out like this it makes a bit more sense to me aswell… I’ll try to read my own code once again :slight_smile:

Mahoke:
So we have to check, is ‘StepperDesiredPosition’ < or > then ‘StepperActualPosition’ ?
Let’s say ‘StepperActualPosition’ is higher then the ‘StepperDesiredPosition’. Then we have to see, if we take ‘StepperDesiredPosition’ of the ‘StepperActualPosition’ would it go below zero?

For my benefit and for your own, I suspect, put in some example numbers like I did in Reply #1. For me, that makes it much easier to visualize a problem.

…R

I’ve figured it out myself. Thanks for helping me analyse though.

   if ((StepperMove == 1) && (StepperDesiredPosition < StepperActualPosition))
   //check if the new position if lower then the actual
  {
    Serial.println("StepperDesiredPosition < StepperActualPosition");
  //print this part is executed
    StepperTempCalc = (StepperDesiredPosition - StepperActualPosition);
  //calculate the result
    Serial.print("StepperTempCalc 1: ");
    Serial.println(StepperTempCalc);
    if (StepperTempCalc < 0)
  //check if the result is lower than 0
    {
    myStepper.step(-StepperActualPosition); //It would be below 0, so we only move the actual position backwards
      StepperActualPosition = 0; //it's lower then 0, so we move it to 0 which is the minimum 
      Serial.print("StepperTempCalc 2: ");
      Serial.println(StepperTempCalc);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
    else //If it's not below 0, we execute the new movement
    {
      myStepper.step(-StepperTempCalc); // move the stepper back by the difference between desire - actual 
      StepperActualPosition = (StepperActualPosition - StepperTempCalc); // update the actual position 
      Serial.print("StepperTempCalc 3: ");
      Serial.println(StepperTempCalc);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
  }


  if ((StepperMove == 1) && (StepperDesiredPosition > StepperActualPosition))
  {
    Serial.println("StepperDesiredPosition > StepperActualPosition");
    StepperTempCalc = (StepperDesiredPosition + StepperActualPosition);
    Serial.print("StepperTempCalc 4: ");
    Serial.println(StepperTempCalc);
    if (StepperTempCalc > 5000)
    {
      StepperTempCalc = (5000 - StepperActualPosition);
      Serial.print("StepperTempCalc 5: ");
      Serial.println(StepperTempCalc);
      StepperActualPosition = StepperTempCalc;
      myStepper.step(StepperActualPosition);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }

    else
    {
      StepperTempCalc = (StepperDesiredPosition - StepperActualPosition);
      Serial.print("StepperTempCalc 6: ");
      Serial.println(StepperTempCalc);
      StepperActualPosition = StepperTempCalc;
      myStepper.step(StepperActualPosition);
      Serial.print("Stepper Actual Position is : ");
      Serial.println(StepperActualPosition);
      StepperMove = 0;
    }
  }