I have a little stepper project and I am using an uno and accelstepper to drive it.
I want to run the stepper at a speed, but be able to change the speed by inputting a new speed via the serial port.
I have created code that does run the stepper at the initial speed but as soon as I try to send a new speed the stepper stops.
Right now I am sending the new speed via serial monitor. If I get this to work, the new speed will come from another arduino uno via the serial ports on both boards.
I included a serial write in the program so I can see that it is returning the correct number and it is.
By the way I am a newbie.
Here is my code:
<
#include <AccelStepper.h> //include the accelstepper library
AccelStepper stepper(AccelStepper::DRIVER, 9, 10); //let accelstepper know I'm using a driver and the step and direction pins
int c = 1000; // declare integer and start the stepper at 1000 steps per second
void setup() //run once
{
Serial.begin(9600); //start the serial port
stepper.setMaxSpeed(20000); //set the maximum speed for the stepper
stepper.setSpeed(c); //run the stepper at 1000 steps per second
}
void loop() //do over and over
{
if (Serial.available()) //if the serial port is available then:
{
c = Serial.read(); //read the new speed number I manually send from serial monitor and stick it in the variable "c"
Serial.write(c); //this is to see if the variable "c" is getting the number I type in the serial monitor - it is.
}
stepper.setSpeed(c); //run the stepper at the new commanded speed
stepper.runSpeed(); //command to make the stepper run
}
Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.
Thanks for your help. I read the whole thing and used the example #4 to get the text data into an integer.
I've combined the example code with my stepper code. The example code works well as combined but the stepper code does not.
Here is the combined code:
// Example 4 - Receive a number as text and convert it to an int
#include <AccelStepper.h> //include the accelstepper library
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
AccelStepper stepper(AccelStepper::DRIVER, 9, 10); //let accelstepper know I'm using a driver and the step and direction pins
int dataNumber = 1000; // this will be the stepper speed integer and sets it to 1000 at first
void setup() {
Serial.begin(9600);
Serial.println("<Arduino is ready>");
stepper.setSpeed(dataNumber); //run the stepper at 1000 steps per second
}
void loop() {
recvWithEndMarker();
showNewNumber();
run_stepper();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
if (Serial.available() > 0) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
void showNewNumber() {
if (newData == true) {
dataNumber = 0; // new for this version
dataNumber = atoi(receivedChars); // new for this version
Serial.print("This just in ... ");
Serial.println(receivedChars);
Serial.print("Data as Number ... "); // new for this version
Serial.println(dataNumber); // new for this version
newData = false;
}
}
void run_stepper() {
stepper.setSpeed(dataNumber); //run the stepper at the new commanded speed
stepper.runSpeed(); //command to make the stepper run
}
With the combined code, the stepper no longer runs at the initial speed of 1000 steps/s, nor does it run at a new speed if I enter a new speed.
In fact, on the second to last line of code if I put an actual number in there, for example:
stepper.setSpeed(1000);
the stepper still refuses to run.
Is it possible the serial read code keeps the arduino sufficiently busy or is so slow that it can't execute the stepper code? Some other issue?
The function recvWithEndMarker() should take very little time, especially if there is no data to be received.
The function showNewNumber() will only take time once for every time a number is received. Otherwise it should be extremely brief. The print statements in it will be the slowest part.
What value is showNewNumber() displaying?
What happens if you temporarily comment out these two calls so only the run_stepper() function is active
The problems and the solutions to reading user input (and doing other things) while driving a stepper motor are covered in detail in my tutorial Multi-tasking in Arduino
This builds on my tutorial Text I/O for the Real World which covers non-blocking input and output, user commands and entering setpoints etc.
Both of them rely on my SafeString library which provides safe string handling and non-blocking reading and writing. The tutorial for SafeString is here
Robin2:
The function recvWithEndMarker() should take very little time, especially if there is no data to be received.
The function showNewNumber() will only take time once for every time a number is received. Otherwise it should be extremely brief. The print statements in it will be the slowest part.
What value is showNewNumber() displaying?
What happens if you temporarily comment out these two calls so only the run_stepper() function is active
showNewNumber() was displaying the number I sent from the serial monitor.
I ran the code with the other call commented out and the stepper still won't run.
drmpf:
The problems and the solutions to reading user input (and doing other things) while driving a stepper motor are covered in detail in my tutorial Multi-tasking in Arduino
This builds on my tutorial Text I/O for the Real World which covers non-blocking input and output, user commands and entering setpoints etc.
Both of them rely on my SafeString library which provides safe string handling and non-blocking reading and writing. The tutorial for SafeString is here
In the combined code I missed an important accellstepper call namely:
stepper.setMaxSpeed(20000);
I had it in my original stepper code but when I combined my code with the code in example 4 I accidentally missed it. The stepper doesn't run without it.
It's working nicely now and I can change the stepper speed via the serial monitor.