Printing without blocking ex: stepper motor

Hi guys,
i am using the accelstepper library to control my stepper motor. However, i need to print the currentPosition of the stepper for visualization purposes.

void loop()
{

  stepper.moveTo(500);
  Serial.println(stepper.currentPosition()); 
  //or
  Serial.write(stepper.currentPosition());
  stepper.run();

}

When i use such code, the print or write function will block the code and cause the stepper motor not to run proparely.

Could you help ?

Set your serial Baud rate to the highest usable value.
Paul

It doesn't make sense to print the current position with every loop cycle. At least print only when the current position changed. With higher steprates even this seems too often and your print buffer will fill up totally - which leads to blocking.

2 Likes

you are right i do not need to print the position that much but is there a formula or a way to know the max frequency i can print the position with without affecting the stepper movement?

Depends on the baudrate and the number of characters you want to print. The baudrate defines how much time it takes to transmit one character ( with 115200 Baud it's about 90µs / char - In the long run you must not print more than 1char/90µs to avoid blocking ). As far as I know, the buffer is about 64 characters long.

Or you use my MobaTools library to move the stepper :wink: . This library creates the step pulses per timer interrupt and is not affected by blocking the loop.

1 Like

Hi again,

so i am using the following code to move a stepper motor to a new position with a certain speed using the serial commentation port. However, i can not get the stepper motor to run!
could you help ?

#include <AccelStepper.h>

#define PI 3.1415926535897932384626433832795
#define reductionRatio 2.72727272727

// AccelStepper Setup
AccelStepper stepper(1, 7, 6);   // 1 = Easy Driver interface
// NANO Pin 2 connected to STEP pin of Easy Driver
// NANO Pin 3 connected to DIR pin of Easy Driver


bool complete = false;
unsigned long curMillis;
unsigned long prevTime = 0;
unsigned long FeedbackInterval = 500;

const byte buffSize = 40;
char inputBuffer[buffSize];
const char startMarker = '<';
const char endMarker = '>';
byte bytesRecvd = 0;
boolean readInProgress = false;
boolean newDataFromPC = false;
int newPosition = 0;
int newSpeed = 0;
int previousPosition = 0;

void setup() {
  Serial.begin(9600);

  stepper.setMaxSpeed(500);     
  stepper.setAcceleration(200);
  // tell the PC we are ready
  Serial.println("<Arduino is ready>");

}

//=============
void loop()
{
  curMillis = millis();
  getDataFromPC();
  moveStepper(newPosition, newSpeed);
  sendToPC();
}

//=============

void getDataFromPC() {

  // receive data from PC and save it into inputBuffer

  if (Serial.available() > 0) {

    char x = Serial.read();

    // the order of these IF clauses is significant

    if (x == endMarker) {
      readInProgress = false;
      newDataFromPC = true;
      inputBuffer[bytesRecvd] = 0;
      parseData();
    }

    if (readInProgress) {
      inputBuffer[bytesRecvd] = x;
      bytesRecvd ++;
      if (bytesRecvd == buffSize) {
        bytesRecvd = buffSize - 1;
      }
    }

    if (x == startMarker) {
      bytesRecvd = 0;
      readInProgress = true;
    }
  }
}

//=============

void parseData() {

  // split the data into its parts

  char * strtokIndx; 

  strtokIndx = strtok(inputBuffer, ",");     
  newPosition = atoi(strtokIndx);     

  strtokIndx = strtok(NULL, ",");
  newSpeed = atoi(strtokIndx);    

}

//=============

void moveStepper(int newPosition, int newSpeed) {
if(newDataFromPC){
 // newDataFromPC = false;
  previousPosition = newPosition - previousPosition;
  stepper.setMaxSpeed(newSpeed);     
  stepper.setAcceleration(newSpeed);
  //  pos = (1090.90 * TravelX) / (PI * 20);
  //  stepper.moveTo( pos );  // Set new moveto position of Stepper

  stepper.move(previousPosition);
  previousPosition = newPosition;



  // Check if the Stepper has reached desired position
  if (stepper.distanceToGo() != 0)
  {
    stepper.enableOutputs(); //enable pins
    stepper.run(); //step the motor (this will step the motor by 1 step at each loop)
  }

  else //program enters this part if the required distance is completed
  {
    stepper.disableOutputs(); // disable power
    //  stepper.setCurrentPosition(0); //reset the position to zero
  }
  }
 

}

void sendToPC() {

  if (stepper.distanceToGo() != 0) {
    if (curMillis - prevTime >= FeedbackInterval) {
   
      Serial.println(stepper.currentPosition());
      prevTime = curMillis;
      complete = true;
    }

  }
  if (stepper.distanceToGo() == 0 && complete) {
    Serial.println(stepper.currentPosition());
   
    complete = false;
  }
}

The commands to control the stepper must not be included in the 'newDataFromPC' block. And you must reset the 'newDataFromPC' flag:

void moveStepper(int newPosition, int newSpeed) {
    if (newDataFromPC) {
        newDataFromPC = false;
        previousPosition = newPosition - previousPosition;
        Serial.println(newPosition);
        Serial.println(previousPosition);
        stepper.setMaxSpeed(newSpeed);
        stepper.setAcceleration(newSpeed);
        //  pos = (1090.90 * TravelX) / (PI * 20);
        //  stepper.moveTo( pos );  // Set new moveto position of Stepper

        stepper.move(previousPosition);
        previousPosition = newPosition;

    }


    // Check if the Stepper has reached desired position
    if (stepper.distanceToGo() != 0)
    {
        stepper.enableOutputs(); //enable pins
        stepper.run(); //step the motor (this will step the motor by 1 step at each loop)
    }

    else //program enters this part if the required distance is completed
    {
        stepper.disableOutputs(); // disable power
        //  stepper.setCurrentPosition(0); //reset the position to zero
    }
}

Btw: this
stepper.disableOutputs(); // disable power
will not work with a step/dir driver until you define and connect an enable pin.