Stepper push button and pot control

Im in need of some help, ive been working on this for months, I have hours upon hours invested into this and i always end up with the same result.

This is an arduino controlled nema 23 stepper motor using a DM542T driver.

The goal here is to power an X axis on a milling machine, utilizing 4 push buttons and a potentiometer, along with lcd for display.

The 4 momentary push buttons work as follows, button 1- run stepper left, button 2- run stepper right, button 3- rapid move the stepper in direction when pushed while pushing button 1 or 2. and button 4-stop the stepper.

The potentiometer controls the speed of the left and right running.

I want the button 3 rapid Move button to bypass the potentiometer and just run the stepper at whatever speed its set to in the code.

An example of how i want this to run my machine… when running stepper in any direction at any speed set by the potentiometer i want to push the rapid button and either direction button and the speed increases to the set speed in the code, when released it will continue at the speed selected by the pot.

What is happening- when i push the rapid button the speed increases but its not a continuous speed, the motor runs a revolution, has a intermittent stop, runs a revolution, has intermittent stop,and continues this until released.

One way to minimize the momentary pauses in between revolutions is to increase the steps, but then it blocks all other buttons until it runs those steps.

If i change the speed value lower, the motor vibrates and the speed is slower then the pot speed. If i change the speed value high it just stalls the motor.

Ive also tried the accelstepper library, with worst luck… i cant get the pot to control the speed without blocking all other buttons.

Hopefully someone has some ideas on how to bypass my pot speed to increase the stepper speed momentary by a push button. 


 /*
Milling Stepper Motor Speed Controller X Axis

*/

#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// set this to the microstep value  to the steps desired.

const int stepsPerRevolution = 9800;
const int steps = 4800; // pot steps 
const int stepsUp = 2400;
const int stepsDown = 2400; // Change for Step Resolution Higher Number -Less Rapid Off Response

const int speedUp = 100; // Change for Rapid Up Speed 
const int speedDown = 100; //Change for Rapid Down Speed 


