Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********* Pleasedontcode.com **********
- Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- - Terms and Conditions:
- You have a non-exclusive, revocable, worldwide, royalty-free license
- for personal and commercial use. Attribution is optional; modifications
- are allowed, but you're responsible for code maintenance. We're not
- liable for any loss or damage. For full terms,
- please visit pleasedontcode.com/termsandconditions.
- - Project: Dual-Mode Control
- - Source Code NOT compiled for: Arduino Mega
- - Source Code created on: 2025-09-27 14:44:33
- ********* Pleasedontcode.com **********/
- /****** SYSTEM REQUIREMENTS *****/
- /****** SYSTEM REQUIREMENT 1 *****/
- /* help refine the code. want to run the code */
- /* smoothly both in auto mode and manual mode. */
- /****** END SYSTEM REQUIREMENTS *****/
- /* START CODE */
- /****** DEFINITION OF LIBRARIES *****/
- /****** FUNCTION PROTOTYPES *****/
- void setup(void);
- void loop(void);
- // Merged content from USER CODE, adapted to fit the PRELIMINARY CODE structure for Arduino Mega
- //Last Updated 12092025
- // Define stepper motor1 of Linear guide @ Spinning Motor driver pins
- const int DRIVER1_DIR = 28; // Direction pin for stepper motor1
- const int DRIVER1_STEP = 18; // Step pin for stepper motor1
- const int DRIVER1_ENA = 29; // Enable pin for stepper motor1
- // Define stepper motor2 of Linear guide @ Feeder Motor driver pins
- const int DRIVER2_DIR = 30; // Direction pin for stepper motor2
- const int DRIVER2_STEP = 6; // Step pin for stepper motor2
- const int DRIVER2_ENA = 31; // Enable pin for stepper motor2
- // Proximity Sensor for Induction Motor CW and CCW
- const int PROXY_POS = 10; // Proxy POS Sensor for Linear Motor Position
- const int PROXY_A = 11; // Proxy A Sensor for CW
- const int PROXY_B = 12; // Proxy B Sensor for CCW
- // const int PROXY_RUNFEED = 13; // Proxy Feed Run Sensor
- // Define BTS7960B motor driver pins for Feeder motor
- const int EN_FEEDER = 20; // Enable pin for feeder motor
- const int LPWM_FEEDER = 3; // Left PWM pin for feeder motor
- const int RPWM_FEEDER = 4; // Right PWM pin for feeder motor
- // Define Limit switchs of Linear drive @ Spinning motor
- const int LIMIT_SWITCH1 = 15; // 32; // Limit switch 1 pin (Bottom)
- const int LIMIT_SWITCH2 = 33; // Limit switch 2 pin (Up)
- // Define Limit switchs of Linear drive @ Feeder motor
- const int LIMIT_SWITCH3 = 35; // Limit switch 3 pin (Reverse)
- const int LIMIT_SWITCH4 = 16; // Limit switch 4 pin (Forward)
- // Define relay pins
- const int RELAY1 = A0; // Relay for
- const int RELAY2 = A1; // Relay for Air-Nipper Cutter
- const int RELAY3 = A12; // Relay for Gripper 1
- const int RELAY4 = A3; // Relay for Gripper 2
- const int RELAY5 = A4; // Relay for CW direction
- const int RELAY6 = A5; // Relay for CCW direction
- const int RELAY7 = A6; // Relay for Feeder Linear Drive
- const int RELAY8 = A7; // Relay for Label Vaccum pad Forward/Backward
- const int RELAY9 = 43; // Relay for Spinning Linear Drive
- const int RELAY10 = 45; // Relay for Cutter-up & Cutter-down Cylinder
- const int RELAY11 = 46; // Relay for
- const int RELAY12 = 47; // Relay for
- const int RELAY13 = 48; // Relay for
- const int RELAY14 = 49; // Relay for
- const int RELAY15 = 50; // Relay for
- const int RELAY16 = 51; // Relay for
- // Flags and variables
- bool autoMode = false; // Flag for Auto Mode
- bool manualMode = false; // Flag for Manual Mode
- int numCycles = 0; // Variable to store number of cycles
- bool feederRunning = false; // Flag to indicate if the feeder is running
- bool isForward = false;
- int targetCounts = 0; // Stores the required counts for current operation
- volatile int countA = 0; // Count for Proxy A
- volatile int countB = 0; // Count for Proxy B
- bool motorRunning = false; // Flag to indicate if the motor is currently running
- bool countingEnabled = false; // Flag to enable counting based on relay state
- bool isClockwise = false; // Global variable to track motor direction
- bool countProxyAEnabled = true; // Flag to enable/disable counting for Proxy A
- bool countProxyBEnabled = true; // Flag to enable/disable counting for Proxy B
- bool countProxyPOSEnabled = true; // Flag to enable/disable counting for Proxy POS
- volatile bool isMoving1 = false; // Flag to indicate if the linear guide is currently moving
- volatile bool isMoving2 = false; // Flag to indicate if the linear guide is currently moving
- unsigned long feederStartTime = 0; // When feeder started
- unsigned long feederDuration = 0; // How long to run (ms)
- bool linearGuide1Complete = false;
- bool linearGuide2Complete = false;
- bool feederComplete = false;
- bool motorComplete = false;
- // Command enumeration
- enum Command { START, STOP, G1, G2, G3, G4, VC, VO, VF, VR, PU, PD, OG, CW, CCW, LU, LD, LF, LR, CU, CD, CX, X, FD, RD, AUTO, MANUAL, NONE, UNKNOWN };
- // Debounce variables
- const unsigned long DEBOUNCE_TIME = 1000; // 1 second debounce time
- unsigned long lastCommandTime = 0; // Variable to store the last command execution time
- // Auto mode state machine variables
- enum AutoState { AUTO_IDLE, AUTO_CHECK_POS, AUTO_LU, AUTO_LF, AUTO_VF, AUTO_FD, AUTO_G3, AUTO_LR, AUTO_G1, AUTO_CU, AUTO_CX, AUTO_CD, AUTO_LD, AUTO_VR, AUTO_CW, AUTO_CCW, AUTO_OG, AUTO_COMPLETE, AUTO_CW_RUNNING, AUTO_CCW_RUNNING, AUTO_STOPPED };
- AutoState autoState = AUTO_IDLE;
- int currentCycle = 0;
- unsigned long autoStepStartTime = 0;
- const unsigned long STEP_DELAY = 100; // 100ms delay between steps
- // Completion check functions
- bool isLinearGuide1Complete() { return linearGuide1Complete; }
- bool isLinearGuide2Complete() { return linearGuide2Complete; }
- bool isFeederComplete() { return feederComplete; }
- bool isMotorComplete() { return motorComplete; }
- // Function declarations
- void stopMotor(); // To Stop Linear Motor, Feeder Motor, Spinning Motor
- void moveLinearGuide1(String direction); // To move Linear UP and Down
- void moveLinearGuide2(String direction); // To move Linear Right and Left
- void moveStepper1(bool direction, int stopPin); // To Execute Linear & Spinning in sequence
- void moveStepper2(bool direction, int stopPin); // To Execute Linear & Feeder in sequence
- void runFeeder(bool forward, unsigned long durationMillis = 0, int speed = 25); // To activte Feeder motor
- void setFeederMotorSpeed(int speed, bool forward);
- void runOpenGripper(); // To deactivate Gripper Relay 3 & 4
- void runMotor(bool clockwise); // Combined CW and CCW motor function
- void handleCommand(Command cmd); // To handle and execute Manual Input Command
- bool runAutoMode(int numCycles); // To execute Auto Input Command sequence
- void resetSerialBuffer(); // To reset Command line
- bool checkStopCommand(); // To check for STOP command during process
- void resetMode();
- void CutterSensor();
- void proxyA();
- void proxyB();
- // Subsystem wrappers to isolate auto/manual control (new)
- void Subsystem_AutoStart(int cycles) { // Initialize and start Auto mode for a fixed cycle count
- numCycles = cycles;
- autoMode = true;
- autoState = AUTO_IDLE;
- currentCycle = 0;
- Serial.print("Subsystem Auto Start: "); Serial.println(cycles);
- }
- void Subsystem_AutoTick() { updateAutoMode(); }
- void Subsystem_AutoStop() { stopAutoMode(); }
- void Subsystem_ManualActivate() { manualMode = true; resetMode(); Serial.println("Subsystem Manual Mode Activated"); }
- void Subsystem_ManualDeactivate() { manualMode = false; Serial.println("Subsystem Manual Mode Deactivated"); }
- bool Subsystem_AutoRunning() { return autoMode; }
- Command parseCommand(String command);
- Command currentMode = NONE;
- // Helper functions to set completion flags
- void setLinearGuide1Complete() {
- linearGuide1Complete = true;
- Serial.println("Linear Guide 1 operation complete");
- }
- void setLinearGuide2Complete() {
- linearGuide2Complete = true;
- Serial.println("Linear Guide 2 operation complete");
- }
- void setFeederComplete() {
- feederComplete = true;
- Serial.println("Feeder operation complete");
- }
- void setMotorComplete() {
- motorComplete = true;
- Serial.println("Motor operation complete");
- }
- void setup() {
- // Set pin modes for motors and relays
- pinMode(RPWM_FEEDER, OUTPUT);
- pinMode(LPWM_FEEDER, OUTPUT);
- pinMode(EN_FEEDER, OUTPUT);
- pinMode(PROXY_POS, INPUT_PULLUP); // Set proxy POS as input
- pinMode(PROXY_A, INPUT_PULLUP); // Set proxy A as input
- pinMode(PROXY_B, INPUT_PULLUP); // Set proxy B as input
- // pinMode(PROXY_RUNFEED, INPUT); // Set proxy Feed Run as input
- pinMode(RELAY1, OUTPUT);
- pinMode(RELAY2, OUTPUT);
- pinMode(RELAY3, OUTPUT);
- pinMode(RELAY4, OUTPUT);
- pinMode(RELAY5, OUTPUT);
- pinMode(RELAY6, OUTPUT);
- pinMode(RELAY7, OUTPUT);
- pinMode(RELAY8, OUTPUT);
- pinMode(RELAY9, OUTPUT);
- pinMode(RELAY10, OUTPUT);
- pinMode(RELAY11, OUTPUT);
- pinMode(RELAY12, OUTPUT);
- pinMode(RELAY13, OUTPUT);
- pinMode(RELAY14, OUTPUT);
- pinMode(RELAY15, OUTPUT);
- pinMode(RELAY16, OUTPUT);
- pinMode(LIMIT_SWITCH1, INPUT_PULLUP);
- pinMode(LIMIT_SWITCH2, INPUT_PULLUP);
- pinMode(LIMIT_SWITCH3, INPUT_PULLUP);
- pinMode(LIMIT_SWITCH4, INPUT_PULLUP);
- pinMode(DRIVER1_STEP, OUTPUT);
- pinMode(DRIVER1_DIR, OUTPUT);
- pinMode(DRIVER1_ENA, OUTPUT);
- pinMode(DRIVER2_STEP, OUTPUT);
- pinMode(DRIVER2_DIR, OUTPUT);
- pinMode(DRIVER2_ENA, OUTPUT);
- // Initialize relays to LOW (off state)
- digitalWrite(RELAY1, LOW);
- digitalWrite(RELAY2, LOW);
- digitalWrite(RELAY3, LOW);
- digitalWrite(RELAY4, LOW);
- digitalWrite(RELAY5, LOW);
- digitalWrite(RELAY6, LOW);
- digitalWrite(RELAY7, LOW);
- digitalWrite(RELAY8, LOW);
- digitalWrite(RELAY9, LOW);
- digitalWrite(RELAY10, LOW);
- digitalWrite(RELAY11, LOW);
- digitalWrite(RELAY12, LOW);
- digitalWrite(RELAY13, LOW);
- digitalWrite(RELAY14, LOW);
- digitalWrite(RELAY15, LOW);
- digitalWrite(RELAY16, LOW);
- digitalWrite(DRIVER1_ENA, LOW); // Enable stepper motor1
- digitalWrite(DRIVER2_ENA, LOW); // Enable stepper motor2
- Serial.begin(9600); // Start serial communication
- resetSerialBuffer(); // Clear serial buffer on startup
- }
- Command parseCommand(String command) {
- command.trim();
- // Parse incoming command strings and return corresponding Command enum
- if (command == "START") return START;
- if (command == "STOP") return STOP;
- if (command == "G1") return G1;
- if (command == "G2") return G2;
- if (command == "G3") return G3;
- if (command == "G4") return G4;
- if (command == "VC") return VC;
- if (command == "VO") return VO;
- if (command == "VF") return VF;
- if (command == "VR") return VR;
- if (command == "PU") return PU;
- if (command == "PD") return PD;
- if (command == "OG") return OG;
- if (command == "CW") return CW;
- if (command == "CCW") return CCW;
- if (command == "LU") return LU;
- if (command == "LD") return LD;
- if (command == "LF") return LF;
- if (command == "LR") return LR;
- if (command == "CU") return CU;
- if (command == "CD") return CD;
- if (command == "CX") return CX;
- if (command == "X") return X;
- if (command == "FD") return FD; // Forward command
- if (command == "RD") return RD; // Reverse command
- if (command == "AUTO") return AUTO; // Auto mode
- if (command == "MANUAL") return MANUAL; // Manual mode
- return UNKNOWN; // Return UNKNOWN if command is not recognized
- }
- void handleCommand(Command cmd) {
- // Handle commands based on the parsed Command enum
- switch (cmd) {
- case START:
- Serial.println("Process started.");
- break;
- case STOP:
- stopMotor();
- Serial.println("MOTORS STOPPED");
- break;
- case G1:
- digitalWrite(RELAY3, HIGH); // Activate RELAY3 for G1 Close
- Serial.println("RELAY3 ON");
- break;
- case G2:
- digitalWrite(RELAY3, LOW); // Deactivate RELAY3 for G2 Open
- Serial.println("RELAY3 OFF");
- break;
- case G3:
- digitalWrite(RELAY4, HIGH); // Activate RELAY4 for G2 Close
- Serial.println("RELAY4 ON");
- break;
- case G4:
- digitalWrite(RELAY4, LOW); // Deactivate RELAY4 for G2 Open
- Serial.println("RELAY4 OFF");
- break;
- case VC: // Removed as on 28082025
- digitalWrite(RELAY11, HIGH); // Activate RELAY10 for Vaccum pad Pick
- Serial.println("RELAY11 ON");
- break;
- case VO: // Removed as on 28082025
- digitalWrite(RELAY11, LOW); // Deactivate RELAY10 for Vaccum pad Eject
- Serial.println("RELAY11 OFF");
- break;
- case VF:
- digitalWrite(RELAY8, HIGH); // Activate RELAY8 for Vaccum pad Forward
- Serial.println("RELAY8 ON");
- break;
- case VR:
- digitalWrite(RELAY8, LOW); // Deactivate RELAY8 for Vaccum pad Reverse
- Serial.println("RELAY8 OFF");
- break;
- case PU:
- digitalWrite(RELAY11, HIGH); // Activate RELAY11 for Push Up Load
- Serial.println("RELAY11 ON");
- break;
- case PD:
- digitalWrite(RELAY11, LOW); // Deactivate RELAY11 for Push Down Load
- Serial.println("RELAY11 OFF");
- break;
- case OG:
- runOpenGripper();
- Serial.println("Gripper 1 & 2 OPEN...");
- break;
- case CW:
- runMotor(true);
- Serial.println("Starting CW motor...");
- break;
- case CCW:
- runMotor(false);
- Serial.println("Starting CCW motor...");
- break;
- case LU:
- moveLinearGuide1("LU");
- Serial.println("Linear Guide1 Moving Up");
- break;
- case LD:
- moveLinearGuide1("LD");
- Serial.println("Linear Guide1 Moving Down");
- break;
- case LF:
- moveLinearGuide2("LF");
- Serial.println("Linear Guide2 Moving Forward");
- break;
- case LR:
- moveLinearGuide2("LR");
- Serial.println("Linear Guide2 Moving Reverse");
- break;
- case CX:
- digitalWrite(RELAY2, HIGH);
- delay(1000);
- digitalWrite(RELAY2, LOW);
- Serial.println("Air-Nipper Cutter Operated.");
- break;
- case CU:
- digitalWrite(RELAY10, HIGH); // Activate RELAY10 for Cutter Up Load
- Serial.println("RELAY10 ON");
- break;
- case CD:
- digitalWrite(RELAY10, LOW); // Deactivate RELAY10 for Cutter Down Load
- Serial.println("RELAY10 OFF");
- break;
- case X:
- stopMotor();
- Serial.println(" All motors stopped.");
- break;
- case FD:
- runFeeder(true, 2150); // Move feeder forward
- Serial.println("Feeder moving forward.");
- break;
- case RD:
- runFeeder(false, 2150); // Move feeder reverse
- Serial.println("Feeder moving reverse.");
- break;
- case AUTO:
- if (!autoMode) { // Only prompt if not already in Auto mode
- resetMode(); // Reset mode before starting Auto Mode
- autoMode = true; // Set Auto mode flag
- autoState = AUTO_IDLE;
- currentCycle = 0;
- Serial.println("Auto mode activated.");
- // delay(2000);
- Serial.println("Please enter the number of cycles:");
- unsigned long startWaitTime = millis();
- while (millis() - startWaitTime < 10000) {
- if (Serial.available() > 0) {
- numCycles = Serial.parseInt();
- if (numCycles > 0) {
- Serial.print("Starting Auto Mode for " );
- Serial.print(numCycles);
- Serial.println(" cycles.");
- break;
- } else {
- Serial.println("Invalid input. Please entre a positive number:");
- }
- }
- }
- if (numCycles == 0) {
- Serial.println("Timeout! Auto mode cancelled.");
- autoMode = false;
- }
- }
- break;
- case MANUAL:
- if (!manualMode) { // Only prompt if not already in Manual mode
- resetMode(); // Reset mode before starting Manual Mode
- manualMode = true; // Set Manual mode flag
- Serial.println("Manual mode activated.");
- }
- break;
- default:
- Serial.println("UNKNOWN COMMAND");
- break;
- }
- }
- void loop() {
- // Process serial commands non-blockingly
- if (Serial.available() > 0) {
- String command = Serial.readStringUntil('\n');
- command.trim(); // Remove any trailing spaces or newlines
- Serial.flush(); // Clear buffer after reading
- Serial.println("Received: " + command); // Debugging
- // Check if enough time has passed since the last command
- if (millis() - lastCommandTime >= DEBOUNCE_TIME) {
- Command cmd = parseCommand(command);
- lastCommandTime = millis();
- if (cmd == STOP || cmd == X) {
- // Handle stop command immediately
- if (autoMode) {
- stopAutoMode();
- }
- handleCommand(cmd);
- } else if (cmd == AUTO) {
- handleCommand(cmd);
- } else if (cmd == MANUAL) {
- handleCommand(cmd);
- } else {
- // Handle other commands (START, STOP, Q, etc.)
- handleCommand(cmd);
- }
- // Clear serial buffer after mode changes or commands
- resetSerialBuffer();
- }
- }
- // If in Auto mode, run the auto sequence incrementally
- if (autoMode) {
- updateAutoMode();
- }
- // State monitoring (no more proxy function calls)
- updateFeeder();
- if (motorRunning) {
- if (isClockwise) { // Check if the motor is running CW
- proxyA(); // Check Proxy A
- }
- else { // Otherwise, it must be CCW
- proxyB(); // Check Proxy B
- }
- }
- }
- void updateAutoMode() {
- static unsigned long lastUpdateTime = 0;
- static bool firstTimeInState = true;
- unsigned long currentTime = millis();
- // Update at 100ms intervals for responsiveness
- if (currentTime - lastUpdateTime < 100) {
- return;
- }
- lastUpdateTime = currentTime;
- // Check for stop commands continuously
- if (checkStopCommand()) {
- stopAutoMode();
- return;
- }
- switch (autoState) {
- case AUTO_IDLE:
- if (firstTimeInState) {
- Serial.print("AUTO_IDLE - Starting cycle ");
- Serial.println(currentCycle + 1);
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- if (currentTime - autoStepStartTime > 500) {
- if (currentCycle < numCycles) {
- currentCycle++;
- Serial.print("Starting cycle ");
- Serial.println(currentCycle);
- autoState = AUTO_CHECK_POS;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- } else {
- autoState = AUTO_COMPLETE;
- }
- }
- break;
- case AUTO_CHECK_POS:
- if (firstTimeInState) {
- int sensorState = digitalRead(PROXY_POS);
- Serial.print("Proxy POS Sensor State: ");
- Serial.println(sensorState);
- if (sensorState == LOW) {
- Serial.println("Proxy POS not active! Cannot proceed.");
- autoState = AUTO_STOPPED;
- } else {
- Serial.println("Proxy POS active. Proceeding to LU...");
- autoState = AUTO_LU;
- firstTimeInState = true;
- }
- autoStepStartTime = currentTime;
- }
- break;
- case AUTO_LU:
- if (firstTimeInState) {
- linearGuide1Complete = false;
- moveLinearGuide1("LU");
- Serial.println("Executing LU command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- if (isLinearGuide1Complete()) {
- autoState = AUTO_LF;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- break;
- }
- // Timeout safety
- if (currentTime - autoStepStartTime > 15000) {
- Serial.println("LU operation timeout!");
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_LF:
- if (firstTimeInState) {
- linearGuide2Complete = false;
- moveLinearGuide2("LF");
- Serial.println("Executing LF command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- delay(1000);
- }
- if (isLinearGuide2Complete()) {
- autoState = AUTO_VF;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- break;
- }
- if (currentTime - autoStepStartTime > 15000) {
- Serial.println("LF operation timeout!");
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_VF:
- digitalWrite(RELAY8, HIGH);
- Serial.println("Executing VF command...");
- autoState = AUTO_FD;
- autoStepStartTime = currentTime;
- delay(1000);
- break;
- case AUTO_FD:
- if (firstTimeInState) {
- feederComplete = false;
- runFeeder(true, 2150);
- Serial.println("Executing FD command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- if (isFeederComplete()) {
- autoState = AUTO_G3;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- break;
- }
- if (currentTime - autoStepStartTime > 5000) {
- Serial.println("FD operation timeout!");
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_G3:
- digitalWrite(RELAY4, HIGH);
- Serial.println("Executing G3 command...");
- autoState = AUTO_LR;
- autoStepStartTime = currentTime;
- break;
- case AUTO_LR:
- if (firstTimeInState) {
- linearGuide2Complete = false;
- moveLinearGuide2("LR");
- Serial.println("Executing LR command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- if (isLinearGuide2Complete()) {
- autoState = AUTO_G1;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- break;
- }
- if (currentTime - autoStepStartTime > 15000) {
- Serial.println("LR operation timeout!");
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_G1:
- digitalWrite(RELAY3, HIGH);
- Serial.println("Executing G1 command...");
- autoState = AUTO_CU;
- autoStepStartTime = currentTime;
- delay(1000);
- break;
- case AUTO_CU:
- digitalWrite(RELAY10, HIGH);
- Serial.println("Executing CU command...");
- autoState = AUTO_CX;
- autoStepStartTime = currentTime;
- delay(1000);
- break;
- case AUTO_CX:
- digitalWrite(RELAY2, HIGH);
- Serial.println("Executing CX command...");
- autoState = AUTO_CD;
- autoStepStartTime = currentTime;
- delay(1000);
- break;
- case AUTO_CD:
- digitalWrite(RELAY2, LOW);
- digitalWrite(RELAY10, LOW);
- Serial.println("Executing CD command...");
- autoState = AUTO_LD;
- autoStepStartTime = currentTime;
- delay(1000);
- break;
- case AUTO_LD:
- if (firstTimeInState) {
- linearGuide1Complete = false;
- moveLinearGuide1("LD");
- Serial.println("Executing LD command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- if (isLinearGuide1Complete()) {
- autoState = AUTO_CW;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- break;
- }
- if (currentTime - autoStepStartTime > 15000) {
- Serial.println("LD operation timeout!");
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_CW:
- if (firstTimeInState) {
- motorComplete = false;
- runMotor(true);
- Serial.println("Executing CW command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- autoState = AUTO_CW_RUNNING; // Move to intermediate state
- }
- break;
- case AUTO_CW_RUNNING:
- // Check if motor has completed its operation
- if (isMotorComplete()) {
- Serial.println("CW operation completed.");
- autoState = AUTO_VR; // Move to next main state
- firstTimeInState = true;
- }
- // Timeout safety
- if (currentTime - autoStepStartTime > 30000) {
- Serial.println("CW operation timeout!");
- stopMotor();
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_VR:
- digitalWrite(RELAY8, LOW);
- Serial.println("Executing VR command...");
- autoState = AUTO_OG;
- autoStepStartTime = currentTime;
- break;
- case AUTO_OG:
- if (firstTimeInState) {
- runOpenGripper();
- Serial.println("Executing OG command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- }
- // Wait 3000ms for OG delay
- if (currentTime - autoStepStartTime >= 3000) {
- autoState = AUTO_CCW;
- firstTimeInState = true;
- autoStepStartTime = currentTime;
- }
- break;
- case AUTO_CCW:
- if (firstTimeInState) {
- motorComplete = false;
- runMotor(false); // Start CCW motor
- Serial.println("Executing CCW command...");
- firstTimeInState = false;
- autoStepStartTime = currentTime;
- autoState = AUTO_CCW_RUNNING; // Move to intermediate state
- }
- break;
- case AUTO_CCW_RUNNING:
- // Check if motor has completed its operation
- if (isMotorComplete()) {
- Serial.println("CCW operation completed.");
- // Move to whatever state comes after CCW, or back to IDLE
- autoState = AUTO_IDLE;
- firstTimeInState = true;
- }
- // Timeout safety
- if (currentTime - autoStepStartTime > 30000) {
- Serial.println("CCW operation timeout!");
- stopMotor();
- autoState = AUTO_STOPPED;
- }
- break;
- case AUTO_COMPLETE:
- Serial.println("Auto mode completed all cycles.");
- resetMode();
- autoMode = false;
- break;
- case AUTO_STOPPED:
- // Do nothing until reset
- default:
- break;
- }
- }
- void stopAutoMode() {
- // Stop all ongoing operations
- stopMotor();
- digitalWrite(RELAY2, LOW);
- digitalWrite(RELAY3, LOW);
- digitalWrite(RELAY4, LOW);
- digitalWrite(RELAY8, LOW);
- digitalWrite(RELAY9, LOW);
- digitalWrite(RELAY10, LOW);
- digitalWrite(DRIVER1_ENA, HIGH);
- digitalWrite(DRIVER2_ENA, HIGH);
- digitalWrite(EN_FEEDER, LOW);
- autoState = AUTO_STOPPED;
- Serial.println("Auto mode stopped by command.");
- }
- bool checkStopCommand() {
- while (Serial.available() > 0) {
- String command = Serial.readStringUntil('\n');
- command.trim();
- if (command == "STOP" || command == "X") {
- Serial.println("Stop command received: " + command);
- return true;
- }
- // Put the command back into the buffer for normal processing
- // for (int i = 0; i < command.length(); i++) {
- // Serial.print(command[i]);
- // }
- }
- return false;
- }
- void setFeederMotorSpeed(int speed, bool forward) {
- analogWrite(RPWM_FEEDER, forward ? map(speed, 0, 100, 0, 255) : 0);
- analogWrite(LPWM_FEEDER, forward ? 0 : map(speed, 0, 100, 0, 255));
- }
- void runFeeder(bool forward, unsigned long durationMillis, int speed) {
- feederComplete = false;
- if (feederRunning) {
- Serial.println("Feeder is already running.");
- return; // Return the current direction if already running
- }
- // Start the feeder motor
- setFeederMotorSpeed(speed, forward);
- digitalWrite(EN_FEEDER, HIGH); // Enable feeder motor
- delay (100);
- feederRunning = true; // set feeder running flag to true
- isForward = forward;
- // Set duration if provided (0 means run indefinitely)
- if (durationMillis > 0) {
- feederStartTime = millis();
- feederDuration = durationMillis;
- } else {
- feederDuration = 0; // Run until manually stopped
- }
- Serial.print(forward ? "FEEDER MOTOR FD STARTED" : "FEEDER MOTOR RD STARTED");
- if (durationMillis > 0) {
- Serial.print(" for ");
- Serial.print(durationMillis / 1000.0);
- Serial.println(" seconds");
- } else {
- Serial.println(" (indefinite run)");
- }
- }
- void updateFeeder() {
- if (feederRunning && feederDuration > 0 && (millis() - feederStartTime >= feederDuration)) {
- // Time's up - stop the motor
- digitalWrite(EN_FEEDER, LOW);
- stopMotor();
- feederRunning = false;
- Serial.println("Feeder motor stopped (time elapsed)");
- // SET COMPLETION FLAG HERE
- setFeederComplete();
- }
- }
- void moveLinearGuide1(String direction1) {
- linearGuide1Complete = false;
- if (direction1 == "LU") { // Forward Direction (Linear motor up)
- int sensorState = digitalRead(PROXY_POS);
- Serial.print("Proxy POS Sensor State: ");
- Serial.println(sensorState); // Print the actual state of the sensor
- // Check if proxyPOS is active
- if (sensorState == LOW) { // Assuming HIGH means the sensor is inactive
- Serial.println("Cannot move up. Proxy POS is not active.");
- return; // Exit the function if proxyPOS is not active
- }
- // Check if already at upper limit (like LF/LR does)
- if (digitalRead(LIMIT_SWITCH2) == LOW) {
- Serial.println("Already at Limit Switch 2");
- setLinearGuide1Complete(); // ADD THIS - was missing!
- return;
- }
- Serial.println("LU");
- digitalWrite(DRIVER1_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY9, HIGH); // Turn ON Relay 1
- Serial.println("RELAY9 ON"); // Notify Python
- delay(100);
- digitalWrite(DRIVER1_DIR, HIGH); // Set direction forward
- delay(100);
- digitalWrite(DRIVER1_ENA, LOW); // Enable motor
- delay(200);
- Serial.print("Limit States - 1: ");
- Serial.print(digitalRead(LIMIT_SWITCH1));
- Serial.print(" & Limit States - 2: ");
- Serial.println(digitalRead(LIMIT_SWITCH2));
- // Direct stepper movement (similar to LF/LR)
- unsigned long startTime = millis();
- const unsigned long timeout = 15000; // 15 second timeout
- while (digitalRead(LIMIT_SWITCH2) == HIGH) {
- digitalWrite(DRIVER1_STEP, HIGH);
- delayMicroseconds(40);
- digitalWrite(DRIVER1_STEP, LOW);
- delayMicroseconds(45);
- // Check for timeout
- if (millis() - startTime > timeout) {
- Serial.println("LU movement timeout! Stopping.");
- break;
- }
- if (checkStopCommand()) {
- Serial.println("Emergency Stop Triggered");
- stopMotor();
- digitalWrite(RELAY9, LOW);
- return;
- }
- }
- digitalWrite(RELAY9, LOW);
- Serial.println("RELAY9 OFF");
- Serial.println("Motors stopped at Limit Switch 2 or Emergency Stop.");
- setLinearGuide1Complete();
- }
- else if (direction1 == "LD") { // Linear motor down
- // Check if already at lower limit
- if (digitalRead(LIMIT_SWITCH1) == LOW) {
- Serial.println("Already at Limit Switch 1");
- setLinearGuide1Complete();
- return;
- }
- Serial.println("LD");
- digitalWrite(DRIVER1_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY9, HIGH);
- Serial.println("RELAY9 ON");
- delay(100);
- digitalWrite(DRIVER1_DIR, LOW); // Set direction for DOWN movement
- delay(100);
- digitalWrite(DRIVER1_ENA, LOW);
- delay(200);
- Serial.print("Limit States - 1: ");
- Serial.print(digitalRead(LIMIT_SWITCH1));
- Serial.print(" & Limit States - 2: ");
- Serial.println(digitalRead(LIMIT_SWITCH2));
- // Direct stepper movement (similar to LF/LR)
- unsigned long startTime = millis();
- const unsigned long timeout = 15000; // 15 second timeout
- while (digitalRead(LIMIT_SWITCH1) == HIGH) {
- digitalWrite(DRIVER1_STEP, HIGH);
- delayMicroseconds(40);
- digitalWrite(DRIVER1_STEP, LOW);
- delayMicroseconds(45);
- // Check for timeout
- if (millis() - startTime > timeout) {
- Serial.println("LD movement timeout! Stopping.");
- break;
- }
- if (checkStopCommand()) {
- Serial.println("Emergency Stop Triggered");
- stopMotor();
- digitalWrite(RELAY9, LOW);
- return;
- }
- }
- digitalWrite(RELAY9, LOW);
- Serial.println("RELAY9 OFF");
- Serial.println("Motors stopped at Limit Switch 1 or Emergency Stop.");
- delay(100);
- setLinearGuide1Complete();
- }
- else {
- Serial.println("Invalid direction for moveLinearGuide.");
- }
- }
- void moveLinearGuide2(String direction2) {
- linearGuide2Complete = false;
- if (direction2 == "LF") { // Linear motor forward
- if (digitalRead(LIMIT_SWITCH4) == LOW) {
- Serial.println("Already at Limit Switch 4");
- setLinearGuide2Complete();
- return;
- }
- Serial.println("LF");
- digitalWrite(DRIVER2_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY7, HIGH); // Turn ON Relay 7
- Serial.println("RELAY7 ON"); // Notify Python
- delay(100);
- digitalWrite(DRIVER2_DIR, HIGH); // Set direction forward
- delay(100);
- digitalWrite(DRIVER2_ENA, LOW); // Enable motor
- delay(100);
- Serial.print("Limit States - 3: ");
- Serial.print(digitalRead(LIMIT_SWITCH3));
- Serial.print(" & Limit States - 4: ");
- Serial.println(digitalRead(LIMIT_SWITCH4));
- // Direct stepper movement (similar to LF/LR)
- unsigned long startTime = millis();
- const unsigned long timeout = 15000; // 15 second timeout
- while (digitalRead(LIMIT_SWITCH4) == HIGH) {
- digitalWrite(DRIVER2_STEP, HIGH);
- delayMicroseconds(20);
- digitalWrite(DRIVER2_STEP, LOW);
- delayMicroseconds(25);
- // Check for timeout
- if (millis() - startTime > timeout) {
- Serial.println("LF movement timeout! Stopping.");
- break;
- }
- if (checkStopCommand()) {
- Serial.println("Emergency Stop Triggered");
- stopMotor();
- digitalWrite(RELAY7, LOW);
- digitalWrite(DRIVER2_ENA, HIGH);
- return;
- }
- }
- digitalWrite(DRIVER2_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY7, LOW); // Turn OFF Relay 7
- Serial.println("RELAY7 OFF"); // Notify Python
- Serial.println("Motors stopped at Limit Switch 4 or Emergency Stop.");
- delay (100);
- // SET COMPLETION FLAG HERE
- setLinearGuide2Complete();
- }
- else if (direction2 == "LR") { // Move Reverse Direction (Linear motor reverse)
- // Check if already at lower limit
- if (digitalRead(LIMIT_SWITCH3) == LOW) { // Already at limit
- Serial.println("Already at Limit Switch 3");
- setLinearGuide2Complete();
- return;
- }
- Serial.println("LR");
- digitalWrite(DRIVER2_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY7, HIGH); // Turn ON Relay 7
- Serial.println("RELAY7 ON"); // Notify Python
- delay(100);
- digitalWrite(DRIVER2_DIR, LOW); // Set direction reverse
- delay(100);
- digitalWrite(DRIVER2_ENA, LOW); // Enable motor
- delay(100);
- Serial.print("Limit States - 3: ");
- Serial.print(digitalRead(LIMIT_SWITCH3));
- Serial.print(" & Limit States - 4: ");
- Serial.println(digitalRead(LIMIT_SWITCH4));
- // Run BTS7960B motor forward at 5 speed
- digitalWrite(EN_FEEDER, HIGH); // Enable feeder motor
- setFeederMotorSpeed(35, true); // Use the helper function to set speed and direction
- // Direct stepper movement (similar to LF/LR)
- unsigned long startTime = millis();
- const unsigned long timeout = 15000; // 15 second timeout
- while (digitalRead(LIMIT_SWITCH3) == HIGH) {
- digitalWrite(DRIVER2_STEP, HIGH);
- delayMicroseconds(20);
- digitalWrite(DRIVER2_STEP, LOW);
- delayMicroseconds(25);
- // Check for timeout
- if (millis() - startTime > timeout) {
- Serial.println("LD movement timeout! Stopping.");
- break;
- }
- if (checkStopCommand()) {
- Serial.println("Emergency Stop Triggered");
- stopMotor();
- digitalWrite(RELAY7, LOW);
- digitalWrite(DRIVER2_ENA, HIGH);
- return;
- }
- }
- // Stop both motors when Limit Switch 3 is triggered or X command is received
- digitalWrite(DRIVER2_ENA, HIGH);
- delay(100);
- digitalWrite(RELAY7, LOW); // Turn OFF Relay 7
- digitalWrite(EN_FEEDER, LOW);
- Serial.println("RELAY7 OFF"); // Notify Python
- Serial.println("Motors stopped at Limit Switch 3 or Emergency Stop.");
- delay (100);
- // SET COMPLETION FLAG HERE
- setLinearGuide2Complete();
- }
- else {
- Serial.println("Invalid direction for moveLinearGuide.");
- }
- }
- void moveStepper1(bool direction, int stopPin) {
- digitalWrite(DRIVER1_DIR, direction);
- digitalWrite(RELAY9, HIGH);
- digitalWrite(DRIVER1_ENA, LOW); // Enable stepper motor
- // Move stepper motor until limit switch is triggered or "X" command is received
- while (digitalRead(stopPin) == HIGH) {
- digitalWrite(DRIVER1_STEP, HIGH);
- delayMicroseconds(25);
- digitalWrite(DRIVER1_STEP, LOW);
- delayMicroseconds(30);
- if (checkStopCommand()) {
- Serial.println("Emergency Stop Triggered");
- stopMotor(); // Stop when "X" command is received
- return;
- }
- }
- digitalWrite(RELAY9, LOW); // Turn off Relay 1 to stop stepper motor control
- }
- void runOpenGripper() {
- // Define the behavior for Opening Grippers 1 & 2 after tying
- digitalWrite(RELAY3, LOW); // Deactivate Gripper 1 (RELAY3)
- digitalWrite(RELAY4, LOW); // Deactivate Gripper 2 (RELAY4)
- delay(1000);
- }
- void stopMotor() {
- // Stop Feeder motor
- analogWrite(RPWM_FEEDER, 0);
- analogWrite(LPWM_FEEDER, 0);
- digitalWrite(EN_FEEDER, LOW);
- digitalWrite(DRIVER1_ENA, HIGH);
- digitalWrite(DRIVER2_ENA, HIGH);
- feederRunning = false; // Reset feeder running flag
- // Turn off relays
- digitalWrite(RELAY9, LOW);
- digitalWrite(RELAY5, LOW); // Disable both relays
- digitalWrite(RELAY6, LOW);
- motorRunning = false;
- Serial.println("Motor stopped");
- }
- void resetSerialBuffer() {
- while (Serial.available()) {
- Serial.read(); // Clear serial input buffer
- }
- }
- void resetMode() {
- autoMode = false; // Reset Auto mode flag
- manualMode = false; // Reset Manual mode flag
- currentMode = NONE; // Reset the current mode to a default state
- resetSerialBuffer(); // Clear the serial buffer
- Serial.println("Enter next command (START, STOP, Q):"); // Prompt for the next command
- }
- void runMotor(bool clockwise) {
- motorComplete = false;
- if (motorRunning) {
- Serial.println("Motor is already running.");
- return isClockwise; // Return the current direction if already running
- }
- int relayPin = clockwise ? RELAY5 : RELAY6; // Choose correct relay
- digitalWrite(relayPin, HIGH); // Start motor
- motorRunning = true; // Set motor running flag to true
- countA = 0; // Reset count for Proxy A
- countB = 0; // Reset count for Proxy B
- countingEnabled = true; // Enable counting
- isClockwise = clockwise; // Set the direction
- // Disable counting for the opposite proxy and Proxy POS
- if (clockwise) {
- countProxyBEnabled = false; // Disable counting for Proxy B
- countProxyPOSEnabled = false; // Disable counting for Proxy POS
- countProxyAEnabled = true; // Enable counting for current direction
- }
- else {
- countProxyAEnabled = false; // Disable counting for Proxy A
- countProxyPOSEnabled = false; // Disable counting for Proxy POS
- countProxyBEnabled = true; // Enable counting for current direction
- }
- Serial.println(clockwise ? "INDUCTION MOTOR CW STARTED" : "INDUCTION MOTOR CCW STARTED");
- return clockwise; // Return the direction
- }
- void proxyA() {
- static int lastStateA = LOW; // Remember previous state for Proxy A
- static unsigned long lastTriggerTimeA = 0;
- const unsigned long debounceDelay = 300;
- const unsigned long minCountInterval = 2600; // Minimum time between counts (1 second)
- int sensorStateA = digitalRead(PROXY_A); // Read the current state of the sensor
- unsigned long currentTime = millis();
- // Status feedback
- Serial.print("Proxy A Status: ");
- Serial.println(sensorStateA == HIGH ? "Triggered (High)" : "Not Triggered (Low)");
- // Check for Proxy A (CW)
- if (isClockwise && countProxyAEnabled) {
- // Only detect Rising edge (LOW to HIGH)
- if (lastStateA == LOW && sensorStateA == HIGH) {
- // Debounce check
- if ((currentTime - lastTriggerTimeA) > debounceDelay && (currentTime - lastTriggerTimeA) > minCountInterval) {
- countA++; // Increment count for Proxy A
- lastTriggerTimeA = currentTime; // Update last trigger time
- Serial.print("Proxy A Count: ");
- Serial.println(countA);
- // Stop relay 4 if count reaches 4
- if (countA >= 4) {
- digitalWrite(RELAY5, LOW); // Stop relay 4
- stopMotor();
- motorRunning = false; // Set flag to stop motor
- countA = 0; // Reset count after stopping
- countProxyAEnabled = false; // Disable counting for Proxy A
- countProxyBEnabled = true; // Re-enable counting for Proxy B
- // SET COMPLETION FLAG HERE
- setMotorComplete();
- }
- }
- }
- lastStateA = sensorStateA; // Update last state for Proxy A
- }
- }
- void proxyB() {
- static int lastStateB = LOW; // Remember previous state for Proxy B
- static unsigned long lastTriggerTimeB = 0;
- const unsigned long debounceDelay = 300;
- const unsigned long minCountInterval = 2600; // Minimum time between counts (1 second)
- int sensorStateB = digitalRead(PROXY_B); // Read the current state of the sensor
- unsigned long currentTime = millis();
- // Status feedback
- Serial.print("Proxy B Status: ");
- Serial.println(sensorStateB == HIGH ? "Triggered (High)" : "Not Triggered (Low)");
- // Check for Proxy B (CCW)
- if (!isClockwise && countProxyBEnabled) {
- // Only detect Rising edge (LOW to HIGH)
- if (lastStateB == LOW && sensorStateB == HIGH) {
- // Debounce check
- if ((currentTime - lastTriggerTimeB) > debounceDelay && (currentTime - lastTriggerTimeB) > minCountInterval) {
- countB++; // Increment count for Proxy B
- lastTriggerTimeB = currentTime;
- Serial.print("Proxy B Count: ");
- Serial.println(countB);
- // Stop relay 5 if count reaches 5
- if (countB >= 4) {
- digitalWrite(RELAY6, LOW); // Stop relay 5
- stopMotor();
- motorRunning = false; // Set flag to stop motor
- countB = 0; // Reset count after stopping
- countProxyBEnabled = false; // Disable counting for Proxy B
- countProxyAEnabled = true; // Re-enable counting for Proxy A
- // SET COMPLETION FLAG HERE
- setMotorComplete();
- }
- }
- }
- lastStateB = sensorStateB; // Update last state for Proxy B
- }
- }
- /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment