Hi there!
I'm trying to build my own G-code interpreter in which the commands have to come from Arduino serial Monitor.
The problem is if I send a command while the other is being executed the current execution stops and execute the command I just sent.
I want it to queue the commands that the commands sent must wait until current execution finishes then execute the next command.
I want to build A CNC punching machine using Stepper motors-lead screw drive and a hydraulic cylinder whose stroke is controlled by opening and closing a valve. Arduino Mega is the controller.
The code I've written so far is shown below which I used accelstepper library and some arduino builtin functions. However, I've not yet written valve control chunk of code, I think it won't be difficult because it is just ON or OFF control(HIGH or LOW)
Could anyone help me to implement command queuing that every comands wait for the other to be executed first?
The code I've written so far is shown below.
//Transforming the motor's rotary motion into linear motion by using a threaded rod:
//Threaded rod's pitch = 2 mm. This means that one revolution will move the nut 2 mm.
//Default stepping = 400 step/revolution.
// 400 step = 1 revolution = 8 mm linear motion. (4 start 2 mm pitch screw)
// 1 cm = 10 mm =>> 10/8 * 400 = 4000/8 = 500 steps are needed to move the nut by 1 cm.
#define HOMING_SPEED 600
#define MM_PER_REV 8
#define INCH_PER_REV 0.314960629
#define STEPS_PER_REV 200
//character for commands
/*
'C' : Prints all the commands and their functions.
'P' : Rotates the motor in positive (CW) direction, relative.
'N' : Rotates the motor in negative (CCW) direction, relative.
'R' : Rotates the motor to an absolute positive position (+).
'r' : Rotates the motor to an absolute negative position (-).
'S' : Stops the motor immediately.
'A' : Sets an acceleration value.
'L' : Prints the current position/location of the motor.
Preformatted text
'H' : Goes back to 0 position from the current position (homing).
'U' : Updates the position current position and makes it as the new 0 position.
*/
#include <AccelStepper.h>
//User-defined values
long x_steps = 0; //Number of steps
long receivedSpeed = 0; //Steps / second
long receivedAcceleration = 0; //Steps / second^2
char receivedCommand;
float Speed;
float unit_per_sec;
long y_steps;
bool homing;
bool isnegative;
bool unit_inch;
bool unit_mm;
//-------------------------------------------------------------------------------
int directionMultiplier = 1; // = 1: positive direction, = -1: negative direction
bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag
bool isabsolute, isrelative, print_allowed;
//AcceleSteper yourstepper(interface_type, step,direction)
AccelStepper x_stepper(1, 8, 9);// direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper y_stepper(1, 10, 11);
void setup()
{
Serial.begin(19200); //define baud rate
//Transforming the motor's rotary motion into linear motion by using a threaded rod:
//Threaded rod's pitch = 2 mm. This means that one revolution will move the nut 2 mm.
//Default stepping = 400 step/revolution.
// 400 step = 1 revolution = 8 mm linear motion. (4 start 2 mm pitch screw)
// 1 cm = 10 mm =>> 10/8 * 400 = 4000/8 = 500 steps are needed to move the nut by 1 cm.
#define HOMING_SPEED 600
#define MM_PER_REV 8
#define INCH_PER_REV 0.314960629
#define STEPS_PER_REV 200
//character for commands
/*
'C' : Prints all the commands and their functions.
'P' : Rotates the motor in positive (CW) direction, relative.
'N' : Rotates the motor in negative (CCW) direction, relative.
'R' : Rotates the motor to an absolute positive position (+).
'r' : Rotates the motor to an absolute negative position (-).
'S' : Stops the motor immediately.
'A' : Sets an acceleration value.
'L' : Prints the current position/location of the motor.
'H' : Goes back to 0 position from the current position (homing).
'U' : Updates the position current position and makes it as the new 0 position.
*/
#include <AccelStepper.h>
//User-defined values
long x_steps = 0; //Number of steps
long receivedSpeed = 0; //Steps / second
long receivedAcceleration = 0; //Steps / second^2
char receivedCommand;
float Speed;
float unit_per_sec;
long y_steps;
bool homing;
bool isnegative;
bool unit_inch;
bool unit_mm;
//-------------------------------------------------------------------------------
int directionMultiplier = 1; // = 1: positive direction, = -1: negative direction
bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag
bool isabsolute, isrelative, print_allowed;
//AcceleSteper yourstepper(interface_type, step,direction)
AccelStepper x_stepper(1, 8, 9);// direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper y_stepper(1, 10, 11);
void setup()
{
Serial.begin(19200); //define baud rate
Serial.println("Demonstration of AccelStepper Library"); //print a messages
Serial.println("Send 'C' for printing the commands.");
//setting up some default values for maximum speed and maximum acceleration
Serial.println("Default speed: 400 steps/s, default acceleration: 800 steps/s^2.");
x_stepper.setMaxSpeed(600); //SPEED = Steps / second
y_stepper.setMaxSpeed(600);
[quote="mbise1997, post:1, topic:886405, full:true"]
Hi there!
I'm trying to build my own G-code interpreter in which the commands have to come from Arduino serial Monitor.
The problem is if I send a command while the other is being executed the current execution stops and execute the command I just sent.
I want it to queue the commands that the commands sent must wait until current execution finishes then execute the next command.
I want to build A CNC punching machine using Stepper motors-lead screw drive and a hydraulic cylinder whose stroke is controlled by opening and closing a valve. Arduino Mega is the controller.
The code I've written so far is shown below which I used accelstepper library and some arduino builtin functions. However, I've not yet written valve control chunk of code, I think it won't be difficult because it is just ON or OFF control(HIGH or LOW)
Could anyone help me to implement command queuing that every comands wait for the other to be executed first?
The code I've written so far is shown below.
//Transforming the motor's rotary motion into linear motion by using a threaded rod:
//Threaded rod's pitch = 2 mm. This means that one revolution will move the nut 2 mm.
//Default stepping = 400 step/revolution.
// 400 step = 1 revolution = 8 mm linear motion. (4 start 2 mm pitch screw)
// 1 cm = 10 mm =>> 10/8 * 400 = 4000/8 = 500 steps are needed to move the nut by 1 cm.
#define HOMING_SPEED 600
#define MM_PER_REV 8
#define INCH_PER_REV 0.314960629
#define STEPS_PER_REV 200
//character for commands
/*
'C' : Prints all the commands and their functions.
'P' : Rotates the motor in positive (CW) direction, relative.
'N' : Rotates the motor in negative (CCW) direction, relative.
'R' : Rotates the motor to an absolute positive position (+).
'r' : Rotates the motor to an absolute negative position (-).
'S' : Stops the motor immediately.
'A' : Sets an acceleration value.
'L' : Prints the current position/location of the motor.
'H' : Goes back to 0 position from the current position (homing).
'U' : Updates the position current position and makes it as the new 0 position.
*/
#include <AccelStepper.h>
//User-defined values
long x_steps = 0; //Number of steps
long receivedSpeed = 0; //Steps / second
long receivedAcceleration = 0; //Steps / second^2
char receivedCommand;
float Speed;
float unit_per_sec;
long y_steps;
bool homing;
bool isnegative;
bool unit_inch;
bool unit_mm;
//-------------------------------------------------------------------------------
int directionMultiplier = 1; // = 1: positive direction, = -1: negative direction
bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag
bool isabsolute, isrelative, print_allowed;
//AcceleSteper yourstepper(interface_type, step,direction)
AccelStepper x_stepper(1, 8, 9);// direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper y_stepper(1, 10, 11);
void setup()
{
Serial.begin(19200); //define baud rate
Serial.println("Demonstration of AccelStepper Library"); //print a messages
Serial.println("Send 'C' for printing the commands.");
//setting up some default values for maximum speed and maximum acceleration
Serial.println("Default speed: 400 steps/s, default acceleration: 800 steps/s^2.");
x_stepper.setMaxSpeed(600); //SPEED = Steps / second
y_stepper.setMaxSpeed(600);
x_stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
y_stepper.setAcceleration(1000);
// stepper.disableOutputs(); //disable outputs
}
void loop()
{
//Constantly looping through these 2 functions.
//We only use non-blocking commands, so something else (should also be non-blocking) can be done during the movement of the motor
checkSerial(); //check serial port for new commands
RunTheMotor(); //function to handle the motor
}
void RunTheMotor() //function for the motor
{
if (runallowed == true)
{
//stepper.enableOutputs(); //enable pins
x_stepper.run();
y_stepper.run();
//step the motor (this will step the motor by 1 step at each loop)
}
else //program enters this part if the runallowed is FALSE, we do not do anything
{
// stepper.disableOutputs(); //disable outputs
return;
}
}
void checkSerial() //function for receiving the commands
{
if (Serial.available() > 0) //if something comes from the computer
{
receivedCommand = Serial.read(); // pass the value to the receivedCommad variable
newData = true; //indicate that there is a new data by setting this bool to true
if (newData == true) //we only enter this long switch-case statement if there is a new command from the computer
{
switch (receivedCommand) //we check what is the command
{
case '-' :
isnegative = true;
if (isnegative)directionMultiplier = -1;
else directionMultiplier = 1;
break;
case 'X': //P uses the move() function of the AccelStepper library, which means that it moves relatively to the current position.
float x_received_distance = Serial.parseFloat(); //value for distance to move
x_steps = convert_distance_to_motor_steps(x_received_distance); //value for distance to move
//receivedSpeed = Serial.parseFloat(); //value for the speed
directionMultiplier = 1; //We define the direction
if (isrelative)
x_RotateRelative(); //Run the function
else if (isabsolute)
x_RotateAbsolute();
Serial.println("Positive direction."); //print the action
break;
case 'Y': //P uses the move() function of the AccelStepper library, which means that it moves relatively to the current position.
float y_received_distance = Serial.parseFloat(); //value for distance to move
y_steps = convert_distance_to_motor_steps(y_received_distance); //value for distance to move
//y_receivedSpeed = Serial.parseFloat(); //value for the speed
directionMultiplier = 1; //We define the direction
Serial.println("Positive direction."); //print the action
y_RotateRelative(); //Run the function
//example: P2000 400 - 2000 steps (5 revolution with 400 step/rev microstepping) and 400 steps/s speed
//In theory, this movement should take 5 seconds
break;
case 'S': // axes speed
unit_per_sec = Serial.parseFloat();
Speed = convert_speed_to_motor_steps_per_sec(unit_per_sec);
break;
case 's': // Stops the motor
stopMotors();
runallowed = false; //disable running
break;
case 'G':
int int_value = Serial.parseInt();
switch (int_value) {
case 30:
homing = true;
Serial.println("Homing"); //Print the message
GoHome();// Run the function
break;
case 20:
unit_inch = true;
break;
case 21:
unit_mm = true;
break;
case 90:
isabsolute = true; break;
case 91:
isrelative = true; break;
} break;
case 'C':
print_allowed = true;
PrintCommands(); //Print the commands for controlling the motor
break;
default:
break;
}
}
//after we went through the above tasks, newData is set to false again, so we are ready to receive new commands again.
newData = false;
}
}
void GoHome()
{
if (x_stepper.currentPosition() == 0)
{
if (y_stepper.currentPosition() == 0)
Serial.println("We are at the home position.");
// x_stepper.disableOutputs(); //disable power
}
else
{
home_steppers();
}
}
void x_RotateRelative()
{
//We move X steps from the current position of the stepper motor in a given direction.
//The direction is determined by the multiplier (+1 or -1)
runallowed = true; //allow running - this allows entering the RunTheMotor() function.
x_stepper.setMaxSpeed(Speed); //set speed
x_stepper.move(directionMultiplier * x_steps); //set relative distance and direction
}
void x_RotateAbsolute()
{
//We move to an absolute position.
//The AccelStepper library keeps track of the position.
//The direction is determined by the multiplier (+1 or -1)
//Why do we need negative numbers? - If you drive a threaded rod and the zero position is in the middle of the rod...
runallowed = true; //allow running - this allows entering the RunTheMotor() function.
x_stepper.setMaxSpeed(Speed); //set speed
x_stepper.moveTo(directionMultiplier * x_steps); //set relative distance
}
void y_RotateAbsolute()
{
//We move to an absolute position.
//The AccelStepper library keeps track of the position.
//The direction is determined by the multiplier (+1 or -1)
//Why do we need negative numbers? - If you drive a threaded rod and the zero position is in the middle of the rod...
runallowed = true; //allow running - this allows entering the RunTheMotor() function.
y_stepper.setMaxSpeed(Speed); //set speed
y_stepper.moveTo(directionMultiplier * y_steps); //set relative distance
}
void y_RotateRelative()
{
//We move X steps from the current position of the stepper motor in a given direction.
//The direction is determined by the multiplier (+1 or -1)
runallowed = true; //allow running - this allows entering the RunTheMotor() function.
y_stepper.setMaxSpeed(Speed); //set speed
y_stepper.move(directionMultiplier * y_steps); //set relative distance and direction
}
void PrintCommands()
{
if (print_allowed) {
//Printing the commands
Serial.println(" 'C' : Prints all the commands and their functions.");
Serial.println(" 'P' : Rotates the motor in positive (CW) direction, relative.");
Serial.println(" 'N' : Rotates the motor in negative (CCW) direction, relative.");
Serial.println(" 'R' : Rotates the motor to an absolute positive position (+).");
Serial.println(" 'r' : Rotates the motor to an absolute negative position (-).");
Serial.println(" 'S' : Stops the motor immediately.");
Serial.println(" 'A' : Sets an acceleration value.");
Serial.println(" 'L' : Prints the current position/location of the motor.");
Serial.println(" 'H' : Goes back to 0 position from the current position (homing).");
Serial.println(" 'U' : Updates the position current position and makes it as the new 0 position. ");
}
}
void home_steppers() {
if (homing == true) {
x_stepper.setMaxSpeed(HOMING_SPEED); //set speed manually to 400. In this project 400 is 400 step/sec = 1 rev/sec.
y_stepper.setMaxSpeed(HOMING_SPEED);
x_stepper.moveTo(0);
y_stepper.moveTo(0); //set abolute distance to move
}
}
void stopMotors() {
x_stepper.stop(); //stop motor
y_stepper.stop(); //stop motor
//X_stepper.disableOutputs(); //disable power
Serial.println("Stopped."); //print action
}
long convert_distance_to_motor_steps(float distance) {
long steps;
if (unit_inch)
steps = (distance * STEPS_PER_REV) / INCH_PER_REV;
else if (unit_mm)
steps = (distance * STEPS_PER_REV) / MM_PER_REV;
return steps;
}
long convert_speed_to_motor_steps_per_sec(float _speed) {
long steps_per_sec;
if (unit_inch)
steps_per_sec = (_speed * STEPS_PER_REV) / INCH_PER_REV;
else if (unit_mm)
steps_per_sec = (_speed * STEPS_PER_REV) / MM_PER_REV;
return steps_per_sec;
}`
`* Preformatted text`
`
[/quote]
type or paste code here