LiquidCrystal_I2C lcd1(0x21, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display

// Define our three input button pins
const int UP_PIN = 7;
const int STOP_PIN = 12;
const int DOWN_PIN = 13;
const int FAST = 5;
const int rLight = 11;
const int lLight = 22;
const int sLight = 24;

Stepper myStepper1(stepsPerRevolution, 8, 9);

int stepCount = 0;

unsigned long previousMicros= 0;

const long interval = 1000;

void setup() {
// Set up the three button inputs, with pullups
pinMode(UP_PIN, INPUT_PULLUP);
pinMode(STOP_PIN, INPUT_PULLUP);
pinMode(DOWN_PIN, INPUT_PULLUP);
pinMode(FAST, INPUT_PULLUP);  

pinMode (rLight, OUTPUT);
pinMode (lLight, OUTPUT);
pinMode (sLight, OUTPUT);

lcd1.init();
lcd1.backlight();
lcd1.setCursor(2,0);
lcd1.print (" KING 6 FAB");
lcd1.setCursor(0,1);
lcd1.print (" MILLING MACHINE");
delay(5000);
lcd1.clear();
lcd1.setCursor(0, 1);
lcd1.print("Speed:");
lcd1.setCursor(13,1);
lcd1.print("IPM");
Serial.begin(9600);
lcd1.setCursor(0, 0);
lcd1.print("Z Axis");
lcd1.setCursor(7, 0);
lcd1.print("BEGIN  ");

}

void loop() {

static int sign = 0;

if (digitalRead(UP_PIN) == 0){
sign = 1;digitalWrite (rLight, LOW);
digitalWrite (lLight, HIGH);digitalWrite (sLight, HIGH);
lcd1.setCursor(7, 0);
lcd1.print(" UP      ");
}

else if (digitalRead(DOWN_PIN) == 0) {
sign = -1;  digitalWrite (lLight, LOW);
digitalWrite (rLight, HIGH);digitalWrite (sLight, HIGH);
lcd1.setCursor(7, 0);
lcd1.print("DOWN      ");
}

else if (digitalRead(STOP_PIN) == 0) {
sign = 0;digitalWrite (lLight, HIGH);
digitalWrite (rLight, HIGH);
digitalWrite (sLight, LOW);
lcd1.setCursor(7, 0);
lcd1.print("HOLD       ");
}

// read the sensor value:
int sensorReading = analogRead(A1);
// map it to a range from 0 to 120:
int motorSpeed = map(sensorReading, 0, 1023, 1, 120);
// set the motor speed:
if (motorSpeed > 0) {
myStepper1.setSpeed(motorSpeed);

myStepper1.step(sign * steps / 100);
{
lcd1.setCursor(7, 1);
lcd1.print(float(float(motorSpeed) / float(4)), 2);}// float divide (15)) x 2 ) for IPM
unsigned long currentMicros = micros();

if (currentMicros - previousMicros >= interval) {

previousMicros = currentMicros;
}
{
  if (digitalRead(FAST)==1&&digitalRead(UP_PIN)==0&&digitalRead(DOWN_PIN)==1)       //rapid traverse up
  {  lcd1.setCursor(7, 1);
lcd1.print(float(float(speedUp) / float(4)), 1);// float divide (8)) x 1 ) for IPM

 myStepper1.setSpeed(speedUp);//Rapid Speed
   myStepper1.step(stepsUp);//Rapid Motor Steps

if (currentMicros - previousMicros >= interval) {

previousMicros = currentMicros;}

    if (digitalRead(FAST)==1&&digitalRead(UP_PIN)==1&&digitalRead(DOWN_PIN)==0) //rapid traverse down
  {  lcd1.setCursor(7, 1);
lcd1.print(float(float(speedDown) / float(4)), 1);// float divide (8)) x 1 ) for IPM

    myStepper1.setSpeed(speedDown); //Rapid Speed
    myStepper1.step(-stepsDown); //Rapid Motor Steps

if (currentMicros - previousMicros >= interval) {

previousMicros = currentMicros;
  }

  }
}
}
}

You have said what you want to happen - which seems straightforward and you have posted a program but you have not told us what actually happens when you run and what you want it to do that is different. In other words I don't know what part you are having trouble with.

Separately, your code is pretty much unreadable because it is not indented consistently so we can see the different blocks. Please use the AutoFormat tool to lay it out consistently and then post the revised version in your next Reply.

I suspect this is a problem that will benefit from a "state machine" approach. "State machine" is just a fancy name for using one or more variables to keep track of the state of a system. In your case the states might be Stop, run Left, run Right and Fast or Normal which could be represented by two char variables having values 'S', 'L' or 'R' and 'F' or 'N'. Pressing buttons would set the state and the motion of the motor would be based on the current state setting. There would be no direct linkage between pressing a button and moving the motor. This has the advantage that the button-pressing and the motor movement can be tested separately.

The AccelStepper library is almost certainly essential as the standard Stepper library blocks the Arduino until a move is complete.

...R

I guess i didn’t layout my description of what’s going on properly because its in what i originally wrote. I also posted with my phone so it might have unformmated the code.

What its doing:
the left/right/stop push buttons and pot control all work as intended, the motor makes continuous revolutions at the speed selected by the pot.

However, the rapid button what is happening- when i push the rapid button the speed increases to whats its set to, but its not a continuous speed, the motor runs a revolution, has a intermittent stop, runs a revolution, has intermittent stop,and continues until the rapid botton is released. Its the intermittent stop that’s the issue.

In the posted video below, you can see this, especially when the pot is turned down (witch i would like the pot not to effect the rapid speed like its doing)

What i want to happen=
when the rapid button is pressed, for it to run continuous revolutions at a set increased speed, and when the button is released go back to the pot speed.

Attached is a video of the motor in action. Mind you this is on my Z axis, same code but the buttons are labeled up and down.

What i had thought of but haven’t tried yet because i dont know how to implement it is a switch case, to switch from pot speed to rapid speed.

Accelstepper would be ideal for this project for the acceleration and non blocking, but i cannot get it to work with the Potentiometer control.

     /*
  Milling Stepper Motor Speed Controller Z Axis

*/

#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// set this to the microstep value on the stepper driver
const int stepsPerRevolution = 4800;
const int steps = 4800;
const int steps2 = 14000;
const int steps3 = 10800;
const int stepsD2 = 1.8; // Change for Step Resolution Higher Number -Less Rapid Off Response
const int speedD2 = 125; //
const int speedD3 = 160; //Change for Speed Resolution Lower Number Finer Speed but Slower, Higher Numnber Coarse Speed But Faster
LiquidCrystal_I2C lcd1(0x21, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display





// Define our three input button pins
const int UP_PIN = 7;
const int STOP_PIN = 12;
const int DOWN_PIN = 13;
const int FAST = 5;
const int rLight = 11;
const int lLight = 22;
const int sLight = 24;


Stepper myStepper1(stepsPerRevolution, 8, 9);


int stepCount = 0;

unsigned long previousMicros = 0;

const long interval = 1000;

void setup() {
  // Set up the three button inputs, with pullups
  pinMode(UP_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(DOWN_PIN, INPUT_PULLUP);
  pinMode(FAST, INPUT_PULLUP);

  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);

  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");

}

void loop() {
  unsigned long currentMicros = micros();
  static int sign = 0;

  if (digitalRead(UP_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);
    lcd1.setCursor(7, 0);
    lcd1.print(" UP      ");
  }



  else if (digitalRead(DOWN_PIN) == 0) {
    sign = -1;  digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);
    lcd1.setCursor(7, 0);
    lcd1.print("DOWN      ");
  }


  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);
    lcd1.setCursor(7, 0);
    lcd1.print("HOLD       ");
  }

  // read the sensor value:
  int sensorReading = analogRead(A1);
  // map it to a range from 0 to 120:
  int motorSpeed = map(sensorReading, 0, 1023, 1, 120);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper1.setSpeed(motorSpeed);

    myStepper1.step(sign * steps / 100);

    lcd1.setCursor(7, 1);
    lcd1.print(float(float(motorSpeed) / float(27)), 3);// float divide (15)) x 2 ) for IPM

    if (currentMicros - previousMicros >= interval) {

      previousMicros = currentMicros;
    }
  }




  if (digitalRead(FAST) == 1 && digitalRead(UP_PIN) == 0 && digitalRead(DOWN_PIN) == 1) //rapid traverse up
  { lcd1.setCursor(7, 1);
    lcd1.print(float(float(speedD2) / float(16)), 2);// float divide (8)) x 1 ) for IPM

    myStepper1.setSpeed(speedD2);//Rapid Speed
    myStepper1.step(steps3 / 5.8);//Rapid Motor Steps
  }

  if (currentMicros - previousMicros >= interval) {

    previousMicros = currentMicros;
  }

  if (digitalRead(FAST) == 1 && digitalRead(UP_PIN) == 1 && digitalRead(DOWN_PIN) == 0) //rapid traverse down
  { lcd1.setCursor(7, 1);
    lcd1.print(float(float(speedD2) / float(16)), 2);// float divide (8)) x 1 ) for IPM

    myStepper1.setSpeed(speedD3); //Rapid Speed
    myStepper1.step(-steps3 / 4.8); //Rapid Motor Steps
  }

  if (currentMicros - previousMicros >= interval) {

    previousMicros = currentMicros;
  }

}

