Interrupt on embedded motor sequence loop

I have a number pad 5*4 with i2c , L298n motor driver, one channel relay (active low) and Arduino mega 2560 also limit switch.
so what my program does is that it takes an input value from the number pad and calculate motor delay time and apply it on motor sequence loop.
what i'm dealing with is that the interrupt is not working properly if i wanted to pause in between the motor sequence loop it just keeps counting the loop by itself just waiting the delay time to finish. instead what i want it to do is hold the loop where it’s paused and and continue when pressed again. Here’s the code for better understanding .

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

// Define keypad layout
// Define keypad layout
// Define keypad layout
const byte ROWS = 5; // 5 rows
const byte COLS = 4; // 4 columns
char *specialKeys[] = {
    "F1", "F2", "#", "*",
    "1", "2", "3", "UP",
    "4", "5", "6", "DOWN",
    "7", "8", "9", "ESC",
    "LEFT", "0", "RIGHT", "ENTER"};

char specialKeysID[] = {
    'A', 'B', '#', '*',
    '1', '2', '3', 'C',
    '4', '5', '6', 'D',
    '7', '8', '9', 'E',
    'F', '0', 'G', 'H'};

char keys[ROWS][COLS] = {
    {specialKeysID[0], specialKeysID[1], specialKeysID[2], specialKeysID[3]},
    {specialKeysID[4], specialKeysID[5], specialKeysID[6], specialKeysID[7]},
    {specialKeysID[8], specialKeysID[9], specialKeysID[10], specialKeysID[11]},
    {specialKeysID[12], specialKeysID[13], specialKeysID[14], specialKeysID[15]},
    {specialKeysID[16], specialKeysID[17], specialKeysID[18], specialKeysID[19]}};

byte rowPins[ROWS] = {38, 36, 34, 32, 30}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {22, 24, 26, 28};     // connect to the column pinouts of the kpd

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// Define LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD I2C address

// Define pins
const int motorPin1 = 9;
const int motorPin2 = 10;
const int limitswitch1 = 2; // pin for the start button (limit switch 1)
const int relayPin = 13;

// Define variables
int loopCount = 0;
int N = 0;
int limitSwitch2Count = 0;
const int limitswitch1InterruptPin = 2; // The pin number for Limit Switch 1 should match the signal pin connected to it.
volatile bool isMotorRunning = false;
volatile bool motorActive = false; // This flag controls the state of the motor loop.
volatile bool pause = false;
int storedLoopCount = 0;

// Function prototypes
void startMotorSequence();
void fetchNValue();
void askNValueConfirmation();

bool directionConfirmed = false;
// int N = 0;              // Global variable to store the N value
bool nValueSet = false; // Global flag to determine if N has been set

void setup()
{
    // Initialize the LCD
    lcd.init();
    lcd.backlight();

    // Initialize pins
    pinMode(motorPin1, OUTPUT);
    pinMode(motorPin2, OUTPUT);
    pinMode(limitswitch1, INPUT_PULLUP);
    pinMode(relayPin, OUTPUT);
    digitalWrite(relayPin, HIGH); // Assume relay is active LOW

    // Show welcome message
    lcd.print("Welcome");
    delay(500);
    lcd.clear();

    attachInterrupt(digitalPinToInterrupt(limitswitch1InterruptPin), limitSwitch1InterruptHandler, FALLING);
}


void limitSwitch1InterruptHandler()
{
    delay(100); // Simple debouncing
    if (digitalRead(limitswitch1) == LOW)
    {
        isMotorRunning = !isMotorRunning;
        pause = !pause;
        digitalWrite(relayPin, HIGH);
        digitalWrite(motorPin1, LOW);
        // digitalWrite(motorPin2, LOW);

        // lcd.print("big motor off");
    }
}




void loop()
{
    if (!nValueSet)
    {
        fetchNValue();
        lcd.clear();
        lcd.print("limit switch 1");
    }
    else if (nValueSet)
    {

        // Check if Limit Switch 1 is pressed to start the motor sequence
        if (digitalRead(limitswitch1) == LOW)
        { // Assuming LOW when pressed
            // Debounce the limit switch
            delay(50);

            if (digitalRead(limitswitch1) == LOW)
            {
                isMotorRunning = true;
                startMotorSequence();
            }
        }
    }

    // Check if it needs to restart the motor sequence
}
    

 

