Start/stop a turntable with toggle pushbutton

I am following a YouTube project to control a model train turntable. The following code uses a SPDT switch and I want to use a pushbutton 'toggle' switch.
No matter what I try, I end up breaking out of the loop, and cannot get back to execute the program further.
Any suggestions would be welcome.

[code]
//Turntable stepper (ex Dutch) with toggle pushbutton to rotate

//define stepper pins
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

//define pushbutton and led pins
const int moveButPin = 9; //when pushed (LOW), (0), (ON), stepper turns. Pull up resistor inverts logic
const int redLedPin = 5; //led is HIGH, (ON), (1) when stepper is running

//define pushbutton states
int moveButState = HIGH;
int moveButStateNew;
int moveButStateOld = LOW;
int delayTime = 50;
unsigned long timeSinceLastToggle = 0;
unsigned long debounce = 20UL;

//define stepper constants
const float stepsPerMotorRevolution = 32; //for the 28BYJ stepper this is 32
const float gearboxReduction = 64; //the 28BYJ is fitted with a 64:1 reduction gearbox
const float stepsPerStepperRevolution = stepsPerMotorRevolution * gearboxReduction; //Stepper and gearbox specific, = 2048 for 28BYJ-48

//define stepper variable
int stepperRpm = 8; // max speed of stepper is 12 rpm, else pulses get lost
/if stepper turns at x Rpm, then time for one revolution is 60/x seconds, or 60 000 000/x micros (us)
and if each revolution is y stepsPerStepperRevolution, then each step takes 60 000 000/x/y us
/
unsigned long timeOfEachStep;
unsigned long timeOfLastStep;
byte stepnr;

void doOneStep() {
digitalWrite(redLedPin, HIGH);
stepnr = (stepnr + 1) % 8; // counts and remembers in which of the 8 phases the stepper is
switch (stepnr) {
case 0:
digitalWrite(stepperPin1, HIGH);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, LOW);
break;
case 1:
digitalWrite(stepperPin1, HIGH);
digitalWrite(stepperPin2, HIGH);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, LOW);
break;
case 2:
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, HIGH);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, LOW);
break;
case 3:
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, HIGH);
digitalWrite(stepperPin3, HIGH);
digitalWrite(stepperPin4, LOW);
break;
case 4:
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, HIGH);
digitalWrite(stepperPin4, LOW);
break;
case 5:
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, HIGH);
digitalWrite(stepperPin4, HIGH);
break;
case 6:
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, HIGH);
break;
case 7:
digitalWrite(stepperPin1, HIGH);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, HIGH);
break;
}
}

void stepperIdle() {
digitalWrite(stepperPin1, LOW);
digitalWrite(stepperPin2, LOW);
digitalWrite(stepperPin3, LOW);
digitalWrite(stepperPin4, LOW);
digitalWrite(redLedPin, LOW);
}

void setup() {
Serial.begin(9600);
pinMode(stepperPin1, OUTPUT);
pinMode(stepperPin2, OUTPUT);
pinMode(stepperPin3, OUTPUT);
pinMode(stepperPin4, OUTPUT);
pinMode(moveButPin, INPUT_PULLUP);
pinMode(redLedPin, OUTPUT);
digitalWrite(redLedPin, LOW);
timeOfEachStep = (60000000UL / stepperRpm) / stepsPerStepperRevolution; //approx 3000us
}

void loop() {
while (moveButState == LOW) {
if ((micros() - timeOfLastStep) > timeOfEachStep) { //micros is the number of milliseconds since the program started
timeOfLastStep = micros();
doOneStep();
}
}
stepperIdle();
}

//Turntable stepper (ex Dutch) with toggle pushbutton to rotate

//define stepper pins
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

//define pushbutton and led pins
const int moveButPin = 9; //when pushed (LOW), (0), (ON), stepper turns. Pull up resistor inverts logic
const int redLedPin = 5; //led is HIGH, (ON), (1) when stepper is running

//define stepper constants
const float stepsPerMotorRevolution = 32; //for the 28BYJ stepper this is 32
const float gearboxReduction = 64; //the 28BYJ is fitted with a 64:1 reduction gearbox
const float stepsPerStepperRevolution = stepsPerMotorRevolution * gearboxReduction; //Stepper and gearbox specific, = 2048 for 28BYJ-48
const int stepperRpm = 8; // max speed of stepper is 12 rpm, else pulses get lost
// if stepper turns at x Rpm, then time for one revolution is 60 / x seconds, or 60 000 000 / x micros (us)
//and if each revolution is y stepsPerStepperRevolution, then each step takes 60 000 000 / x / y us /
const unsigned long timeOfEachStep = (60000UL / stepperRpm) / stepsPerStepperRevolution; //approx 3000us;

//define stepper variable
unsigned long timeOfLastStep = 0;
byte stepnr = 0;

void doOneStep() {
  digitalWrite(redLedPin, HIGH);
  stepnr = (stepnr + 2) % 8; // counts and remembers in which of the 8 phases the stepper is
  switch (stepnr) {
    case 0:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 1:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 2:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 3:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, LOW);
      break;
    case 4:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, LOW);
      break;
    case 5:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, HIGH);
      break;
    case 6:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, HIGH);
      break;
    case 7:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, HIGH);
      break;
  }
}

void stepperIdle() {
  digitalWrite(stepperPin1, LOW);
  digitalWrite(stepperPin2, LOW);
  digitalWrite(stepperPin3, LOW);
  digitalWrite(stepperPin4, LOW);
  digitalWrite(redLedPin, LOW);
}

void setup() {
  Serial.begin(9600);
  pinMode(stepperPin1, OUTPUT);
  pinMode(stepperPin2, OUTPUT);
  pinMode(stepperPin3, OUTPUT);
  pinMode(stepperPin4, OUTPUT);
  pinMode(moveButPin, INPUT_PULLUP);
  pinMode(redLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
}

void loop() {
  while (digitalRead(moveButPin) == LOW) {
    digitalWrite(redLedPin, HIGH);
    if ((millis() - timeOfLastStep) > timeOfEachStep) { //micros is the number of milliseconds since the program started
      timeOfLastStep = millis();
      doOneStep();
    }
  }
  stepperIdle();
}

I don't see anything in the code that reads any inputs - digitalRead for instance.

  • i don't see the code reading the button pin being read
  • also shouldn't there be a delay after each step? i've found that i can't step faster that a millisec. shouldn't the delay be in doOneStep()?
  • won't you want a button to go in the opposite direction? you can add a direction parameter to doOneStep()
void loop() {
    if (LOW == digitalRead (moveButPin))
        doOneStep();
        delay (2);
        }
    }
    else
        stepperIdle();
}

consider

// simple stepper motor turntable controller

#undef MyHW
#ifdef MyHW
const int stepperPin1 = 10;
const int stepperPin2 = 11;
const int stepperPin3 = 12;
const int stepperPin4 = 13;

const int redLedPin   = 5; 

const int ButForPin  = A1; 
const int ButRevPin  = A2; 

#define StepMsec    100

#else
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

const int redLedPin = 5; 

const int ButForPin  = 9; 
const int ButRevPin  = 8; 

#define StepMsec    2
#endif

// -----------------------------------------------------------------------------

const byte StepperPins [] = {
    stepperPin1, stepperPin2, stepperPin3, stepperPin4
};
#define N_STEP_PINS     sizeof(StepperPins)

const byte StepperSeq [][N_STEP_PINS] = {
    { HIGH, LOW,  LOW,  LOW  },
    { HIGH, HIGH, LOW,  LOW  },
    { LOW,  HIGH, LOW,  LOW  },
    { LOW,  HIGH, HIGH, LOW  },

    { LOW,  LOW,  HIGH, LOW  },
    { LOW,  LOW,  HIGH, HIGH },
    { LOW,  LOW,  LOW,  HIGH },
    { HIGH, LOW,  LOW,  HIGH },
};
#define N_SEQ_STEPS (sizeof (StepperSeq)/N_STEP_PINS)