KING6FAB:
What i had thought of but haven't tried yet because i dont know how to implement it is a switch case, to switch from pot speed to rapid speed.

Accelstepper would be ideal for this project for the acceleration and non blocking, but i cannot get it to work with the Potentiometer control.

I doubt very much that SWITCH / CASE would help - it is just a specific form of IF ELSE intended to make code more readable.

I do think the solution is AccelStepper.

Post the program that represents your best attempt at using AccelStepper and tell us in detail what it actually does and what you want it to do that is different.

...R

PS ... karma for posting a short video

Here’s the accelstepper version… i didn’t create this code, i utilized it from an example online, thus i didnt put any of my lcd code in just to keep it simple for testing.

In this code the push buttons work far as the direction and stop function. Also the pot works for speed.

However i have the hold the direction push buttons in to keep it moving, otherwise it stops after a few turns.

   #include <AccelStepper.h>
#include <Wire.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);

// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4

// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  
}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1;
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0;
  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
  }

  
    // This will run the stepper at a constant speed
    stepper1.runSpeed();
  }

When i add the fast button to the code…
The “fast” push button appears to do nothing. Holding it in with any direction button does nothing.
If i hold the right direction push button button in… it will make the rapid fast move for as long as its held in… If i just press the right push button it will run the pot speed for a few rotations and stop.

