Applying a PAUSE and RESUME feature in my Pneumatic Pick-and-Place Project

// Define pin assignments for components
const int fwdButtonPin = 2;    // Pin for the forward button
const int revButtonPin = 3;    // Pin for the reverse button
const int lhsSwitchPin = 4;    // Pin for the left-hand side reed switch
const int rhsSwitchPin = 5;    // Pin for the right-hand side reed switch
const int motorRSPin = 6;      // Pin for the RS signal of the motor
const int motorLSPin = 7;      // Pin for the LS signal of the motor
const int y1Pin = 8;           // Pin for controlling Y1
const int aPlusPin = 9;        // Pin for the A+ reed switch
const int aMinusPin = 10;      // Pin for the A- reed switch
const int vacPin = A5;         // Pin for controlling the vacuum
const int y2Pin = 11;          // Pin for controlling Y2
const int bPlusPin = 12;       // Pin for the B+ reed switch
const int bMinusPin = 13;      // Pin for the B- reed switch
const int startButtonPin = A4; // Pin for the START button
const int stopButtonPin = A3;  // Pin for the STOP button
const int AMswitch = A2;	   // Pin for the A/M Switch

void setup() 
{
	// Initialize pins
	pinMode(AMswitch, INPUT);
	pinMode(fwdButtonPin, INPUT);
	pinMode(revButtonPin, INPUT);
	pinMode(lhsSwitchPin, INPUT);
	pinMode(rhsSwitchPin, INPUT);
	pinMode(motorRSPin, OUTPUT);
	pinMode(motorLSPin, OUTPUT);
	pinMode(y1Pin, OUTPUT);
	pinMode(aPlusPin, INPUT);
	pinMode(aMinusPin, INPUT);
	pinMode(vacPin, OUTPUT);
	pinMode(y2Pin, OUTPUT);
	pinMode(bPlusPin, INPUT);
	pinMode(bMinusPin, INPUT);
	pinMode(startButtonPin, INPUT);
	pinMode(stopButtonPin, INPUT);

	// Initial state for motor control
	digitalWrite(motorRSPin, LOW);
	digitalWrite(motorLSPin, LOW);
	digitalWrite(y1Pin, LOW);
	digitalWrite(vacPin, LOW);
	digitalWrite(y2Pin, LOW);

	// Serial communication for debugging (optional)
	Serial.begin(9600);
}

void loop() 
{  
	// Define AM switch state (Manual=1, Auto=0)
	int AM = digitalRead(AMswitch);

	// Check the state of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);

	// Choose the mode based on the state of AM
	if (AM == 1) {
		AutoMode(); // Call the function for Automatic Mode
	} else if (AM == 0) {
		ManualMode(); // Call the function for Manual Mode
	}

	// Add a small delay to prevent rapid state changes
	delay(100);

	// Print state for debugging (optional)
	Serial.print(" Mode: "); Serial.print(AM);
	Serial.print(" |Inputs:");
	Serial.print(Aplus);
	Serial.print(Aminus);
	Serial.print(Bplus);
	Serial.print(Bminus);
 	Serial.print(" |Outputs:");
	delay(100);
}

void AutoMode() // Commands for Automatic Mode (AM == 1)
{

	// Check the state of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);

	digitalWrite(FWD,0);
	digitalWrite(REV,0);

	if (Start == 1) {
		// If START is pressed, move the car automatically to the LHS
		digitalWrite(motorRSPin, 0);
		digitalWrite(motorLSPin, 1);
	} else if (Stop == 1 || LHS == 1 || RHS == 1) {
		// If STOP is pressed, pause the system
		digitalWrite(motorRSPin, 0);
		digitalWrite(motorLSPin, 0);
	} 
	// Pick-and-Place Sequence based on the states of switches
	if (LHS == 1) {
		// Step 1: Extend Y1
		digitalWrite(y1Pin, 1);
	} 
	else if (Aplus == 1) {
		// Step 2: Trigger A+, Turn ON VAC, then Retract Y1
		delay(1000);
		digitalWrite(vacPin, 1);
		delay(2000);
		digitalWrite(y1Pin, 0);
	} 
	else if (Aminus == 1) {
		// Step 3: Trigger A-, activate Y2
		digitalWrite(y2Pin, 1);
	} 
	else if (Bplus == 1) {
		// Step 4: Trigger B+, Turn OFF VAC, Retract Y2
		digitalWrite(vacPin, 0);
		delay(1000);
		digitalWrite(y2Pin, 0);
	} 
	else if (Bminus == 1) {
		// Step 5: Trigger B-, move cart to RHS
		digitalWrite(motorRSPin, 1);
		digitalWrite(motorLSPin, 0);
	}

	if (Stop == 1) {
		digitalWrite(Aplus&&Aminus&&Bplus&&Bminus,0);
	}
}

void ManualMode() // Commands for Automatic Mode (AM == 0)
{
	// Check the state of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);

	// Commands for Manual Mode (AM == 0)

	// Pick-and-Place Sequence based on the states of switches
	if (LHS == 1) {
		// Step 1: Extend Y1
		digitalWrite(y1Pin, 1);
	} 
	else if (Aplus == 1) {
		// Step 2: Trigger A+, Turn ON VAC, then Retract Y1
		delay(1000);
		digitalWrite(vacPin, 1);
		delay(2000);
		digitalWrite(y1Pin, 0);
	} 
	else if (Aminus == 1) {
		// Step 3: Trigger A-, activate Y2
		digitalWrite(y2Pin, HIGH);
	} 
	else if (Bplus == 1) {
		// Step 4: Trigger B+, Turn OFF VAC, Retract Y2
		digitalWrite(vacPin, 0);
		delay(1000);
		digitalWrite(y2Pin, 0);
	} 
	if (Stop == 1) {
		digitalWrite(Aplus&&Aminus&&Bplus&&Bminus,0);
	}
}

I/Os (kinda long, but please bear with me)
For context, this project is a "Pneumatic Pick-and-Place System" with 4 outputs:

  • 2 cylinders that extend/retract if air is applied/removed = 8 & 11
  • 1 vacuum to suck/release the object= A5
  • 1 DC Motor (w/ H-bridge) on a conveyor that carries an object = 6 & 7 for motor pins direction

And 11 inputs:

  • Forward = 2
  • Reverse = 3
  • LHS (left-hand side) = 4
  • RHS (right-hand side) = 5
  • Reed Switches (A+, A-, B+,B-) = 9,10,12,13
    If cylinderA/B is extended = A+/B+
    If cylinderA/B is retracted = A-/B-
    these reed switches act as sensors to continue the sequence
  • Start = A4
  • Stop = A3
  • Auto/Manual (AM) Switch = A2

Heres a more comprehensive step-by-step process of my project
P-n-P Project Description.pdf (167.8 KB)

Regarding the PDF, I have already accomplished Sections B, C, and D. I can do the necessary commands whether I am in AUTO mode or MANUAL mode as shown in the code.

The parts that don't get how to do are Section A and the additional conditions shown before the Illusion (Stop Conditions), specifically:

  • Pressing STOP should pause the pick-and-place sequence in Section D when I pressed it.
  • Pressing STOP Twice should initialize the entire system completely.
  • Pressing START after pausing should continue the sequence.
  • Switching from Manual mode to Auto mode should also initialize the entire system completely.

Help would be very much appreciated. Thanks

is that a school project?


I'd suggest you pick one of the numerous button library such as Button in easyRun or OneButton or Toggle or EasyButton or Bounce2, and study finite state machines to implement the code. Here is a small introduction to the topic: Yet another Finite State Machine introduction

Yeah, it is, I've been working on this for the past seven days, but I just can't solve it. I completed the entire project using Festo's FluidSim (using actual relays), but I don't know how to replicate the program to Arduino. I'll try reading some of the things you posted.

Here's the FluidSim File by the way if you're curious.

can you explain the sensors used in the auto mode? how does "it" know when it has reached the leftmost side as well as has returned to it's initial position?

  • haven't the buttons and switches been read in loop()?
  • why "write" to an input pin?
  • buttons are typically connected between the pin and ground, the pin configured as INPUT_PULLUP to use the internal pullup resistor which pulls the pin HIGH and when pressed, the button pulls the pin LOW. a button press can be recognized by detecting a change in state and becoming LOW
  • does something like this need to be "paused" before it completes or can it be allowed to complete?

is there a need for that initial delay()?

  • this looks like you're trying to set multiple pins to zero. need to set each pin individually
  • looks like the manual mode is semi-autonomous

  • seems that in autonomous modes, each step needs to be tracked, perform some action when the input that step waits for becomes active and advance to the next step.

if some input becomes active, indicating that that step has been reached, a subsequent else if for the next trigger may not be reached. hence a switch statement with a case for each step.

handling start/stop may need to be separate

you code start with just the movement actions

Sorry for the late reply. I attached a diagram below for reference.

Your Q1: How does "it" know when it has reached the leftmost side as well as has returned to it's initial position?
Basically, since reed switches are triggered via a magnetic field, I attached a magnet to the cart and the Cylinders. It acts as a means of triggering the reed inputs (A+, A-, B+, B-, LHS, RHS).

Your Q2: why "write" to an input pin?
This is a personal fuck-up. You're right; it doesn't make sense; I was probably sleepy when writing this. Basically, I was trying to block the FWD and REV buttons when I was in AUTO MODE since, according to the instructions, these buttons should only work during MANUAL MODE.

Your Q3: Does something like this need to be "paused" before it completes, or can it be allowed to be completed?
I should be able to pause at ANY POINT of the sequence (i.e., If I press STOP during Step 1, Step 2 should not continue unless I press START to resume the sequence.)

Your Q4: is there a need for that initial delay()?
It's within the given instruction that a 1-second delay is there so that Cylinder A (refer to attached PDF or PNG to see system illustration) is fully extended and able to reach the black box we are trying to pick up.

Your Q5: his looks like you're trying to set multiple pins to zero, need to set each pin individually
This is also a fuckup since I was again "writing" on inputs. This is my initial attempt at "PAUSING" the sequence. I guess another way to do it is by turning off Y1, Y2, or Vacc. So that the PnP sequence won't continue?

NOTE:

  • In both modes, their only significant difference is the means of controlling the conveyor.
  • Manual Mode requires you to hold either FWD/REV to bring the cart to LHS or RHS.
  • Auto mode however, only requires 1 press from START to bring it all the way to LHS.
  • Specific Conditions and Properties can be seen in my attached PDF.
  • what are these 6 "triggers", in particular why an A- and an A+? seems confusing that LHS, RHS and Bminus affect motors. LHS also affects y1Pin. In post #1 you say A/B+ extend and A/B- retract.
  • why do you need a 1 second delay before turning on the vacuum or extending Y1 but no a delay while extending Y1?
  • seems there a sequence:
  • LHS extends Y1
  • A+ turns on the vacuum and waits a moment for some object to be captured by the vacuum and retracts Y1
  • A- turns of Y1 and extends Y2
  • B+ turns off the vaccum, waits a moment for the object to be released and retracts Y2
  • B- turns off Y2
  • seems like some things are in motion. does pause mean temporarily stopping them and then resuming when un-paused? do you need to keep track of state as well as paused states?
  • when re-initializing the system, do you need to know what state it was in?

You were correct about the sequence here:

  • LHS extends Y1
  • A+ turns on the vacuum and waits a moment for some object to be captured by the vacuum and retracts Y1
  • A- turns of Y1 and extends Y2
  • B+ turns off the vacuum, waits a moment for the object to be released, and retracts Y2
  • B- turns off Y2

