Arduino Uno, serial.read and accelstepper issue

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
}

code>

Your code to read the speed from the serial monitor is a SINGLE ASCII byte, not an INT.
Paul

Paul_KD7HB:
Your code to read the speed from the serial monitor is a SINGLE ASCII byte, not an INT.
Paul

Thank you. Is there a way I can convert it to an integer and then copy it to the variable "c"? Or some other solution?

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.

...R

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

void loop() {
  // recvWithEndMarker();
  // showNewNumber();
  run_stepper();
}

...R

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

void loop() {

// recvWithEndMarker();
 // showNewNumber();
 run_stepper();
}




...R

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

Thank you. I will read your tutorials.

Does the stepper run properly at startup?

It's working.

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.

Thanks for your help everyone.

Eric