The left push button wont make a rapid fast move at all. Holding it in just keeps it going left.

      #include <AccelStepper.h>
#include <Wire.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);

// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  5
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);
}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1;
  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1;
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0;
  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);
    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
  }

  {
    // This will run the stepper at a constant speed
    stepper1.runSpeed();
  }
  if (digitalRead(FAST_PIN) == 0 && sign == 1) { //rapid traverse up
    sign = 1;
    stepper1.setSpeed(4000);
    stepper1.runSpeed();
  }





  if (digitalRead(FAST_PIN) == 0 && sign == -1) {
    //rapid traverse down

    sign = -1;
    stepper1.setSpeed(4000);
    stepper1.runSpeed();
  }

}

The call to runSpeed() should normally be outside all IF sections - just put it as the last thing in loop()

Note that runSpeed() does not use acceleration. If you want acceleration you should use run()

If you want the program to work eve if you take your finger off the button then pressing the button needs to set a variable. Your program seems to set the variable sign so you can use that. For example, as the last thing in loop()

if (sign != 0) {
  stepper1.runSpeed();
}

and remove the reference to sign from these lines (in both places)

  if (digitalRead(FAST_PIN) == 0 && sign == 1) { //rapid traverse up
    sign = 1;

...R

Wow! that solved the problem i was having, now it works as i intended, i can’t believe i spent so much time on that.

However this brought on another problem… implementing the lcd into the code, when i do, everything displays as it should when pressing a corresponding button, but my stepper is acting up with it.

On pot mode, theres more vibration and noise in the steps and it wont reach the same rpm as it did without the lcd.

When pressing the fast button, the stepper goes extremely slow.

Code with lcd in it

      #include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);
// Define the LCD Display
LiquidCrystal_I2C lcd1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  2
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

//Define left, right and stop lights
#define rLight 12
#define lLight 13
#define sLight 11
void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);

  // Set up the lights with outputs.
  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);
  // begin the LCD Display
  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");

}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);

  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1; digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);

  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);

  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);


    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);


  }


  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 1 && digitalRead(RIGHT_PIN) == 0) { //rapid traverse right

    stepper1.setSpeed(-4000);

  }





  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 0 && digitalRead(RIGHT_PIN) == 1) {
    //rapid traverse left

    stepper1.setSpeed(4000);
  }



  if (sign != 0) {
    stepper1.runSpeed();
  }

}

If i remove the lcd code from the loop, it all works correctly but i don’t have the readouts of IPM witch was important so that i can set the machine accurately everytime i use it

The direction readout on button push are not as important

Far as ive read the lcd takes bogs it down, is there a work around for this?

Code with lcd removed from loop

     #include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);
// Define the LCD Display
LiquidCrystal_I2C lcd1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  2
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

//Define left, right and stop lights
#define rLight 12
#define lLight 13
#define sLight 11
void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);

  // Set up the lights with outputs.
  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);
  // begin the LCD Display
  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");

}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);

  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1; digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);

  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);

  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);


    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);


  }


  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 1 && digitalRead(RIGHT_PIN) == 0) { //rapid traverse right

    stepper1.setSpeed(-4000);

  }





  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 0 && digitalRead(RIGHT_PIN) == 1) {
    //rapid traverse left

    stepper1.setSpeed(4000);
  }



  if (sign != 0) {
    stepper1.runSpeed();
  }

}

Code with lcd in it

Unfortunately there is no lcd code in loop() in what you have posted. Please try again.

I would suggest that you change your lcd library to hd44780.h. The hd44780 library is the best available for I2C LCDs and is significantly faster than the library you are using. This can be important if the display updates are blocking the stepper.

The library is available in the Library Manager. Go to Library Manager (in the IDE, Sketch, Include Libraries, Manage Libraries) and in the Topics dropdown choose Display and in the Filter your search box enter hd44780. Select and install the hd44780 library by Bill Perry.