const byte StepperIdle [N_STEP_PINS] = { HIGH, HIGH,  HIGH,  HIGH };

enum { For = 1, Rev = -1 };

// -----------------------------------------------------------------------------
void step (
    const byte   seq [N_STEP_PINS] )
{
    for (unsigned n = 0; n < N_STEP_PINS; n++)
        digitalWrite (StepperPins [n], seq [n]);
    delay (StepMsec);
}

// -------------------------------------
void doOneStep (
    int   dir)
{
    static byte stepnr;
    stepnr = (stepnr + dir) % N_SEQ_STEPS;

    step (& StepperSeq [stepnr][0]);

    digitalWrite (redLedPin, HIGH);
}

// -------------------------------------
void stepperIdle ()
{
    step (StepperIdle);

    digitalWrite (redLedPin, LOW);
}

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);

    pinMode (redLedPin,  OUTPUT);

    pinMode (ButForPin, INPUT_PULLUP);
    pinMode (ButRevPin, INPUT_PULLUP);

    stepperIdle ();
    for (unsigned n = 0; n < N_STEP_PINS; n++)
        pinMode (StepperPins [n], OUTPUT);
}

// -----------------------------------------------------------------------------
void loop () {
    if (LOW == digitalRead (ButForPin))
        doOneStep (For);
    else if (LOW == digitalRead (ButRevPin))
        doOneStep (Rev);
    else
        stepperIdle ();
}

If your pushbutton is a toggle switch (press ON, press OFF), then it should work the same as a SPDT switch.

If your pushbutton is momentary (press ON, release OFF) and you want to simulate a toggle switch, then I don't see where this is done in your code. Looks like you have to continuously press the pushbuton to keep moveButPin LOW. Also, there's no debouncing.