I've been reading about using hardware interrupts here (Using Arduino Interrupts - Hardware, Pin Change and Timer) to pause the main loop function. Once the interrupt function is done, it goes right back to the main loop function right before I left off. This is the most straightforward solution I found online.

However, I've read that the interrupt function should only be instantaneous, no delay() or millis() allowed, and it only travels sequentially once.

So, is there a way to stay within the interrupt function when I press STOP and only exit the interrupt if I press START? This way, I can pause whenever I want during the whole PnP sequence.

Your intention to achieve a certain functionality and to read about a lot of different things is honorable. But using interrupts in this way is the most unsuitable one.

An interrupt does what its name says: interrupting code-execution. This interruption through an interrupt occurs on the lowest level. This means totally regardless of which command your code is executing at the moment the code will be interrupted. For example creating vacuum is started but sucker did not touch the object. If additionally you would stop code-execution in this moment even sensing a button to resume would have to be duplicated to be done in your

"interrupt is active waiting for resume-button-press"

Very ugly way to create the wanted functionality.

One basic property of a state-machine is:

quickly jump in, quickly jump out
quickly jump in, quickly jump out
quickly jump in, quickly jump out
quickly jump in, quickly jump out

this makes a state-machine very responsive to whatever input ever

This means at a minimum it jumps in / jumps out 100 times per second
it s very likely that it will jump in jump out 1000 times or even more per second.

And this quickly jump in / jump out will enable to always check a pause and a resume button

This means you get the function of pausing / resuming from everywhere in your code regardless of what your machine is doing in this moment.

And additionally you will win the option to

  • depending on what your machine is doing in the moment the pause-button-press occurs -

to execute some quick additional steps before really pausing.
example switching off vacuum in case the sucker did not even start to move towards the object that shall be picked up

This is just an option. You don't have to.

And a state-machine will offer to memorise at what step the pausing occured and to continue after pressing the resume-button with exactly that step that shall hapen next
or
if you like to change with which step the machine shall continue

Once you have understood the concept of state-machine you never want to use something else again.

Another advantage of state-machines is that it minimizes the number of if-conditions to a minimum. This is caused through the

mutually exclusive code-execution that a state-machine offers

Every machine-control needs timing. There is a way for non-blocking timing that avoids all the disadvantages of delay() .

The combination of non-blocking timing combined with a
quickly jump in / quickly jump out
quickly jump in / quickly jump out
quickly jump in / quickly jump out
state-machine
offers all possabilities you are dreaming of
additionally it is very easy to maintain, to modify, to expand its functionalities.

Here is a demo-code that demonstrates how state-machines work

And here is a short tutorial that explains how non-blocking timing works

best regards Stefan

Thanks for the info; I'm still stuck on making Interrupt work. I get that it would fuck up my project if I pause at a crucial time

  • (i.e., I interrupted the part of the sequence when Vaccumm sucks an object, which may hinder the PnP sequence.)

