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
}
}