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.
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.
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 . This library creates the step pulses per timer interrupt and is not affected by blocking the loop.
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.