A solution (I dunno if this is even possible) that I thought of is making some sort of counting mechanism inside the interrupt function. For example,

  1. I press STOP, which then calls the Interrupt Function (let's call it PAUSE in this case).
  2. Inside the PAUSE function, I will toggle the STOP button so that PAUSE will keep counting until a certain big number (i.e., 1000) is reached. *** I'm sort of cheating here since I'm just trying to create a long enough interval to make it seem that I am pausing the system.***
  3. I can only exit the function by pressing the START button, which would then finish the count, resetting it back to 0, and ultimately, finishing PAUSE, and going back to the main loop().

I am already thinking that this may not work since the "counting" function requires continuous inputs, and since PAUSE doesn't loop, it'll probably just do a "current count+1" when I press STOP and then go back to the main loop where I left off.....

My solution above would probably be my last attempt at using INTERRUPTS. If all else fails, I'll start reading on state machines.

that not how an interrupt should be used

it's a bit unclear what pause requires.

what should happen while Y1 is being extended waiting for A+? can it be stopped from extending, should it be retracted?

if the vacuum has been turned on, can it be left on during the pause period? if so, this requires writing the code such that instead of turning on the vacuum and waiting a moment before retracting Y1 being one step, it be 2 steps using a timer to trigger the retraction so that the retraction can be delayed.

the above suggests using a sequencer. here's a partial example


const byte PinAplus = 2;
const byte PinLhs   = 3;
const byte PinStart = 4;
const byte PinVac   = 5;
const byte PinY1    = 6;

unsigned long msecPeriod;
unsigned long msecLast;
unsigned long msec;

int  state;
bool paused;

enum { Off = LOW, On = HIGH };

// -----------------------------------------------------------------------------
void
sequencer (void)
{
    switch (state) {
    case 1:
        if (LOW == digitalRead (PinLhs))  {
            digitalWrite (PinY1, On);
            state++;
        }
        break;

    case 2:
        if (LOW == digitalRead (PinAplus)) {
            digitalWrite (PinVac, On);
            msecLast   = msec;
            msecPeriod = 1000;
            state++;
        }
        break;

    case 3:
        if (msec - msecLast >= msecPeriod)  {
            digitalWrite (PinY1, Off);
            state++;
        }
        break;

    // ...
    }
}

void
loop (void)
{
    msec = millis ();

    if (LOW == digitalRead (PinStart))   {
        // start button logic
    }

    if (! paused)
        sequencer ();
}

void
setup (void)
{
    Serial.begin (9600);
}
  • In this case, if I press STOP at the point when Y1 is extended, it remains extended and it shouldn't retract back.

Yes, that is correct; pausing at the point where the vacuum is turned on should leave it on.
/----------------------------------------------------------------------/

I'll try to understand your code for a bit here...

At this point, I'm guessing you're defining time intervals manually so as not to use delays() and stop the operation.

I don't know what this is, though. Did you make a function named "sequencer" and then put another void in the sequencer?

For this one, did you make a case where if LHS is LOW, you activate Y1? Also, what does "state++" mean? Move on to the next case, perhaps?

The main loop function is basically just sitting here waiting for me to pause the system. "If PinStart is LOW, then I would do nothing, so the system is paused." But if I'm not paused (!paused), I do whatever is being stated in the "sequencer()" function.

How accurate are my assumptions here???

yes. not using delay allows the pause to take effect immediately, before Y1 is extended after the vacuum is turned on

sorry, i'm in the habit of using void to indicate there is no argument. it could have been "()".

var++ is the same as var = var + 1. since state is 1 when this case is executed, it means case 2 will not be executed next time sequencer() is invoked

no. your requirements don't say the system only runs while the start button is pressed, does it?

i believe you need to recognize when the stop pin changes state, going LOW and pause the system (i.e. paused = true;). It would be un-paused when the start button is pressed.

and if the stop button is pressed (state change) again while paused, then isn't the system required to reset?

Yes, and yes, for both statements, you're correct. pressing STOP while it is paused should reset the entire system's initial state. I'll try using the switch state stuff you mentioned earlier; I'll get back to you once I do a little more editing. Thanks

Soo, I did a little something here:

// Define pin assignments for components
const int fwdButtonPin = 2;    // Pin for the forward button
const int revButtonPin = 3;    // Pin for the reverse button
const int lhsSwitchPin = 4;    // Pin for the left-hand side reed switch
const int rhsSwitchPin = 5;    // Pin for the right-hand side reed switch
const int motorRSPin = 6;      // Pin for the RS signal of the motor
const int motorLSPin = 7;      // Pin for the LS signal of the motor
const int y1Pin = 8;           // Pin for controlling Y1
const int aPlusPin = 9;        // Pin for the A+ reed switch
const int aMinusPin = 10;      // Pin for the A- reed switch
const int vacPin = A5;         // Pin for controlling the vacuum
const int y2Pin = 11;          // Pin for controlling Y2
const int bPlusPin = 12;       // Pin for the B+ reed switch
const int bMinusPin = 13;      // Pin for the B- reed switch
const int startButtonPin = A4; // Pin for the START button
const int stopButtonPin = A3;  // Pin for the Stop button
const int AMswitch = A2;	   // Pin for the A/M Switch

unsigned long msecPeriod;
unsigned long msecLast;
unsigned long msec;
bool paused;

int State;
enum State {Step1, Step2, Step3, Step4, Step5, Step6, Step7};
State currentState;

void setup() 
{
	// Initialize INPUT & OUTPUT pins
	pinMode(AMswitch, INPUT);
	pinMode(fwdButtonPin, INPUT);
	pinMode(revButtonPin, INPUT);
	pinMode(lhsSwitchPin, INPUT);
	pinMode(rhsSwitchPin, INPUT);
	pinMode(aPlusPin, INPUT);
	pinMode(aMinusPin, INPUT);
	pinMode(bPlusPin, INPUT);
	pinMode(bMinusPin, INPUT);
	pinMode(startButtonPin, INPUT);
	pinMode(stopButtonPin, INPUT);
	
	pinMode(motorRSPin, OUTPUT);
	pinMode(motorLSPin, OUTPUT);
	pinMode(y1Pin, OUTPUT);
	pinMode(y2Pin, OUTPUT);
	pinMode(vacPin, OUTPUT);

	// Initial State for motor control
	digitalWrite(motorRSPin, LOW);
	digitalWrite(motorLSPin, LOW);
	digitalWrite(y1Pin, LOW);
	digitalWrite(vacPin, LOW);
	digitalWrite(y2Pin, LOW);
	
  	// currentState is at Step1 initially
  	currentState = Step1;
  
	// Serial communication for debugging (optional)
	Serial.begin(9600);
  
   
}

void loop() 
{  
  	//Record Arduino Runtime
	unsigned long msec = millis();
  
	// Define AM switch State (Manual=1, Auto=0)
	int AM = digitalRead(AMswitch);

	// Check the State of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);
	
	// Choose the mode based on the State of AM
	// We can only call Auto or Manual Mode as long as Stop is not pressed...
	if (AM == HIGH && Stop == LOW) {
		AutoMode(); // Call the function for Automatic Mode
	} else if (AM == LOW && Stop == LOW) {
		ManualMode(); // Call the function for Manual Mode
	}
	
	if (!paused||Stop == HIGH){
      	Serial.println("System is Paused");	
	// If Stop button is activated, void loop function will do nothing
	}

	// Add a small delay to prevent rapid State changes
	delay(500);

	// Print State for debugging (optional)
	Serial.print(" Mode: "); Serial.print(AM);
	Serial.print(" |Inputs:");
	Serial.print(Aplus);
	Serial.print(Aminus);
	Serial.print(Bplus);
	Serial.println(Bminus);
 	delay(100);
}

void AutoMode() // Commands for Automatic Mode (AM == 1)
{
	// Check the State of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);
	
	
	// If START is pressed, move the car automatically to the LHS
		if (Start == HIGH) {
		digitalWrite(motorRSPin, LOW);
		digitalWrite(motorLSPin, HIGH);
		}
	
	// If Stop is pressed, pause the system
		if (Stop == HIGH || LHS == HIGH || RHS == HIGH) {
		digitalWrite(motorRSPin, LOW);
		digitalWrite(motorLSPin, LOW);
		} 
		
	/*-----Pick-and-Place Sequence based on the States of switches-----*/
	switch (currentState){
	case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
		if (LHS == HIGH) {
		digitalWrite(y1Pin, HIGH);
		msecLast   = msec;
        msecPeriod = 1000;
		currentState++;
		} 
		break;
	
	case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
	 	if (Aplus == HIGH && msec - msecLast >= msecPeriod) {
		digitalWrite(vacPin, HIGH);
		msecLast   = msec;
        msecPeriod = 2000;
		currentState++;
		} 
		break;
	
	case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
		if (msec - msecLast >= msecPeriod) {
		digitalWrite(y1Pin,LOW);
		currentState++;
		}
		break; 
	
	case Step4:// Step 4: If A- is activate, Cylinder B (Y2) will swing
		if (Aminus == HIGH){
		digitalWrite(y2Pin,HIGH);
		currentState++;
		} 
		break;
		
	case Step5://Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
		if (Bplus == HIGH) {
		digitalWrite(vacPin, LOW);
		msecLast   = msec;
        msecPeriod = 1000;
		currentState++;
		} 	
		break;
		
	case Step6:// Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to initial position
		if (msec - msecLast >= msecPeriod) {
		digitalWrite(y2Pin, LOW);
		currentState++;
		}
		break;
	
	case Step7: // Step 7: ONLY FOR AUTO MODE, we also have to bring back cart to initial position (RHS)
		if (Bminus == HIGH) {
		digitalWrite(motorRSPin, HIGH);
		digitalWrite(motorLSPin, LOW);
		}
		break;
	}
	//END Auto Sequence
}

void ManualMode() // Commands for Automatic Mode (AM == 0)
{
	// Check the State of buttons and reed switches
	int FWD = digitalRead(fwdButtonPin); 
	int REV = digitalRead(revButtonPin); 
	int LHS = digitalRead(lhsSwitchPin);
	int RHS = digitalRead(rhsSwitchPin); 
	int Start = digitalRead(startButtonPin);
	int Stop = digitalRead(stopButtonPin); 
	int Aplus = digitalRead(aPlusPin);
	int Aminus = digitalRead(aMinusPin); 
	int Bplus = digitalRead(bPlusPin);
	int Bminus = digitalRead(bMinusPin);
	
	//Record Arduino Runtime
	msec = millis();
	
	/*-----Pick-and-Place Sequence based on the States of switches-----*/
	switch (currentState)
	{
	case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
		if (LHS == HIGH) {
		digitalWrite(y1Pin, HIGH);
		msecLast   = msec;
        msecPeriod = 1000;
		currentState++;
		} 
		break;
	
	case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
	 	if (Aplus == HIGH && msec - msecLast >= msecPeriod) {
		digitalWrite(vacPin, HIGH);
		msecLast   = msec;
        msecPeriod = 2000;
		currentState++;
		} 
		break;
	
	case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
		if (msec - msecLast >= msecPeriod) {
		digitalWrite(y1Pin,LOW);
		currentState++;
		}
		break; 
	
	case Step4:// Step 4: If A- is activate, Cylinder B (Y2) will swing
		if (Aminus == HIGH){
		digitalWrite(y2Pin,HIGH);
		currentState++;
		} 
		break;
		
	case Step5://Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
		if (Bplus == HIGH) {
		digitalWrite(vacPin, LOW);
		msecLast   = msec;
        msecPeriod = 1000;
		currentState++;
		} 	
		break;
		
	case Step6:// Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to initial position
		if (msec - msecLast >= msecPeriod) {
		digitalWrite(y2Pin, LOW);
		}
		break;
	}
	//END Manual Sequence
}


I tried practicing with State-Machines, and here is my attempt on it for my project. What do think about the changes? I removed all the delays here but still followed the necessary intervals according to the instructions.

According to my simulations: It seems that using "currentState++" doesn't really work due to how I defined my "enum" in the global variable. So I made a few changes now where instead of using currentState++, I manually told the function to move on to the next step (i.e., currentState = Step1,2,3,...)

// Define pin assignments for components
const int fwdButtonPin = 2;    // Pin for the forward button
const int revButtonPin = 3;    // Pin for the reverse button
const int lhsSwitchPin = 4;    // Pin for the left-hand side reed switch
const int rhsSwitchPin = 5;    // Pin for the right-hand side reed switch
const int motorRSPin = 6;      // Pin for the RS signal of the motor
const int motorLSPin = 7;      // Pin for the LS signal of the motor
const int y1Pin = 8;           // Pin for controlling Y1
const int aPlusPin = 9;        // Pin for the A+ reed switch
const int aMinusPin = 10;      // Pin for the A- reed switch
const int vacPin = A5;         // Pin for controlling the vacuum
const int y2Pin = 11;          // Pin for controlling Y2
const int bPlusPin = 12;       // Pin for the B+ reed switch
const int bMinusPin = 13;      // Pin for the B- reed switch
const int startButtonPin = A4; // Pin for the START button
const int stopButtonPin = A3;  // Pin for the Stop button
const int AMswitch = A2;	   // Pin for the A/M Switch

unsigned long msecPeriod;
unsigned long msecLast;
unsigned long msec;
bool paused;

enum State { Step1, Step2, Step3, Step4, Step5, Step6, Step7 };
State currentState = Step1;

void setup()
{
    // Initialize INPUT & OUTPUT pins
    pinMode(AMswitch, INPUT);
    pinMode(fwdButtonPin, INPUT);
    pinMode(revButtonPin, INPUT);
    pinMode(lhsSwitchPin, INPUT);
    pinMode(rhsSwitchPin, INPUT);
    pinMode(aPlusPin, INPUT);
    pinMode(aMinusPin, INPUT);
    pinMode(bPlusPin, INPUT);
    pinMode(bMinusPin, INPUT);
    pinMode(startButtonPin, INPUT);
    pinMode(stopButtonPin, INPUT);

    pinMode(motorRSPin, OUTPUT);
    pinMode(motorLSPin, OUTPUT);
    pinMode(y1Pin, OUTPUT);
    pinMode(y2Pin, OUTPUT);
    pinMode(vacPin, OUTPUT);

    // Initial State for motor control
    digitalWrite(motorRSPin, LOW);
    digitalWrite(motorLSPin, LOW);
    digitalWrite(y1Pin, LOW);
    digitalWrite(vacPin, LOW);
    digitalWrite(y2Pin, LOW);

    // Serial communication for debugging (optional)
    Serial.begin(9600);
}

void loop()
{
    // Record Arduino Runtime
    msec = millis();

    // Define AM switch State (Manual=1, Auto=0)
    int AM = digitalRead(AMswitch);

    // Check the State of buttons and reed switches
    int FWD = digitalRead(fwdButtonPin);
    int REV = digitalRead(revButtonPin);
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);

    // Choose the mode based on the State of AM
    // We can only call Auto or Manual Mode as long as Stop is not pressed...
    if (AM == HIGH)
    {
        AutoMode(); // Call the function for Automatic Mode
    }
    else if (AM == LOW)
    {
        ManualMode(); // Call the function for Manual Mode
    }

    if (Stop == HIGH)
    {
        Serial.println("System is Paused");
        paused = true;
        // If Stop button is activated, void loop function will do nothing
    }

    // Add a small delay to prevent rapid State changes
    delay(500);

    // Print State for debugging (optional)
    Serial.print(" Mode: ");
    Serial.print(AM);
    Serial.print(" |Inputs:");
    Serial.print(Aplus);
    Serial.print(Aminus);
    Serial.print(Bplus);
    Serial.println(Bminus);
    delay(100);
}