Just to demonstrate how easy it is to debounce and convert a momentary pushbutton to toggle type (I've used your moveButPin and redLedPin numbers):

#include <Toggle.h>

const byte moveButPin = 9;
const byte redLedPin = 5;

Toggle sw1(moveButPin);

void setup() {
  sw1.begin(moveButPin);
  pinMode(redLedPin, OUTPUT);
}

void loop() {
  sw1.poll();
  digitalWrite(redLedPin, sw1.toggle());
}

Toggle Library

Steppers get hot. Also, they're never really all that smooth. Just food for thought.

I just finished building a display case for my FIL for his antique milk bottles and after fiddling with a stepper turntable and being dissatisfied with the result, I bought one of these:

https://www.amazon.ca/gp/product/B095HKVW46/ref=ppx_yo_dt_b_asin_title_o09_s00?ie=UTF8&th=1

It can be powered by micro USB or 4AA batteries, so I soldered in wires to the battery box, left the turntable power switch selected to clockwise and wired from the battery box out to a remote switch I had so it could be paused while FIL is standing next to the thing chewing the rag with his fellow collectors.

For those about to build, I salute you! :vulcan_salute:

Hi John,

welcome to the Arduino-Forum,
you should post code like described here.

best regards Stefan

1 Like

Hi StefanL38,
Thank you for the explanation on how to post code. I will try harder going forward.
If I follow the instructions 'Copy for Forum', and then Ctrl-V this what I get.
Not sure if this is good enough.
Regards, John

[code]
//Turntable stepper (ex Dutch) with push to rotate

//define stepper pins
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

//define switch and led pins
const int stepperMovePin = 9; //when pushed (LOW), (0), (ON), stepper turns
const int redLedPin = 5; //led is HIGH, (ON), (1) when stepper is running

//define stepper constants
const float stepsPerMotorRevolution = 32;  //for the 28BYJ stepper this is 32
const float gearboxReduction = 64;  //the 28BYJ is fitted with a 64:1 reduction gearbox
const float stepsPerStepperRevolution = stepsPerMotorRevolution * gearboxReduction;  //Stepper and gearbox specific, = 2048 for 28BYJ-48

//define stepper variables
//if stepper turns at x Rpm, then time for one revolution is 60/x seconds, or 60 000 000/x micros (us)
//if each revolution is y stepsPerStepperRevolution, then each step takes 60 000 000/x/y us
int stepperRpm = 2; // max speed of stepper is 12 rpm, else pulses get lost
unsigned long timeOfEachStep;  //time taken from one step to the next (time interval)
unsigned long timeOfLastStep;  //time since the program started running
byte stepnr;  //stepper phase counter

void setup() {
  Serial.begin(9600);
  pinMode(stepperMovePin, INPUT_PULLUP);
  pinMode(stepperPin1, OUTPUT);
  pinMode(stepperPin2, OUTPUT);
  pinMode(stepperPin3, OUTPUT);
  pinMode(stepperPin4, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
  timeOfEachStep = (60000000UL / stepperRpm) / stepsPerStepperRevolution; //approx 3000us
}

void loop() {
  //check whether the pushbutton is pressed
  while (digitalRead(stepperMovePin) == LOW) {
    delay(10);
    if ((micros() - timeOfLastStep) > timeOfEachStep) {  //micros is the number of milliseconds since the program started
      timeOfLastStep = micros();
      //if the button is pressed and the timing is correct, switch the led ON and rotate the stepper
      digitalWrite(redLedPin, HIGH);
      stepnr = (stepnr + 1) % 8;  // counts and remembers in which of the 8 phases the stepper is
      switch (stepnr) {
        case 0:
          digitalWrite(stepperPin1, HIGH);
          digitalWrite(stepperPin2, LOW);
          digitalWrite(stepperPin3, LOW);
          digitalWrite(stepperPin4, LOW);
          break;
        case 1:
          digitalWrite(stepperPin1, HIGH);
          digitalWrite(stepperPin2, HIGH);
          digitalWrite(stepperPin3, LOW);
          digitalWrite(stepperPin4, LOW);
          break;
        case 2:
          digitalWrite(stepperPin1, LOW);
          digitalWrite(stepperPin2, HIGH);
          digitalWrite(stepperPin3, LOW);
          digitalWrite(stepperPin4, LOW);
          break;
        case 3:
          digitalWrite(stepperPin1, LOW);
          digitalWrite(stepperPin2, HIGH);
          digitalWrite(stepperPin3, HIGH);
          digitalWrite(stepperPin4, LOW);
          break;
        case 4:
          digitalWrite(stepperPin1, LOW);
          digitalWrite(stepperPin2, LOW);
          digitalWrite(stepperPin3, HIGH);
          digitalWrite(stepperPin4, LOW);
          break;
        case 5:
          digitalWrite(stepperPin1, LOW);
          digitalWrite(stepperPin2, LOW);
          digitalWrite(stepperPin3, HIGH);
          digitalWrite(stepperPin4, HIGH);
          break;
        case 6:
          digitalWrite(stepperPin1, LOW);
          digitalWrite(stepperPin2, LOW);
          digitalWrite(stepperPin3, LOW);
          digitalWrite(stepperPin4, HIGH);
          break;
        case 7:
          digitalWrite(stepperPin1, HIGH);
          digitalWrite(stepperPin2, LOW);
          digitalWrite(stepperPin3, LOW);
          digitalWrite(stepperPin4, HIGH);
          break;
      }
    }
    //if the button is not pressed, switch the led OFF and stop the stepper
    while (digitalRead(stepperMovePin) == HIGH) {
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      digitalWrite(redLedPin, LOW);;
    }
  }
  Serial.print(redLedPin);
}
[/code]type or paste code here

Hi,
the issue I have is that this is a model train turntable where the positions will be indexed based on number of steps from a reference stored in EEPROM. The model you are using does a different task.
Thanks for the feedback.

1 Like

Thank you so much for taking an interest.
This first section of the sketch to control a model train turntable is part of a much bigger picture going forward. I am following the progress on YouTube as I have no desire to write all the code myself, so I would like to stay as close to the originators code as possible. I am sure there are many ways to rewrite what he/she is doing, but for better or worse, I am following him/her.
At the end I anticipate being able to rotate the turntable CW or CCW, vary the speed of rotation, select various positions indexed to a reference (Hall effect transistor), store the positions in EEPROM, and then be able to select position 1,2, 3 etc and the turntable will rotate to the elected position accurately.
dlloyd, you have guessed correctly, I am trying to get the turntable moving using a momentary pushbutton rather than a SPDT switch - with the view to using a keypad much, much later.
I note than the library is your creation, well done and works brilliantly.
I did not include my attempts at including a 'toggle' switch because none of the 10 versions I tried worked.
The problem is that when I call 'doOneStep' I leave the loop, never to come back.
If I use where do I insert this code so that 'doOneStep' is called, and the loop returns?

[code]
void loop() {
  if (digitalRead(stepperMovePin) == LOW) {  //if button is pushed (LOW)
    if ((micros() - timeOfLastStep) > timeOfEachStep) {  //micros is the number of us since the program started
      timeOfLastStep = micros();
      doOneStep();
    }
  }
  else
  stepperIdle();
}
[/code]

Hi
this is a very neat solution, but in all honesty, I am trying to stay as close to the originators code as possible, because there is a lot more to come.
All I am trying to achieve here is to use a toggle momentary pushbutton as a SPDT switch and keep the code running.
Cheers

Hi,
Is your momentary press button, a toggle PUSH ON, PUSH OFF type?
OR
Is it a simple PRESS ON and then OFF when the button is released.

Can you please post an image of the button you are trying?

Google;

push on push off switch

Thanks.. Tom.... :smiley: :+1: :australia:

Hi Tom, same time zone!
This is a simple Jaycar momentary pushbutton that I know I can code to a toggle switch, but the problem is where does the sub-program, doOne Step, get called and returned?.

image

Hi,
So you have a "a simple PRESS ON and then OFF when the button is released."
Google;

arduino momentary toggle code

Thanks.. Tom... :smiley: :+1: :coffee: :australia:
PS. Ballarat, Victoria

Please explain more about this. Which version of code behaves like this?

Hi,
Try this library, it has debounce and toggle operation.

Tom... :smiley: :+1: :coffee: :australia:

Hi, what I am trying to say is this:
I do not understand, and I have tried many, many ways, is where in the execution code below, do I add the switch toggling. Is it added at the beginning of the loop, or at the end? Have a look at what I tried further down.

[code]
void loop() {
  if (digitalRead(stepperMovePin) == LOW) {  //if button is pushed (LOW)
    if ((micros() - timeOfLastStep) > timeOfEachStep) {  //micros is the number of us since the program started
      timeOfLastStep = micros();
      doOneStep();
    }
  }
  else
  stepperIdle();
}
[/code]

Here is my attempt at toggling. The turntable turns but does not stop.

[code]
void loop() {
  moveButStateNew = digitalRead(moveButPin);
  delay(delayTime);
  if (moveButStateOld == LOW && moveButStateNew == HIGH) {
    if (moveButState == LOW) {
      if ((micros() - timeOfLastStep) > timeOfEachStep) {  //micros is the number of milliseconds since the program started
        timeOfLastStep = micros():
         doOneStep;
          moveButState = HIGH;
        }
      }
      else
        stepperIdle;
      moveButState = LOW;
    }
  }
  moveButStateOld = moveButStateNew;

[/code]

Here is code with toggle between running and stopped using Bounce2 for the button

EDIT: Correct bracket position

#include <Bounce2.h>


//Turntable stepper (ex Dutch) with push to rotate

//define stepper pins
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

//define switch and led pins
const int stepperMovePin = 9; //when pushed (LOW), (0), (ON), stepper turns
const int redLedPin = 5; //led is HIGH, (ON), (1) when stepper is running

//define stepper constants
const float stepsPerMotorRevolution = 32;  //for the 28BYJ stepper this is 32
const float gearboxReduction = 64;  //the 28BYJ is fitted with a 64:1 reduction gearbox
const float stepsPerStepperRevolution = stepsPerMotorRevolution * gearboxReduction;  //Stepper and gearbox specific, = 2048 for 28BYJ-48

//define stepper variables
//if stepper turns at x Rpm, then time for one revolution is 60/x seconds, or 60 000 000/x micros (us)
//if each revolution is y stepsPerStepperRevolution, then each step takes 60 000 000/x/y us
int stepperRpm = 2; // max speed of stepper is 12 rpm, else pulses get lost
unsigned long timeOfEachStep;  //time taken from one step to the next (time interval)
unsigned long timeOfLastStep;  //time since the program started running
byte stepnr;  //stepper phase counter

#define stopped 0
#define moving 1
byte machineStatus = stopped;
Bounce debouncer = Bounce(); // Instantiate a Bounce object

void setup() {
  Serial.begin(9600);
  pinMode(stepperMovePin, INPUT_PULLUP);
  pinMode(stepperPin1, OUTPUT);
  pinMode(stepperPin2, OUTPUT);
  pinMode(stepperPin3, OUTPUT);
  pinMode(stepperPin4, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
  timeOfEachStep = (60000000UL / stepperRpm) / stepsPerStepperRevolution; //approx 3000us
  debouncer.attach(stepperMovePin, INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
  debouncer.interval(25); // Use a debounce interval of 25 milliseconds
}

void loop() {
  //check whether the pushbutton is pressed
  debouncer.update(); // Update the Bounce instance
  if ( debouncer.fell() ) {  // Call code if button transitions from HIGH to LOW
    if (machineStatus == stopped)
    {
      machineStatus = moving;
    }
    else
    {
      machineStatus = stopped;
    }
    Serial.print("machineStatus = ");
    Serial.println(machineStatus);
  } //add bracket here to close toggle reading block
    // while (digitalRead(stepperMovePin) == LOW) {
    if (machineStatus == moving) {
      delay(10);
      if ((micros() - timeOfLastStep) > timeOfEachStep) {  //micros is the number of milliseconds since the program started
        timeOfLastStep = micros();
        //if the button is pressed and the timing is correct, switch the led ON and rotate the stepper
        digitalWrite(redLedPin, HIGH);
        stepnr = (stepnr + 1) % 8;  // counts and remembers in which of the 8 phases the stepper is
        switch (stepnr) {
          case 0:
            digitalWrite(stepperPin1, HIGH);
            digitalWrite(stepperPin2, LOW);
            digitalWrite(stepperPin3, LOW);
            digitalWrite(stepperPin4, LOW);
            break;
          case 1:
            digitalWrite(stepperPin1, HIGH);
            digitalWrite(stepperPin2, HIGH);
            digitalWrite(stepperPin3, LOW);
            digitalWrite(stepperPin4, LOW);
            break;
          case 2:
            digitalWrite(stepperPin1, LOW);
            digitalWrite(stepperPin2, HIGH);
            digitalWrite(stepperPin3, LOW);
            digitalWrite(stepperPin4, LOW);
            break;
          case 3:
            digitalWrite(stepperPin1, LOW);
            digitalWrite(stepperPin2, HIGH);
            digitalWrite(stepperPin3, HIGH);
            digitalWrite(stepperPin4, LOW);
            break;
          case 4:
            digitalWrite(stepperPin1, LOW);
            digitalWrite(stepperPin2, LOW);
            digitalWrite(stepperPin3, HIGH);
            digitalWrite(stepperPin4, LOW);
            break;
          case 5:
            digitalWrite(stepperPin1, LOW);
            digitalWrite(stepperPin2, LOW);
            digitalWrite(stepperPin3, HIGH);
            digitalWrite(stepperPin4, HIGH);
            break;
          case 6:
            digitalWrite(stepperPin1, LOW);
            digitalWrite(stepperPin2, LOW);
            digitalWrite(stepperPin3, LOW);
            digitalWrite(stepperPin4, HIGH);
            break;
          case 7:
            digitalWrite(stepperPin1, HIGH);
            digitalWrite(stepperPin2, LOW);
            digitalWrite(stepperPin3, LOW);
            digitalWrite(stepperPin4, HIGH);
            break;
        }
      }
    }
    //if the button is not pressed, switch the led OFF and stop the stepper
    // while (digitalRead(stepperMovePin) == HIGH) {
    if (machineStatus == stopped) {
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      digitalWrite(redLedPin, LOW);;
    }
//  } delete
  Serial.print("redLedPin= ");
  Serial.println(digitalRead(redLedPin));
}

I've added the Toggle Library in your code below.

  • Note that pinMode(moveButPin, INPUT_PULLUP); was removed (done by default in the library)
  • If you need moveButton to start in the opposite state, change line 106 to
    while (moveButton.toggle(1) == LOW) {
//Turntable stepper (ex Dutch) with toggle pushbutton to rotate

#include <Toggle.h>

//define stepper pins
const int stepperPin1 = A1;
const int stepperPin2 = A2;
const int stepperPin3 = A3;
const int stepperPin4 = A4;

//define pushbutton and led pins
const int moveButPin = 9; //when pushed (LOW), (0), (ON), stepper turns. Pull up resistor inverts logic
const int redLedPin = 5; //led is HIGH, (ON), (1) when stepper is running

Toggle moveButton(moveButPin);

//define stepper constants
const float stepsPerMotorRevolution = 32; //for the 28BYJ stepper this is 32
const float gearboxReduction = 64; //the 28BYJ is fitted with a 64:1 reduction gearbox
const float stepsPerStepperRevolution = stepsPerMotorRevolution * gearboxReduction; //Stepper and gearbox specific, = 2048 for 28BYJ-48
const int stepperRpm = 8; // max speed of stepper is 12 rpm, else pulses get lost
// if stepper turns at x Rpm, then time for one revolution is 60 / x seconds, or 60 000 000 / x micros (us)
//and if each revolution is y stepsPerStepperRevolution, then each step takes 60 000 000 / x / y us /
const unsigned long timeOfEachStep = (60000UL / stepperRpm) / stepsPerStepperRevolution; //approx 3000us;

//define stepper variable
unsigned long timeOfLastStep = 0;
byte stepnr = 0;

void doOneStep() {
  digitalWrite(redLedPin, HIGH);
  stepnr = (stepnr + 2) % 8; // counts and remembers in which of the 8 phases the stepper is
  switch (stepnr) {
    case 0:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 1:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 2:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, LOW);
      break;
    case 3:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, HIGH);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, LOW);
      break;
    case 4:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, LOW);
      break;
    case 5:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, HIGH);
      digitalWrite(stepperPin4, HIGH);
      break;
    case 6:
      digitalWrite(stepperPin1, LOW);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, HIGH);
      break;
    case 7:
      digitalWrite(stepperPin1, HIGH);
      digitalWrite(stepperPin2, LOW);
      digitalWrite(stepperPin3, LOW);
      digitalWrite(stepperPin4, HIGH);
      break;
  }
}

void stepperIdle() {
  digitalWrite(stepperPin1, LOW);
  digitalWrite(stepperPin2, LOW);
  digitalWrite(stepperPin3, LOW);
  digitalWrite(stepperPin4, LOW);
  digitalWrite(redLedPin, LOW);
}

void setup() {
  Serial.begin(9600);
  moveButton.begin(moveButPin);
  pinMode(stepperPin1, OUTPUT);
  pinMode(stepperPin2, OUTPUT);
  pinMode(stepperPin3, OUTPUT);
  pinMode(stepperPin4, OUTPUT);
  pinMode(redLedPin, OUTPUT);
  digitalWrite(redLedPin, LOW);
}

void loop() {
  moveButton.poll();
  while (moveButton.toggle() == LOW) {
    digitalWrite(redLedPin, HIGH);
    if ((millis() - timeOfLastStep) > timeOfEachStep) { //micros is the number of milliseconds since the program started
      timeOfLastStep = millis();
      doOneStep();
    }
  }
  stepperIdle();
}