Am trying to control two separate stepper motors via commands from the serial monitor. Am keeping it simple at the start and just try to send one of two commands, either make stepper 1 turn, or make stepper 2 turn. Have butchered the multiple stepper example with some bits to add serial communication.
If for example, I send "servo1", I will get both test point checks being sent back, however, I am getting zero movement from the steppers. Have had a look at some other examples online of people doing similar, but wasnt able to find one with the same Accellibrary being used.
Have you been able to get the motor to move with one of the examples from the AccelStepper library?
If not, do that first so you are just focused on a single problem.
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.
When using Cstrings you must use strcmp() to compare values rather than ==
And have a look at the examples in Serial Input Basics - simple reliable ways to receive data.
You will make your Arduino program much easier to develop if you just send single character commands. Using the alphanumeric characters you can have 62 separate single character commands. If you need to send a command and a value (such as the number of steps) I recommend using the technique in the 3rd example in Serial Input Basics.
Cheers for the reply Robin2, I had managed to get the example working before I started trying to make adjustments.
Took out the strings and have made the checks just look for single character commands, also have tried implementing string compares, but I think I may be screwing up the syntax of them a little bit. I haven't done a lot of work with sending data via serial monitor before, but will read the sites and threads you sent over, thanks for that.
Is this the correct way of doing the strcmp or does it need to be done this way?
result = strcmp(example1, example2);
if (result == 0)
For the moment, I just want to get to the point where sending "a" makes stepper one move, and sending "b", makes stepper two move. Although, in the future I will need to be able to send the number of steps so will give example 3 a look.
Thanks again for the help, in its current state, each time I send an 'a' or a 'b', it moves the respective stepper motor by one step. Although, as you can probably tell from the code, I am trying to get them to do full rotations not just single steps.
I am guessing the issue is due to the stepper1.run() and stepper2.run() being inside an IF statement, so only incrementing by a single step each time. I am unsure of how to rectify this though, how can I take them out of the IF and still keep the check in place?
Stuck the stepper.run in the main code, it is responding to the serial monitor and doing what I want now. However, every time the code is loaded onto the Arduino, both steppers do a half turn in the same direction?
#include <AccelStepper.h>
AccelStepper stepper1(AccelStepper::FULL4WIRE, 5, 6, 7, 8);
AccelStepper stepper2(AccelStepper::FULL4WIRE, 9, 10, 11, 12);
int movement = 360;
void setup()
{
Serial.begin(9600);
stepper1.setMaxSpeed(200.0);
stepper1.setAcceleration(100.0);
stepper1.moveTo(movement);
stepper2.setMaxSpeed(200.0);
stepper2.setAcceleration(100.0);
stepper2.moveTo(movement);
}
char inBuffer = "";
void loop()
{
if(Serial.available()>0)
{
inBuffer = Serial.read();
}
if (inBuffer == 'a')
{
Serial.println("test point 1");
if (stepper1.distanceToGo() == 0)
stepper1.moveTo(-stepper1.currentPosition());
}
if (inBuffer == 'b')
{
Serial.println("test point 2");
if (stepper2.distanceToGo() == 0)
stepper2.moveTo(-stepper2.currentPosition());
}
stepper1.run();
stepper2.run();
inBuffer = "";
}
How would you recommend getting around this issue?
Robin2:
The Arduino is a great system for learning-by-doing.
from the code and it ddn't work at all. Also tried adding a small one time only delay at the start but that did nothing either. If it helps, this is the library I am using.
from the code and it ddn't work at all. Also tried adding a small one time only delay at the start but that did nothing either.
When you make changes to a program you need to include the latest version of the program with your comments - otherwise we have no idea what you have done. My guess is that you removed the code from the wrong place.
Cheers for the guidance, have been trying today to implement your suggestions and this is what I have changed it to.
#include <AccelStepper.h>
AccelStepper stepper1(AccelStepper::FULL4WIRE, 5, 6, 7, 8); //Sets up the pins for stepper one
AccelStepper stepper2(AccelStepper::FULL4WIRE, 9, 10, 11, 12); //Sets up the pins for stepper two
int start_var = 0;
int movement = 360;
long newStepper1Pos = 0; // varialbe for the new stepper position for variable 1
long newStepper2Pos = 0; // variable for the new stepper position for variable 2
void setup()
{
Serial.begin(9600);
stepper1.setMaxSpeed(200.0); //Sets the max speed for stepper 1
stepper1.setAcceleration(100.0); //Sets the acceleration for stepper 1
stepper1.moveTo(movement);
stepper2.setMaxSpeed(200.0); //Sets the max speed for stepper 2
stepper2.setAcceleration(100.0); //Sets the acceleration for stepper 2
stepper2.moveTo(movement);
}
char inBuffer = "";
void loop()
{
if(Serial.available()>0) // If any information is avaiable coming from the serial monitor
{
inBuffer = Serial.read(); // Puts the information coming from the serial monitor in the input buffer
}
if (inBuffer == 'a') // If the command sent is an 'a'
{
Serial.println("test point 1"); //Serial print for test point 1
if (stepper1.distanceToGo() == 0)
newStepper1Pos = -stepper1.currentPosition;
stepper1.moveTo(newStepperPos);
if (stepper2.distanceToGo() == 0)
newStepper2Pos = -stepper2.currentPosition;
stepper2.moveTo(newStepperPos);
}
stepper1.run();
stepper2.run();
inBuffer = ""; //Sets the input buffer back to nothing as to not create a loop
}
I am getting an interesting error message in the form of "wrong type argument to unary minus" which I don't really know what it means.
I tried setting the moveTo() equal to zero so that maybe when the program moved, it wouldn't move until a command was sent, however this just resulted in no movement what so ever.
stepper1.setMaxSpeed(200.0); //Sets the max speed for stepper 1
stepper1.setAcceleration(100.0); //Sets the acceleration for stepper 1
stepper1.moveTo(0);
stepper2.setMaxSpeed(200.0); //Sets the max speed for stepper 2
stepper2.setAcceleration(100.0); //Sets the acceleration for stepper 2
stepper2.moveTo(0);
I am looking through the functions that come with this library to see if there is a way of just setting an initial start point for the servo motors so that they can always start from the same position. Thanks again for the help!
void loop()
{
if(Serial.available()>0) // If any information is avaiable coming from the serial monitor
{
inBuffer = Serial.read(); // Puts the information coming from the serial monitor in the input buffer
}
if (inBuffer == 'a') // If the command sent is an 'a'
{
Serial.println("test point 1"); //Serial print for test point 1
if (stepper1.distanceToGo() == 0) {
if (stepper1.currentPosition() == 0) {
stepper1.moveTo(movement);
}
else {
stepper1.moveTo(0);
}
}
if (stepper2.distanceToGo() == 0) {
if (stepper2.currentPosition() == 0) {
stepper2.moveTo(movement);
}
else {
stepper2.moveTo(0);
}
}
inBuffer = ""; // clear this immediately the 'a' has been used
}
stepper1.run();
stepper2.run();
}