Dear all,
I started from a working example that I wrote a few years ago, where a single character input in the serial monitor was used to choose the direction and the amount of stepper rotation. This was successfully managed inside the loop().
Now I need two parameters:
- the single character that determines the direction and the amount of stepper rotation
- the number of repetitions of that very same rotation. e.g., 5 times rotation "Q".
To that purpose, I tried to get the two values in the setup() function.
Another need that arises is checking within the loop() whether a rotation is completed, to reset the starting point and to repeat the rotation. I thought that checking for distanceToGo() == 0 would suffice.
Now I'm stupidly stuck with two problems:
- A) my very first Serial.println is not shown
- B) while the desired number of rotations is correctly acquired, the String incomingByte = Serial.readString(); doesn't wait for any input on my part, and the setup ends without waiting for my input. This is the serial monitor output that I'm getting after my initial input (7 + enter):
You required 7 rotations.
Which kind of rotation is required ?
Available commands:
====> 360° Rotation
o = 360° clockwise rotation
O = 360° counter-clockwise rotation
====> Rotation by small increments
k = rotate 4° clockwise
K = rotate 4° counter-clockwise
f = rotate 5° clockwise
F = rotate 5° counter-clockwise
t = rotate 10° clockwise
T = rotate 10° counter-clockwise
w = rotate 20° clockwise
W = rotate 20° counter-clockwise
q = rotate 40° clockwise
Q = rotate 40° counter-clockwiseReceived
Starting rotation number 1 of 7
Starting rotation number 2 of 7
Starting rotation number 3 of 7
Starting rotation number 4 of 7
Starting rotation number 5 of 7
Starting rotation number 6 of 7
Starting rotation number 7 of 7
The full code is attached here: thanks for your help!
/*
Stepper-based microscope Z-stage
Circuit and comments:
See http://www.cesarebrizio.it/Arduino/Z-Stage.html
Circuit is as illustrated here:
https://www.tdegypt.com/wp-content/uploads/2017/08/stepper-motor-wiring.png
the only exception being that the sketch uses digital outputs 4 - 5 - 6 - 7
while the Fritzing diagram uses digital outputs 8 - 9 - 10 - 11
*/
/*-----( Import needed libraries )-----*/
#include <AccelStepper.h>
#include <Keyboard.h> // Needed only if keyboard stroke is to be sent (REQUIRES Arduino UNO R4 Minima)
/*-----( Declare Constants and Pin Numbers )-----*/
/* NEVER PUT ; AFTER A #define statement!!!! */
// motor pins
#define motorPin1 4 // Blue - 28BYJ-48 pin 1
#define motorPin2 5 // Pink - 28BYJ-48 pin 2
#define motorPin3 6 // Yellow - 28BYJ-48 pin 3
#define motorPin4 7 // Orange - 28BYJ-48 pin 4 \
// Red - 28BYJ-48 pin 5 (VCC) \
// Blue - 28BYJ-48 pin GND
#define STEPS_PER_TURN 2048 // number of steps in 360°
#define STEPS_PER_FOUR 22 // number of steps in 4°
#define STEPS_PER_FIVE 28 // number of steps in 5°
#define STEPS_PER_TEN 57 // number of steps in 10°
#define STEPS_PER_TWENTY 114 // number of steps in 20°
#define STEPS_PER_FORTY 228 // number of steps in 40°
int motorSpeed = 500; // High speeds (800 and above) may cause erratic behavior in 28BYJ-48
int motorAccel = 400; // As above: better avoiding extreme accelerations
int myPos = 0; // will be used to define a starting point for 360° rotations
int LeftTurnUp = 0; // Couple of flags to determine rotation direction
int RightTurnDown = 0; // Couple of flags to determine rotation direction
int Continuous = 2; // used below to discriminate single rotation commands
// Continuous will be set to 1 or 0 only when a valid command character will be received
//int incomingByte = 0; // for incoming serial data
int STEPS_TO_DO = 0; // to allocate the number of steps needed to perform the required rotation
int RotationsRequired = 0; // How many rotations of the desired type are required?
int RotationsDone = 0; // How many rotations of the desired type were completed?
int RotationsRemaining = 0; // How many rotations remain to do?
/*-----( Objects for stepper control )-----*/
// Set up the stepper as 4 wire bipolar on pin 4,5,6,7
// NOTE: The sequence 1-3-2-4 is required for proper sequencing of 28BYJ48
AccelStepper stepper(4, motorPin1, motorPin3, motorPin2, motorPin4);
void setup() {
Serial.begin(9600);
stepper.setMinPulseWidth(20); // Advisable setting to avoid that pulses from Arduino are too quick to be decoded
stepper.setMaxSpeed(motorSpeed);
stepper.setSpeed(motorSpeed);
stepper.setAcceleration(motorAccel);
// the following two lines reset "step zero" to the current position
stepper.setCurrentPosition(stepper.currentPosition());
stepper.runToPosition();
//Keyboard.begin(); // required to initialize the communication with the keyboard
// ================================================================
// INITIALLY, the user is asked for A NUMBER OF REQUIRED ROTATIONS
// AND THE KIND OF ROTATIONS REQUIRED
// ================================================================
Serial.println("===============================");
Serial.println("How many rotations are desired?");
while (Serial.available() == 0) {
}
RotationsRequired = Serial.parseInt();
RotationsDone = 0; // For now, no rotations has been completed
RotationsRemaining = RotationsRequired; // For now, no rotations has been completed
Serial.print("You required ");
Serial.print(RotationsRequired);
Serial.println(" rotations.");
Serial.println(" ");
Serial.println("Which kind of rotation is required ?");
Serial.println("Available commands:");
Serial.println("====> 360° Rotation");
Serial.println("o = 360° clockwise rotation");
Serial.println("O = 360° counter-clockwise rotation");
Serial.println("====> Rotation by small increments");
Serial.println("k = rotate 4° clockwise");
Serial.println("K = rotate 4° counter-clockwise");
Serial.println("f = rotate 5° clockwise");
Serial.println("F = rotate 5° counter-clockwise");
Serial.println("t = rotate 10° clockwise");
Serial.println("T = rotate 10° counter-clockwise");
Serial.println("w = rotate 20° clockwise");
Serial.println("W = rotate 20° counter-clockwise");
Serial.println("q = rotate 40° clockwise");
Serial.println("Q = rotate 40° counter-clockwise");
while (Serial.available() == 0) {
}
String incomingByte = Serial.readString();
Serial.print("Received ");
Serial.println(incomingByte);
if (incomingByte == "o") {
Serial.println("received «o» - activating single clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_TURN;
}
if (incomingByte == "O") {
Serial.println("received «O» - activating single counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_TURN;
}
if (incomingByte == "k") {
Serial.println("received «k» - activating 4° clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_FOUR;
}
if (incomingByte == "K") {
Serial.println("received «K» - activating 4° counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_FOUR;
}
if (incomingByte == "f") {
Serial.println("received «f» - activating 5° clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_FIVE;
}
if (incomingByte == "F") {
Serial.println("received «F» - activating 5° counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_FIVE;
}
if (incomingByte == "t") {
Serial.println("received «t» - activating 10° clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_TEN;
}
if (incomingByte == "T") {
Serial.println("received «T» - activating 10° counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_TEN;
}
if (incomingByte == "w") {
Serial.println("received «w» - activating 20° clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_TWENTY;
}
if (incomingByte == "W") {
Serial.println("received «W» - activating 20° counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_TWENTY;
}
if (incomingByte == "q") {
Serial.println("received «q» - activating 40° clockwise rotation");
// The following couple of flags determines rotation direction
LeftTurnUp = 0;
RightTurnDown = 1;
STEPS_TO_DO = STEPS_PER_FORTY;
}
if (incomingByte == "Q") {
Serial.println("received «Q» - activating 40° counter-clockwise rotation");
// The following couple of flags determines rotation direction
RightTurnDown = 0;
LeftTurnUp = 1;
STEPS_TO_DO = STEPS_PER_FORTY;
}
// The two lines that follow allow to send commands in any sequence:
// before execution, a quick stop is performed
stepper.stop(); // Stop as fast as possible: sets new target
stepper.runToPosition(); // Now stopped after quickstop
stepper.setCurrentPosition(stepper.currentPosition()); // Set step 0 "here"
stepper.setSpeed(motorSpeed); // Previous commands have reset the speed
Serial.print("Starting rotation number 1 of ");
Serial.println(RotationsRequired);
// I store my current position as starting point of the rotation
myPos = stepper.currentPosition();
if (LeftTurnUp == 1) //left turn
{
stepper.moveTo(myPos + STEPS_TO_DO); // number of steps in 5, 10, 20 or 360°
}
if (RightTurnDown == 1) //right turn
{
stepper.moveTo(myPos - STEPS_TO_DO); // number of steps in 5, 10, 20 or 360°
}
}
void loop() {
stepper.run();
// ==================================================
// Let's check whether the stepper is still running
// ==================================================
if (stepper.distanceToGo() == 0) {
//Serial.println("stepper.distanceToGo() = 0");
// the rotation was completed
// Send F1 to the keyboard
//Keyboard.press(KEY_F1);
//delay(100);
//Keyboard.releaseAll();
// Increase the count of rotations done
RotationsDone = RotationsDone + 1;
// Check how many rotations remain to do
RotationsRemaining = RotationsRequired - RotationsDone;
if (RotationsRemaining > 0) {
Serial.print("Starting rotation number ");
Serial.print(RotationsDone + 1);
Serial.print(" of ");
Serial.println(RotationsRequired);
// reset current position
myPos = stepper.currentPosition();
// start a new rotation of the same kind as the last one
if (LeftTurnUp == 1) //left turn
{
stepper.moveTo(myPos + STEPS_TO_DO); // number of steps in 5, 10, 20 or 360°
}
if (RightTurnDown == 1) //right turn
{
stepper.moveTo(myPos - STEPS_TO_DO); // number of steps in 5, 10, 20 or 360°
}
}
}
}