void AutoMode() // Commands for Automatic Mode (AM == 1)
{
    // Check the State of buttons and reed switches
    int FWD = digitalRead(fwdButtonPin);
    int REV = digitalRead(revButtonPin);
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);

    // If START is pressed, move the car automatically to the LHS
    if (Start == HIGH)
    {
        digitalWrite(motorRSPin, LOW);
        digitalWrite(motorLSPin, HIGH);
    }

    // If Stop is pressed, pause the system
    if (Stop == HIGH || LHS == HIGH || RHS == HIGH)
    {
        digitalWrite(motorRSPin, LOW);
        digitalWrite(motorLSPin, LOW);
    }

    /*-----Pick-and-Place Sequence based on the States of switches-----*/
    switch (currentState)
    {
    case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
        if (LHS == HIGH)
        {
            digitalWrite(y1Pin, HIGH);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step2;
        }
        break;

    case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
        if (Aplus == HIGH && msec - msecLast >= msecPeriod)
        {
            digitalWrite(vacPin, HIGH);
            msecLast = msec;
            msecPeriod = 2000;
            currentState = Step3;
        }
        break;

    case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
        if (msec - msecLast >= msecPeriod)
        {
            digitalWrite(y1Pin, LOW);
            currentState = Step4;
        }
        break;

    case Step4: // Step 4: If A- is activate, Cylinder B (Y2) will swing
        if (Aminus == HIGH)
        {
            digitalWrite(y2Pin, HIGH);
            currentState = Step5;
        }
        break;

    case Step5: // Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
        if (Bplus == HIGH)
        {
            digitalWrite(vacPin, LOW);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step6;
        }
        break;

    case Step6: // Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to the initial position
        if (msec - msecLast >= msecPeriod)
        {
            digitalWrite(y2Pin, LOW);
            currentState = Step7;
        }
        break;

    case Step7: // Step 7: ONLY FOR AUTO MODE, we also have to bring back the cart to the initial position (RHS)
        if (Bminus == HIGH)
        {
            digitalWrite(motorRSPin, HIGH);
            digitalWrite(motorLSPin, LOW);
        }
        break;
    }
    // END Auto Sequence
}