The class that you want to use is the hd44780_I2Cexp class. There are examples to show how to use the library. The nice thing about the hd44780 library is that it will autodetect the I2C address and the I2C backpack to LCD pin mapping.

Here’s a “Hello World” examples which shows how to set up the correct library class

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config display for hd44780 chip

void setup()
{
  // initialize LCD with number of columns and rows:
  lcd.begin(16, 2);

  // Print a message to the LCD
  lcd.print("Hello, World!");
}

void loop()
{
  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);
  delay(1000);
}

Looks like i posted the same code, heres the lcd code

      #include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);
// Define the LCD Display
LiquidCrystal_I2C lcd1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  2
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

//Define left, right and stop lights
#define rLight 12
#define lLight 13
#define sLight 11
void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);

  // Set up the lights with outputs.
  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);
  // begin the LCD Display
  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");

}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);
    lcd1.setCursor(7, 0);
    lcd1.print("LEFT       ");
  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1; digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);
    lcd1.setCursor(7, 0);
    lcd1.print("RIGHT      ");
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);
    lcd1.setCursor(7, 0);
    lcd1.print("HOLD       ");
  }

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);
    // float divide (15)) x 2 ) for IPM
    lcd1.setCursor(7, 1);
    lcd1.print(float(float(current_speed) / float(4)), 2);

    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);


  }


  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 1 && digitalRead(RIGHT_PIN) == 0) { //rapid traverse right
    lcd1.setCursor(7, 1);
    lcd1.print(float(float(MAX_SPEED) / float(4)), 1);// float divide (8)) x 1 ) for IPM


    stepper1.setSpeed(-4000);

  }





  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 0 && digitalRead(RIGHT_PIN) == 1) {
    //rapid traverse left

    lcd1.setCursor(7, 1);
    lcd1.print(float(float(MAX_SPEED) / float(4)), 1);// float divide (8)) x 1 ) for IPM

    stepper1.setSpeed(4000);
  }
  if (sign != 0) {
    stepper1.runSpeed();
  }

}

After thinking about it i believe the fast button not working with the lcd is due to im also pressing a direction button thats continuously telling it to print the direction.

I wasent aware of that lcd library, ill try it out

After thinking about it i believe the fast button not working with the lcd is due to im also pressing a direction button thats continuously telling it to print the direction.

Correct.

It can create problems to continuously print. The i2c bus is relatively slow, uses interrupts, and is blocking.

You need to print when values change, or at periodic intervals no shorter than 250 ms. 500 ms is likely a better interval to visually look at something that is changing rapidly. For periodic updates, I would use a millis() timer, like with "blink without delay", rather than a loop count timer like you do with the analogRead().

Heres my new code, i only implemented it into the potentiometer speed thus far… i tried using that LCD library you mentioned but it kept getting an "error, when i tried uploading the sketch.

I had to put the interval to 5000, otherwise when i press the fast button the stepper acts like it did before i used the accelstepper library, it would run with intermittent stops.

Howevet, with the interval at 5000 my pot reading is very delayed. Is how you would have wrote the blink with out delay?

      #include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);

unsigned long previousMillis= 0;

const long interval = 5000;


// Define the LCD Display
LiquidCrystal_I2C lcd1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  2
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

//Define left, right and stop lights
#define rLight 12
#define lLight 13
#define sLight 11
void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);









  // Set up the lights with outputs.
  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);
  // begin the LCD Display
  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");

}



void loop() {


  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.

  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);

}
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1; digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);
}
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);

}

unsigned long currentMillis = millis();

  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);

    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
   
if ((unasigned long) currentMillis - previousMillis )>= interval) {

    lcd1.setCursor(7, 1);
    lcd1.print(float(float(current_speed) / float(4)), 2);

previousMillis= currentMillis;
  }

}


  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 1 && digitalRead(RIGHT_PIN) == 0) { //rapid traverse right

    stepper1.setSpeed(-4000);
}





  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 0 && digitalRead(RIGHT_PIN) == 1) {
    //rapid traverse left


    stepper1.setSpeed(4000);

}
  if (sign != 0) {
    stepper1.runSpeed();
  }
 
   
   
    
}

Here is your code cleaned up so that it compiles. The lcd update has been removed from the analogRead timing section and placed on its own timer. Look carefully to check how it is different from your arrangement. See if this doesn’t run better.

