Stepper Motor Linear Position w/o Feedback

Hello All,

As the title suggests, I am attempting to keep track of the phase and position of a bipolar stepper motor without feedback.

I have the stepper motor connected to a helical screw to provide linear motion of a small platform, think of the x axis of a 3D printer.

At this phase of the project my goal is to input a position via the serial port and have the platform move to that position.

i.e. The platform is at position 200, I enter 300, the stepper steps 100 steps in the positive direction.

The bulk of my code is working as intended however, I am having trouble entering digits to the serial port and having them executed properly.

THE ISSUE:

If I enter 56, the code will process the '5' then loop and process the '6'. I intend it to process the entire value of 56.

I have attached the code and highlighted the troubled section.

This method worked for a simpler test sketch, I believe the issue arises with the while loop and the if statements using the variable I wish to fill with me serial input.

Any explanation as to why my method did not work as intended would be appreciated as I come from a lowly mechanical background:)

motor_position_via_serial.ino (3.19 KB)

String inString = "";

int pwmA = 3;
int pwmB = 11;

int dirA = 12;
int dirB = 13;

int dt = 2;
int ms = 100;
int st = 0;
int state = LOW;

//int for_seq[] = {0,1,2,3};
//int rev_seq[] = {3,2,1,0};

int new_pos;
int cur_pos = 0;
int move_dist = 0;
int mot_state = 0;

const int mod = 4;

void setup()
{
Serial.begin(9600);
pinMode(pwmA,OUTPUT);
pinMode(pwmB,OUTPUT);
pinMode(dirA,OUTPUT);
pinMode(dirB,OUTPUT);

Serial.println("Motor Start Sequence Initiate");
start_up(); //start up sequence to position motor into A position
motor_stop();
Serial.println("Motor Ready Enter Position");
}

void loop()
{
/* ***********************************
I believe my error lies in using this while loop to grab
a two or more didget number and move the platform to that position.
*/

while(Serial.available()>0)
{
int inChar = Serial.read();
inString += (char)inChar;
new_pos = inString.toInt();
if (Serial.available()=='\n')
{
break;
}
}

inString = "";

move_dist = new_pos - cur_pos;

if(move_dist>0)
{
for(int dist_count=0;dist_count<=move_dist;dist_count++)
{
int x = (mot_state + dist_count +1)%mod;
if(x==0){step_1();}
if(x==1){step_2();}
if(x==2){step_3();}
if(x==3){step_4();}
Serial.println(x);
}
cur_pos = cur_pos + move_dist;
Serial.print("new_pos: ");
Serial.println(new_pos);
Serial.print("cur_pos: ");
Serial.println(cur_pos);
mot_state = (mot_state+cur_pos)%mod;
Serial.print("mot_state: ");
Serial.println(mot_state);
}
else if(move_dist<0)
{
for(int dist_count=0;dist_count<=abs(move_dist);dist_count++)
{
int y = (mot_state + dist_count + 1)%mod;
if(y==0){step_1();}
if(y==1){step_2();}
if(y==2){step_3();}
if(y==3){step_4();}
Serial.println(y);
}
cur_pos = cur_pos + move_dist;
Serial.print("new_pos: ");
Serial.println(new_pos);
Serial.print("cur_pos: ");
Serial.println(cur_pos);
//modular substraction
mot_state = abs((mot_state-cur_pos)%mod);
Serial.print("mot_state: ");
Serial.println(mot_state);
}
else
{
motor_stop();
}
/*Serial.print("new_pos: ");
Serial.println(new_pos);
Serial.print("cur_pos: ");
Serial.println(cur_pos);
*/

}

void step_1()
{
digitalWrite(dirA,state);
digitalWrite(dirB,state);
analogWrite(pwmA,ms);
analogWrite(pwmB,st);
delay(dt);
}
void step_2()
{
digitalWrite(dirA,state);
digitalWrite(dirB,state);
analogWrite(pwmA,st);
analogWrite(pwmB,ms);
delay(dt);
}
void step_3()
{
digitalWrite(dirA,!state);
digitalWrite(dirB,state);
analogWrite(pwmA,ms);
analogWrite(pwmB,st);
delay(dt);
}
void step_4()
{
digitalWrite(dirA,state);
digitalWrite(dirB,!state);
analogWrite(pwmA,st);
analogWrite(pwmB,ms);
delay(dt);
}
void start_up()
{
for(int i=0;i<20;i++)
{
forward();
}
for(int j=0;j<15;j++)
{
reverse();
}

}
void forward()
{
step_1();
step_2();
step_3();
step_4();
}
void reverse()
{
step_4();
step_3();
step_2();
step_1();
}
void motor_stop()
{
digitalWrite(dirA,state);
digitalWrite(dirB,!state);
analogWrite(pwmA,st);
analogWrite(pwmB,st);
}

I suspect one of the examples in serial input basics will meet your requirement for receiving data.

And please read "how to use the Forum" and put your code in code tags - the '</>' button

so it looks like this

and is easy to copy to a text editor. If it is too long add the .ino file as an attachment - but preferably make a short program that illustrates the problem.

...R

You are acting on each character. You should act only when the newline arrives.

void loop() {
  int inChar = Serial.read();

  if (inChar == '\n') {
    ProcessInput(inString);
    inString = "";
  }
  else if (isdigit(inChar)) {
    inString += (char)inChar;
  }
}

void ProcessInput(String input) {
  new_pos = input.toInt();

  int move_dist = new_pos - cur_pos;
  if (move_dist == 0) {
    motor_stop();
  } else {
    Move(move_dist);
    cur_pos = cur_pos + move_dist;

    Serial.print("new_pos:  ");
    Serial.println(new_pos);
    Serial.print("cur_pos:  ");
    Serial.println(cur_pos);
    //modular substraction
    mot_state = abs((mot_state - cur_pos) % mod);
    Serial.print("mot_state:  ");
    Serial.println(mot_state);
  }
}

void Move(int move_dist) {
  if (move_dist > 0)
  {
    for (int dist_count = 0; dist_count <= move_dist; dist_count++)
    {
      int x = (mot_state + dist_count + 1) % mod;
      if (x == 0) {
        step_1();
      }
      if (x == 1) {
        step_2();
      }
      if (x == 2) {
        step_3();
      }
      if (x == 3) {
        step_4();
      }
      Serial.println(x);
    }
    cur_pos = cur_pos + move_dist;
    Serial.print("new_pos:  ");
    Serial.println(new_pos);
    Serial.print("cur_pos:  ");
    Serial.println(cur_pos);
    mot_state = (mot_state + cur_pos) % mod;
    Serial.print("mot_state:  ");
    Serial.println(mot_state);
  } else {
    for (int dist_count = 0; dist_count <= abs(move_dist); dist_count++)
    {
      int y = (mot_state + dist_count + 1) % mod;
      if (y == 0) {
        step_1();
      }
      if (y == 1) {
        step_2();
      }
      if (y == 2) {
        step_3();
      }
      if (y == 3) {
        step_4();
      }
      Serial.println(y);
    }
  }
}