void ManualMode() // Commands for Automatic Mode (AM == 0)
{
    // Check the State of buttons and reed switches
    int FWD = digitalRead(fwdButtonPin);
    int REV = digitalRead(revButtonPin);
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);

    // Record Arduino Runtime
    msec = millis();

    /*-----Pick-and-Place Sequence based on the States of switches-----*/
    switch (currentState)
    {
    case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
        if (LHS == HIGH)
        {
            digitalWrite(y1Pin, HIGH);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step2;
        }
        break;

    case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
        if (Aplus == HIGH && msec - msecLast >= msecPeriod)
        {
            digitalWrite(vacPin, HIGH);
            msecLast = msec;
            msecPeriod = 2000;
            currentState = Step3;
        }
        break;

    case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
        if (msec - msecLast >= msecPeriod)
        {
            digitalWrite(y1Pin, LOW);
            currentState = Step4;
        }
        break;

    case Step4: // Step 4: If A- is activate, Cylinder B (Y2) will swing
        if (Aminus == HIGH)
        {
            digitalWrite(y2Pin, HIGH);
            currentState = Step5;
        }
        break;

    case Step5: // Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
        if (Bplus == HIGH)
        {
            digitalWrite(vacPin, LOW);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step6;
        }
        break;

    case Step6: // Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to the initial position
        if (msec - msecLast >= msecPeriod)
        {
            digitalWrite(y2Pin, LOW);
        }
        break;
    }
    // END Manual Sequence
}

Hmmm, should I add a "!paused" condition in each "if-statements" to have a pausing mechanism? I also plan on creating another if-statement in the main loop function:

// Check if the system is paused
    if (paused) {
        // Check if the Start button is pressed to resume
        if (Start == HIGH) {
            paused = false;  // Resume the system
            Serial.println("System Resumed");
        } else {
            Serial.println("System Paused");
            return;  // If not resumed, exit AutoMode
        }
    }

So that the Start Button would continue the sequence?

the sequencer (type of state machine) looks right. do you think so?