void fetchNValue()
{
    lcd.clear();
    lcd.print("Give the N value:");

    N = 0; // Reset the N value
    bool enterPressed = false;

    // Collect user input until the "ENTER" key is pressed
    while (!enterPressed)
    {
        char key = keypad.getKey();
        if (key)
        { // if a key is pressed
            if (key >= '0' && key <= '9')
            { // if the key is a digit
                if (N < 10)
                {                             // This is a simple check. Adjust it to allow for larger numbers as needed for your use case.
                    N = N * 10 + (key - '0'); // Append the digit to the current value of N
                    lcd.setCursor(0, 1);      // Move cursor to the second line of the LCD
                    lcd.print(N);             // Display current value of N
                }
            }
            
            else if (key == 'D')
            {
                // Skip the current function and keep going
                enterPressed = true;
            }
            else if (key == 'H')
            {
                // The user has confirmed the N value
                enterPressed = true;
            }
        }
        // Add necessary delay if key debouncing is required
    }

    // Confirm the entered N value
    askNValueConfirmation();
}

void askNValueConfirmation()
{
    // After the user has entered the N value, we should ask for confirmation
    lcd.clear();
    lcd.print("N is ");
    lcd.print(N);
    lcd.setCursor(0, 1);
    lcd.print("F1-Yes F2-No");

    bool confirmation = false;
    while (!confirmation)
    {
        char key = keypad.getKey();
        if (key)
        { // if a key is pressed
            if (key == 'A' || key == 'H')
            {
                nValueSet = true;
                lcd.clear();
                lcd.print("Press limit switch 1");
                confirmation = true;
                // The user has confirmed the N value

                // No longer call startMotorSequence() here
                // Proceed to other logic
            }
            else if (key == 'B' || key == 'E')
            {
                // The user has rejected the N value. Prompt for a new value.
                fetchNValue();
                confirmation = true; // Exit the loop
            }
        }
    }
}


void startMotorSequence()
{
    motorActive = true;
    isMotorRunning = true;
    int motorDelayTime = N * 1000 / 1; // Calculate delay time (t) in milliseconds.

     for (loopCount; isMotorRunning && loopCount < 4; loopCount++)
    {
        // Check if the motor is still running after each step
    

        // Check again if motorActive is still true, since it might be changed by "stopEverything()"
        if (motorActive)
        {
            digitalWrite(relayPin, LOW);
            lcd.clear();
            lcd.print("Motor is ON ");
            lcd.print(loopCount + 1);

            // Forward loop operation
            delay(motorDelayTime);
            digitalWrite(motorPin1, HIGH);
            digitalWrite(motorPin2, LOW);
            delay(3000);
            digitalWrite(motorPin1, LOW);
            digitalWrite(motorPin2, LOW);

            lcd.clear();
            lcd.print("Loop ");
            lcd.print(loopCount + 1);
            lcd.print(" done");
            if (!isMotorRunning)
            {
                loopCount = loopCount - 1;
            }
        }

        // After each operation, check if the motor is still running
        
    // After 4 loops, go reverse until it touches Limit Switch 2
    }
}

I'm not really clear on the program structure or intent, and it appears you don't really need the interrupt.

However,

Is that where you need to pause? In which case, I would loop there until isMotorRunning is true.

first thanks for the reply.
and no where i want to pause in here

if (motorActive)
        {
            digitalWrite(relayPin, LOW);
            lcd.clear();
            lcd.print("Motor is ON ");
            lcd.print(loopCount + 1);

            // Forward loop operation
            delay(motorDelayTime);
            digitalWrite(motorPin1, HIGH);
            digitalWrite(motorPin2, LOW);
            delay(3000);
            digitalWrite(motorPin1, LOW);
            digitalWrite(motorPin2, LOW);

            lcd.clear();
            lcd.print("Loop ");
            lcd.print(loopCount + 1);
            lcd.print(" done");

and

if (!isMotorRunning)
{ loopCount = loopCount - 1;
}
this code is for repeating the paused loop again when continued(when limitswitch1InterruptPin goes Low again).

for example, assume it started running and its on loop 2 in which the lcd will display ("Motor is ON 2") at this exact moment if i wanted to pause or when (limitswitch1InterruptPin goes Low), it should pause on ("Motor is ON 2") and hold the paused state but instead what it does is it will of course turn the relay off also motor pins off but after the delay times (delay(motorDelayTime);, delay(3000); ) are over the loop continues to the next one in this case to the third loop in which the lcd will print "Motor is ON 3". with out my permission to continue.

so i think its clear now what i want it to do is (when limitswitch1InterruptPin goes Low) if the MotorSequence or ("if (motorActive)") is running, it should pause and hold the state. then (when limitswitch1InterruptPin goes Low again) it should continue the motorSequence by doing the previous loop again, thats why its ("loopCount = loopCount - 1;").

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.