Hi, all. I have been troubleshooting this program for a long time now. I've referenced some of the older forum post and I am still having trouble incorporating some of the approaches into my code.
My goal is to create a moving stage that can have the user select three modes: (Mode 1) forward motion; (Mode 2) forward motion, backward motion, pause, and then repeat; (Mode 3) No motion (stop). The stage uses a pulley-belt system and requires a conversion factor which I calculated. I want to user to be able to input the desired speed in steps, the translational distance in mm, and the mode. I have programmed the Arduino to achieve all of these things. However, mode (1) and (3) work properly, but mode (2) does not work in any capacity. Please, any help will be appreciated.
Is there any code that has a motor simply move forward, pause, move backwards, pause, and repeats this? I am willing to pay someone for help.
'steps' would be a measure of distance. Did you mean 'steps per minute'? You could also save them trouble by letting them set the speed in mm per minute and doing the math for them.
Hi, I tried the code for mode 2. However, it appears to have an issue with loop and the movements are not repeated. Do you think it would be best to put the different modes into separate files? Or, is there a way for me to still have the three modes in the same file, and have looping with forward motion, pause, back motion, pause repeatedly?
#include <AccelStepper.h>
const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,
const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm
float ArdDist; //converted distance in steps
const int maxspd = 300; //Set Maximum Speed; steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps);
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd; //
int incomingByte = 0; // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//
void MotorSpdfinder() { //motor speed for moving stage
if (!askedForData1) {
Serial.println("Please enter the desired stage speed in steps: ");
askedForData1 = true;
}
if (askedForData1 && !gotData1) {
if (Serial.available()) {
// delay(10);
spd = Serial.parseFloat(SKIP_ALL, ','); //
gotData1 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Distfinder() { //translational distance for the moving stage
if (!askedForData2) {
Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
askedForData2 = true;
}
if (askedForData2 && !gotData2) {
if (Serial.available()) {
// delay(10);
Dist = Serial.parseFloat(SKIP_ALL, ',');
gotData2 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Mfinder() { //select the mode for the moving stage
if (!askedForData3) {
Serial.println("Pick your Mode (1,2,3): ");
askedForData3 = true;
}
if (askedForData3 && !gotData3) {
if (Serial.available()) {
// delay(10);
M = Serial.parseFloat(SKIP_ALL, ',');
Serial.println(M);
gotData3 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void ArdFinder() { //Arduino distance finder
if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
Serial.print("This is your distance in steps: ");
Serial.println(ArdDist);
Serial.println("");
// delay(1000);
askedForData1 = false;
gotData1 = false;
askedForData2 = false;
gotData2 = false;
askedForData3 = false;
gotData3 = false;
}
}
void setup()
{
Serial.begin(9600);
pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
Xaxis.setMaxSpeed(maxspd); //Max speed
MotorSpdfinder(); //
Distfinder(); //
Mfinder(); //
ArdFinder(); //
Xaxis.setSpeed(-spd);
//Xaxis.setCurrentPosition(0);
}
void loop()
{
MotorSpdfinder();
Distfinder();
Mfinder();
ArdFinder();
//Xaxis.setSpeed(-spd);
if ( abs( M - 1) < 0.01 ) { //distanceToGo()
Xaxis.setSpeed(spd);
Xaxis.run();
}
if ( abs(M - 2) < 0.01) {
if (Xaxis.distanceToGo() == 0)
Xaxis.moveTo(-Xaxis.currentPosition());
Xaxis.run();
}
if ( abs(M - 3) < 0.01) {
//Serial.print("Mode 3: ");
Xaxis.setSpeed(0);
Xaxis.run();
}
}
Hi, the user can set the distance in mm which will then convert to steps. However, I am also looking into letting them set the speed in mm/s or mm/minute. I meant steps per second before, sorry for the confusion. Is there a way for me to be able to convert mm/min or mm/s into steps?
#include <AccelStepper.h>
const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,
const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm
float ArdDist; //converted distance in steps
const int maxspd = 300; //Set Maximum Speed; steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps);
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd;
int incomingByte = 0; // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//
void MotorSpdfinder() { //motor speed for moving stage
if (!askedForData1) {
Serial.println("Please enter the desired stage speed in steps: ");
askedForData1 = true;
}
if (askedForData1 && !gotData1) {
if (Serial.available()) {
// delay(10);
spd = Serial.parseFloat(SKIP_ALL, ','); //
gotData1 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Distfinder() { //translational distance for the moving stage
if (!askedForData2) {
Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
askedForData2 = true;
}
if (askedForData2 && !gotData2) {
if (Serial.available()) {
// delay(10);
Dist = Serial.parseFloat(SKIP_ALL, ',');
gotData2 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Mfinder() { //select the mode for the moving stage
if (!askedForData3) {
Serial.println("Pick your Mode (1,2,3): ");
askedForData3 = true;
}
if (askedForData3 && !gotData3) {
if (Serial.available()) {
// delay(10);
M = Serial.parseFloat(SKIP_ALL, ',');
Serial.println(M);
gotData3 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void ArdFinder() { //Arduino distance finder
if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
Serial.print("This is your distance in steps: ");
Serial.println(ArdDist);
Serial.println("");
// delay(1000);
askedForData1 = false;
gotData1 = false;
askedForData2 = false;
gotData2 = false;
askedForData3 = false;
gotData3 = false;
}
}
void setup()
{
Serial.begin(9600);
pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
Xaxis.setMaxSpeed(maxspd); //Max speed
MotorSpdfinder(); //
Distfinder(); //
Mfinder(); //
ArdFinder(); //
Xaxis.setSpeed(-spd);
//Xaxis.setCurrentPosition(0);
}
void loop()
{
MotorSpdfinder();
Distfinder();
Mfinder();
ArdFinder();
//Xaxis.setSpeed(-spd);
if ( abs( M - 1) < 0.01 ) { //distanceToGo()
Xaxis.setSpeed(spd);
Xaxis.run();
}
if ( abs(M - 2) < 0.01) {
if (Xaxis.distanceToGo() == 0)
Xaxis.moveTo(-Xaxis.currentPosition());
Xaxis.run();
}
if ( abs(M - 3) < 0.01) {
//Serial.print("Mode 3: ");
Xaxis.setSpeed(0);
Xaxis.run();
}
}
I am wondering if there is a way that I could fix 'Mode 2 'so that there is a forward and backwards motion with pausing? I tried implementing a while loop based on the 'quickstop' example provided in the accel stepper library examples. I have also tried using the 'bounce' example code.
Sorry, I am new here and thank you for the helpful link.
Bounce:
I tested if the motors would move back and forth within Mode 2 of the double if statements (based on the bounce example)
The motors did not move at all. I believe it is not registering with Arduino inside the double if-statements.
The code is posted in the last comment.
Quickstop:
The motors did move back and forth repeated. However, the speed did not change at all. I varied the speed and acceleration to test this.
I tested if the motors would move back and forth repeatedly.
Question:
Can I implement a for-loop or some other code within the if-statements to create these movements?
Is it better to separate the modes into separate files so there is no issues with the looping?
-I do not understand the reason why the bounce example did not work. Is it because it uses two if-statements repeatedly?
Example Code:
int counter = 0;
void loop() {
// go forwards 100 steps at speed 50
stepper.setSpeed(50);
while (counter++ < 100) {
stepper.runSpeed();
}
// stop
stepper.setSpeed(0);
stepper.runSpeed();
// go backwards 100 steps at speed 50
stepper.setSpeed(-50);
while (counter-- > 0) {
stepper.runSpeed();
}
// stop
stepper.setSpeed(0);
stepper.runSpeed();
}
type or paste code here
Hi,
you are asking specific questions. this is very good. From your questions I can conclude that your knowledge about programming is improvable.
You can combine any commands in almost any order you like. For-loops inside if conditions or if-conditions inside for-loops, or while-loops, or... or... or....
the commands can be in one file or distributed in multiple files.
In most cases it makes sense to have all the code in one file.
what you have posted is not a complete sketch. And beause it is uncomplete it is hard to say what the reason is why the motors didn't moeved
best regards
Stefan
no. donwload-links are suspected to be malicious.
You should post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps
press Ctrl-T for autoformatting your code
do a rightclick with the mouse and choose "copy for forum"
#include <AccelStepper.h>
const byte enablePin = 8; //enable pin on the DRV8825
AccelStepper Xaxis(1, 2, 5); // pin 2 = stepper pin, pin 5 = direction pin,
const float pi = 3.1415926535897932384626433832795;
const float r = 2.5 ; //Diameter of timing pulley. Here it is 5 mm for the GT2 Timing Belt Pulley (20 teeth) with 2 mm Pitch 6 mm wide belt
const float convF2 = 12.732 ; //Units are mm/steps which is the conversion factor; previously: (2 * pi * r) * (1/200); now: (200)/(2 * pi * r) units: steps/mm
float ArdDist; //converted distance in steps
const int maxspd = 300; //Set Maximum Speed; steps per second
//
bool askedForData1 = false;
bool gotData1 = false;
float Dist; //User-input distance in
const float maxDist = 222.816920329; //Maximum distance for stage in steps based on current configuration and conversion factor (max: ~35mm = 445.63 steps);
//
bool askedForData2 = false;
bool gotData2 = false;
//
float spd; //calculated syringe pump speed in steps/sec since (mm/s) *(steps/mm)
int incomingByte = 0; // for incoming serial data
//
bool askedForData3 = false;
bool gotData3 = false;
float M;
//
void MotorSpdfinder() { //motor speed for moving stage
if (!askedForData1) {
Serial.println("Please enter the desired stage speed in steps: ");
askedForData1 = true;
}
if (askedForData1 && !gotData1) {
if (Serial.available()) {
// delay(10);
spd = Serial.parseFloat(SKIP_ALL, ','); //
gotData1 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Distfinder() { //translational distance for the moving stage
if (!askedForData2) {
Serial.println("Please enter the desired distance in mm (less than 35 mm): ");
askedForData2 = true;
}
if (askedForData2 && !gotData2) {
if (Serial.available()) {
// delay(10);
Dist = Serial.parseFloat(SKIP_ALL, ',');
gotData2 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void Mfinder() { //select the mode for the moving stage
if (!askedForData3) {
Serial.println("Pick your Mode (1,2,3): ");
askedForData3 = true;
}
if (askedForData3 && !gotData3) {
if (Serial.available()) {
// delay(10);
M = Serial.parseFloat(SKIP_ALL, ',');
Serial.println(M);
gotData3 = true;
while (Serial.available()) {
Serial.read();
}
}
}
}
void ArdFinder() { //Arduino distance finder
if (askedForData1 && gotData1 && askedForData2 && gotData2 && askedForData3 && gotData3) {
ArdDist = int(Dist * convF2); //Dist = mm, pow(convF2) = steps/mm, ArdDist = steps
Serial.print("This is your distance in steps: ");
Serial.println(ArdDist);
Serial.println("");
// delay(1000);
askedForData1 = false;
gotData1 = false;
askedForData2 = false;
gotData2 = false;
askedForData3 = false;
gotData3 = false;
}
}
void setup()
{
Serial.begin(9600);
pinMode(enablePin, OUTPUT); //Must enable pins on DRV8825
digitalWrite(enablePin, LOW); //Must enable pins on DRV8825
Xaxis.setMaxSpeed(maxspd); //Max speed
MotorSpdfinder(); //
Distfinder(); //
Mfinder(); //
ArdFinder(); //
Xaxis.setSpeed(-spd);
//Xaxis.setCurrentPosition(0);
}
void loop()
{
MotorSpdfinder();
Distfinder();
Mfinder();
ArdFinder();
//Xaxis.setSpeed(-spd);
if ( abs( M - 1) < 0.01 ) { //distanceToGo()
Xaxis.setSpeed(spd);
Xaxis.run();
}
if ( abs(M - 2) < 0.01) {
if (Xaxis.distanceToGo() == 0)
Xaxis.moveTo(-Xaxis.currentPosition());
Xaxis.run();
}
if ( abs(M - 3) < 0.01) {
//Serial.print("Mode 3: ");
Xaxis.setSpeed(0);
Xaxis.run();
}
}
//// Xaxis.moveTo(ArdDist);
// Xaxis.run();
// if (Xaxis.distanceToGo() == 0){
// Xaxis.moveTo(-Xaxis.currentPosition());
// Xaxis.run();
// pause & play button (now) when running with the code; userinput time (later)
// manual button to send in manual direction and to stop (forward and backward button sliding control), set the speed manually as finite value
// emergency stop button (exception - c - interrupt based keyboard)
//Extra Notes:
//Steps per second is the setSpeed(spd) (in units steps per second) -> need to back calculate ; convert rpm to ul/min
//Speed of Stepper: Revolutions per second = steps per second * microstepping / steps per revolution
//check on this -> Speed of Stepper: Revolutions per second = setSpeed(spd) / 200 ->
// const int spd = 100; //Set Current Speed; steps per second; (+) value
Open serial port/board on Arduino interface (Ctrl+M)
Prompts user to enter speed (steps/s), distance (mm), and mode (1,2,or 3). More specifically, the user enters speed and then presses 'enter key'. The user enters distance and presses 'enter key'. The user enters mode then presses 'enter key'.
User enters random speed, distance, and mode. The Arduino prints out the user's inputs and the converted distance in steps.
For this example, the user has entered mode 2.
Once the user enters all three, the mode is selected in the void loop and the program executes.
Mode 2 results in the motor creating a sound but no movement is created. (in contrast, mode 1 creates a forward movement)
This may have been the problem. Should I set speed inside the first if-statement or inside the second if-statement? Also is there a reason why delays do not work inside the void loop of my program?