but start and stop button presses need to be recognized, not just that they are being pressed. recognize a change in state, that it's different than the last time AND add a 20 msec delay to ignore "bounce".

recognizing that stop is pressed pauses the system. recognizing a stop while paused resets it. recognizing that start is pressed when paused un-pauses it.

and buttons are typically connected between the pin and ground, the pin configured as INPUT_PULLUP to use the internal pullup resistor which pulls the pin HIGH and when pressed, the button pulls the pin LOW.

a button press can be recognized by detecting a change in state and becoming LOW

Yoww, I think I did it...

// Define pin assignments for components
const int fwdButtonPin = 2;    // Pin for the forward button
const int revButtonPin = 3;    // Pin for the reverse button
const int lhsSwitchPin = 4;    // Pin for the left-hand side reed switch
const int rhsSwitchPin = 5;    // Pin for the right-hand side reed switch
const int motorRSPin = 6;      // Pin for the RS signal of the motor
const int motorLSPin = 7;      // Pin for the LS signal of the motor
const int y1Pin = 8;           // Pin for controlling Y1
const int aPlusPin = 9;        // Pin for the A+ reed switch
const int aMinusPin = 10;      // Pin for the A- reed switch
const int vacPin = A5;         // Pin for controlling the vacuum
const int y2Pin = 11;          // Pin for controlling Y2
const int bPlusPin = 12;       // Pin for the B+ reed switch
const int bMinusPin = 13;      // Pin for the B- reed switch
const int startButtonPin = A4; // Pin for the START button
const int stopButtonPin = A3;  // Pin for the Stop button
const int AMswitch = A2;	   // Pin for the A/M Switch

unsigned long msecPeriod;
unsigned long msecLast;
unsigned long msec;
bool paused;

enum State { Step1, Step2, Step3, Step4, Step5, Step6, Step7 };
State currentState = Step1;

int stopButtonPressCount = 0;  // Counter for the number of times Stop button is pressed
int previousAMState = LOW;  // Variable to store the previous state of AM

void setup()
{
    // Initialize INPUT & OUTPUT pins
    pinMode(AMswitch, INPUT);
    pinMode(fwdButtonPin, INPUT);
    pinMode(revButtonPin, INPUT);
    pinMode(lhsSwitchPin, INPUT);
    pinMode(rhsSwitchPin, INPUT);
    pinMode(aPlusPin, INPUT);
    pinMode(aMinusPin, INPUT);
    pinMode(bPlusPin, INPUT);
    pinMode(bMinusPin, INPUT);
    pinMode(startButtonPin, INPUT);
    pinMode(stopButtonPin, INPUT);

    pinMode(motorRSPin, OUTPUT);
    pinMode(motorLSPin, OUTPUT);
    pinMode(y1Pin, OUTPUT);
    pinMode(y2Pin, OUTPUT);
    pinMode(vacPin, OUTPUT);

    // Initial State for motor control
    digitalWrite(motorRSPin, LOW);
    digitalWrite(motorLSPin, LOW);
    digitalWrite(y1Pin, LOW);
    digitalWrite(vacPin, LOW);
    digitalWrite(y2Pin, LOW);

    // Serial communication for debugging (optional)
    Serial.begin(9600);
}

void loop()
{
    // Record Arduino Runtime
    msec = millis();

    // Define AM switch State (Manual=1, Auto=0)
    int AM = digitalRead(AMswitch);

    // Check the State of buttons and reed switches
    int FWD = digitalRead(fwdButtonPin);
    int REV = digitalRead(revButtonPin);
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);

    // Choose the mode based on the State of AM
    // We can only call Auto or Manual Mode as long as Stop is not pressed...
    if (AM == HIGH)
    {
        AutoMode(); // Call the function for Automatic Mode
    }
    else if (AM == LOW)
    {
        ManualMode(); // Call the function for Manual Mode
    }

    if (Stop == HIGH)
    {
        paused = true;
        // If Stop button is activated, void loop function will do nothing
    }
 	
  	//Press STOP 2x = System Reset
  	if (Stop == HIGH) {
        if (!paused) {
            // First press of the Stop button
            paused = true;
            Serial.println("System Paused");
        } else {
            // Second press of the Stop button
            stopButtonPressCount++;
            if (stopButtonPressCount >= 2) {
                // Reset everything
                stopButtonPressCount = 0;
                paused = false;
                currentState = Step1;  // Reset to the initial state
                digitalWrite(motorRSPin, HIGH);
                digitalWrite(motorLSPin, LOW);
                digitalWrite(y1Pin, LOW);
                digitalWrite(y2Pin, LOW);
                digitalWrite(vacPin, LOW);
                Serial.println("System Reset");
            }
        }
    }
  
  	//Switch From Manual to Auto = System Reset
    if (AM == HIGH && previousAMState == LOW) {
        // Reset everything
        stopButtonPressCount = 0;
        paused = false;
        currentState = Step1;  // Reset to the initial state
        Serial.println("System Reset due to AM change");
      	digitalWrite(motorRSPin, HIGH);
        digitalWrite(motorLSPin, LOW);
      	digitalWrite(y1Pin, LOW);
        digitalWrite(y2Pin, LOW);
      	digitalWrite(vacPin, LOW);
    }
  	previousAMState = AM;

    // Print State for debugging (optional)
    Serial.print(" Mode: ");
    Serial.print(AM);
    Serial.print(" |Inputs:");
    Serial.print(Aplus);
    Serial.print(Aminus);
    Serial.print(Bplus);
    Serial.println(Bminus);
    delay(500);
}

void AutoMode() // Commands for Automatic Mode (AM == 1)
{
    // Check the State of buttons and reed switches
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);

    if (paused) {
        // Check if the Start button is pressed to resume
        if (Start == HIGH) {
            paused = false;  // Resume the system
            Serial.println("System Resumed");
        } else {
            Serial.println("System Paused");
            return;  // If not resumed, exit AutoMode
        }
    }
    // If START is pressed, move the car automatically to the LHS
    if (Start == HIGH)
    {
        digitalWrite(motorRSPin, LOW);
        digitalWrite(motorLSPin, HIGH);
    }

    // If Stop is pressed, pause the system, also add safety feature (LHS=RHS=1=Stop)
    if (Stop == HIGH || LHS == HIGH || RHS == HIGH)
    {
        digitalWrite(motorRSPin, LOW);
        digitalWrite(motorLSPin, LOW);
    }

    /*-----Pick-and-Place Sequence based on the States of switches-----*/
    switch (currentState)
    {
    case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
        if (!paused && LHS == HIGH)
        {
            digitalWrite(y1Pin, HIGH);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step2;
        }
        break;

    case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
        if (!paused && Aplus == HIGH && msec - msecLast >= msecPeriod)
        {
            digitalWrite(vacPin, HIGH);
            msecLast = msec;
            msecPeriod = 2000;
            currentState = Step3;
        }
        break;

    case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
        if (!paused && msec - msecLast >= msecPeriod)
        {
            digitalWrite(y1Pin, LOW);
            currentState = Step4;
        }
        break;

    case Step4: // Step 4: If A- is activate, Cylinder B (Y2) will swing
        if (!paused && Aminus == HIGH)
        {
            digitalWrite(y2Pin, HIGH);
            currentState = Step5;
        }
        break;

    case Step5: // Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
        if (!paused && Bplus == HIGH)
        {
            digitalWrite(vacPin, LOW);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step6;
        }
        break;

    case Step6: // Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to the initial position
        if (!paused && msec - msecLast >= msecPeriod)
        {
            digitalWrite(y2Pin, LOW);
            currentState = Step7;
        }
        break;

    case Step7: // Step 7: ONLY FOR AUTO MODE, we also have to bring back the cart to the initial position (RHS)
        if (!paused && Bminus == HIGH)
        {
            digitalWrite(motorRSPin, HIGH);
            digitalWrite(motorLSPin, LOW);
        }
        break;
    }
    // END Auto Sequence
}

void ManualMode() // Commands for Automatic Mode (AM == 0)
{
    // Check the State of buttons and reed switches
    int FWD = digitalRead(fwdButtonPin);
    int REV = digitalRead(revButtonPin);
    int LHS = digitalRead(lhsSwitchPin);
    int RHS = digitalRead(rhsSwitchPin);
    int Start = digitalRead(startButtonPin);
    int Stop = digitalRead(stopButtonPin);
    int Aplus = digitalRead(aPlusPin);
    int Aminus = digitalRead(aMinusPin);
    int Bplus = digitalRead(bPlusPin);
    int Bminus = digitalRead(bMinusPin);
  
  	// If RHS or LHS is activate, stop the motor
    if (LHS == HIGH || RHS == HIGH)
    {
        digitalWrite(motorRSPin, LOW);
        digitalWrite(motorLSPin, LOW);
    }
  
    if (paused) {
        // Check if the Start button is pressed to resume
        if (Start == HIGH) {
            paused = false;  // Resume the system
            Serial.println("System Resumed");
        } else {
            Serial.println("System Paused");
            return;  // If not resumed, exit AutoMode
        }
    }
  
    /*-----Pick-and-Place Sequence based on the States of switches-----*/
    switch (currentState)
    {
    case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
        if (!paused && LHS == HIGH)
        {
            digitalWrite(y1Pin, HIGH);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step2;
        }
        break;

    case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
        if (!paused && Aplus == HIGH && msec - msecLast >= msecPeriod)
        {
            digitalWrite(vacPin, HIGH);
            msecLast = msec;
            msecPeriod = 2000;
            currentState = Step3;
        }
        break;

    case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
        if (!paused && msec - msecLast >= msecPeriod)
        {
            digitalWrite(y1Pin, LOW);
            currentState = Step4;
        }
        break;

    case Step4: // Step 4: If A- is activate, Cylinder B (Y2) will swing
        if (!paused && Aminus == HIGH)
        {
            digitalWrite(y2Pin, HIGH);
            currentState = Step5;
        }
        break;

    case Step5: // Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
        if (!paused && Bplus == HIGH)
        {
            digitalWrite(vacPin, LOW);
            msecLast = msec;
            msecPeriod = 1000;
            currentState = Step6;
        }
        break;

    case Step6: // Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to the initial position
        if (!paused && msec - msecLast >= msecPeriod)
        {
            digitalWrite(y2Pin, LOW);
        }
        break;
    }
    // END Manual Sequence
}

Here's my complete code. I think I have already satisfied all the conditions mentioned in the PDF. I'd appreciate it if you could double-check it for me, though.

    case Step1: // Step 1: Cylinder A (Y1) Extends, hitting A+ reed switch. Vac turns on after 1s delay.
    case Step2: // Step 2: If A+ is triggered, Vac Turns HIGH and Stays on for 2s for stable grip
    case Step3: // Step 3: After 2s, we turn off Y1 to retract it and hit A- reed switch
    case Step4: // Step 4: If A- is activate, Cylinder B (Y2) will swing
    case Step5: // Step 5: If Y2 has fully rotated, it will hit B+ and turn off Vac to drop object
    case Step6: // Step 6: After Vac is turned off, we'll wait 1s before Y2 swings back to the initial position
    case Step7: // Step 7: ONLY FOR AUTO MODE, we also have to bring back the cart to the initial position (RHS)

You should give each "step" a self-explaining name for two reasons:

if you yourself want to modify your code in 3 months it will take you much less time to understand your own code

if you want support from the forum all users (= your potential helpers) will understand your code much easier

adding comments is no longer nescessary because the name explains itself