#include <AccelStepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Define the stepper and the pins it will use
AccelStepper stepper1(AccelStepper::DRIVER, 8, 7);

// Define the LCD Display
LiquidCrystal_I2C lcd1(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display; // set the LCD address to 0x27 for a 16 chars and 2 line display
// Define our three input button pins
#define  LEFT_PIN  5
#define  STOP_PIN  10
#define  RIGHT_PIN 4
#define  FAST_PIN  2
// Define our analog pot input pin
#define  SPEED_PIN A1

// Define our maximum and minimum speed in steps per second (scale pot to these)
#define  MAX_SPEED 2000
#define  MIN_SPEED 0.1

//Define left, right and stop lights
#define rLight 12
#define lLight 13
#define sLight 11

void setup() {
  // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
  stepper1.setMaxSpeed(10000.0);

  // Set up the three button inputs, with pullups
  pinMode(LEFT_PIN, INPUT_PULLUP);
  pinMode(STOP_PIN, INPUT_PULLUP);
  pinMode(RIGHT_PIN, INPUT_PULLUP);
  pinMode(FAST_PIN, INPUT_PULLUP);

  // Set up the lights with outputs.
  pinMode (rLight, OUTPUT);
  pinMode (lLight, OUTPUT);
  pinMode (sLight, OUTPUT);
  // begin the LCD Display
  lcd1.init();
  lcd1.backlight();
  lcd1.setCursor(2, 0);
  lcd1.print (" KING 6 FAB");
  lcd1.setCursor(0, 1);
  lcd1.print (" MILLING MACHINE");
  delay(5000);
  lcd1.clear();
  lcd1.setCursor(0, 1);
  lcd1.print("Speed:");
  lcd1.setCursor(13, 1);
  lcd1.print("IPM");
  Serial.begin(9600);
  lcd1.setCursor(0, 0);
  lcd1.print("Z Axis");
  lcd1.setCursor(7, 0);
  lcd1.print("BEGIN  ");
}

void loop() {
  static float current_speed = 0.0;         // Holds current motor speed in steps/second
  static int analog_read_counter = 1000;    // Counts down to 0 to fire analog read
  static char sign = 0;                     // Holds -1, 1 or 0 to turn the motor on/off and control direction
  static int analog_value = 0;              // Holds raw analog value.
  static unsigned long previousMillis = 0;
  static unsigned long currentMillis = 0;
  const unsigned long interval = 1000;//update display every second
  // If a switch is pushed down (low), set the sign value appropriately
  if (digitalRead(LEFT_PIN) == 0) {
    sign = 1; digitalWrite (rLight, LOW);
    digitalWrite (lLight, HIGH); digitalWrite (sLight, HIGH);
  }
  else if (digitalRead(RIGHT_PIN) == 0) {
    sign = -1; digitalWrite (lLight, LOW);
    digitalWrite (rLight, HIGH); digitalWrite (sLight, HIGH);
  }
  else if (digitalRead(STOP_PIN) == 0) {
    sign = 0; digitalWrite (lLight, HIGH);
    digitalWrite (rLight, HIGH);
    digitalWrite (sLight, LOW);
  }
  // We only want to read the pot every so often (because it takes a long time we don't
  // want to do it every time through the main loop).
  if (analog_read_counter > 0) {
    analog_read_counter--;
  }
  else {
    analog_read_counter = 3000;
    // Now read the pot (from 0 to 1023)
    analog_value = analogRead(SPEED_PIN);
    // Give the stepper a chance to step if it needs to
    stepper1.runSpeed();
    //  And scale the pot's value from min to max speeds
    current_speed = sign * (((analog_value / 1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED);

    // Update the stepper to run at this new speed
    stepper1.setSpeed(current_speed);
  }

  currentMillis = millis();
  if ((currentMillis - previousMillis ) >= interval) {
    lcd1.setCursor(7, 1);
    lcd1.print((current_speed) / 4.0), 2);//current speed is typed as float
    previousMillis = currentMillis;
  }

  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 1 && digitalRead(RIGHT_PIN) == 0) { //rapid traverse right

    stepper1.setSpeed(-4000);
  }

  if (digitalRead(FAST_PIN) == 0 && digitalRead(LEFT_PIN) == 0 && digitalRead(RIGHT_PIN) == 1) {
    //rapid traverse left
    stepper1.setSpeed(4000);
  }
  if (sign != 0) {
    stepper1.runSpeed();
  }
}

i tried using that LCD library you mentioned but it kept getting an "error, when i tried uploading the sketch.

You must have made some sort of error. Did you try to run the example I posted? Please post the code you tried to run and the exact error messages. There is slightly different syntax, and lcd.begin(16,2) replaces the lcd.init() command.

You will have an easier time keeping the lcd from interfering with the stepper and analog read if you convert to the most robust and fastest library available. It is also plug and play for the several different configurations of backpack chip wiring and it will be of help if you ever change the display.

I have a new situation with this setup, once if finally implemented this on to my mill i realized there was great value to a few other functions such as being able to bump the mill in 1/1000 to lock on certain positions - this was easy.

Another function was to home the mill to up and down positions.

I have put on upper and lower limit switchs on a sliding track so they can be positioned as I need them. The idea is to press the Up home button and the mill will run to the up limit switch,s top and slowly back away from it and I can make a tool change. I can then press the down home button and it will run to the down limit switch witch will be adjusted to my working height.

This function is working as intended, however after I do either of these homing actions… the up, down and rapid button functions no longer work as they should. I get very very slow speeds from them, as if something else is working at the same time, blocking them since doing a home function. The only way to resolve this is to reset the Arduino

If I dont do a home function, up,down and rapid all work correctly.

Here is a snipped of the code, showing the homing part of it.

 //  Homing Buttons Action
  if (digitalRead(UPHOME_PIN) == 1 &&   sign == 0) {
    lcd1.setCursor(7, 0);
    lcd1.print("UP   HOME      ");
    while (digitalRead(UPLIMIT_PIN)) {  // Make the Stepper move CCW until the switch is activated


      stepper1.moveTo(-initial_homing);  // Set the position to move to
      stepper1.setMaxSpeed(homeUp);      // Set Max Speed of Stepper (Slower to get better accuracy)
      stepper1.setAcceleration(homeUpAccel);  // Set Acceleration of Stepper
      initial_homing--;  // Decrease by 1 for next move if needed
      stepper1.run();  // Start moving the stepper

    }

    stepper1.setCurrentPosition(0);  // Set the current position as zero for now
    stepper1.setMaxSpeed(homeUpOffset);      // Set Max Speed of Stepper (Slower to get better accuracy)
    stepper1.setAcceleration(upOffsetAccel);  // Set Acceleration of Stepper
    initial_homing = 1;

    while (!digitalRead(UPLIMIT_PIN)) { // Make the Stepper move CW until the switch is deactivated
      stepper1.moveTo(initial_homing);
      stepper1.run();
      initial_homing--;

    }
  }
  if (digitalRead(DOWNHOME_PIN) == 0 &&   sign == 0) {
    lcd1.setCursor(7, 0);
    lcd1.print("DOWN HOME      ");
    while (digitalRead(DOWNLIMIT_PIN)) {  // Make the Stepper move CCW until the switch is activated

      stepper1.moveTo(initial_homing);  // Set the position to move to
      stepper1.setMaxSpeed(homeDown);      // Set Max Speed of Stepper (Slower to get better accuracy)
      stepper1.setAcceleration(homeDownAccel);  // Set Acceleration of Stepper
      initial_homing--;  // Decrease by 1 for next move if needed
      stepper1.run();  // Start moving the stepper

    }

    stepper1.setCurrentPosition(0);  // Set the current position as zero for now
    stepper1.setMaxSpeed(homeDownOffset);      // Set Max Speed of Stepper (Slower to get better accuracy)
    stepper1.setAcceleration(DownOffsetAccel);  // Set Acceleration of Stepper
    initial_homing = 1;

    while (!digitalRead(DOWNLIMIT_PIN)) { // Make the Stepper move CW until the switch is deactivated
      stepper1.moveTo(initial_homing);
      stepper1.run();
      initial_homing++;

    }

I attached the full code because its to big to post.

MarZaxis.ino (14.3 KB)