Hello, I am using LCD, Relay, Stepper motors and AC motora for my automation project. Everything runs fine but after 2 hours of running LCD freezes But Program Continues.
#include <Wire.h>
#include <Keypad.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp lcd;
//LiquidCrystal_I2C lcd(0x27,16,2);
// Keypad layout
char keys[5][4] = {
{'F','f','#','*'},
{'1','2','3','U'},
{'4','5','6','D'},
{'7','8','9','C'},
{'L','0','R','N'}
};
byte rowPins[5] = {22,24,26,28,30};
byte colPins[4] = {38,36,34,32};
Keypad keypad(makeKeymap(keys), rowPins, colPins, 5, 4);
// Motor pins
const int m2P=A0, m2D=A1, m2E=A2;
const int m1P=11, m1D=12, m1E=13;
const int relayPin = 8;
// Stepper settings
const long stepsPerRev = 200;
const unsigned long stepDelayM1 = (60*1000000/(stepsPerRev*4*200));
const unsigned long stepDelayM2 = (60*1000000/(stepsPerRev*4*600));
// For F1 flow
char lastKey = 0;
void setup(){
Wire.begin();
Wire.setClock(50000);
lcd.begin(16,2);
lcd.backlight();
//lcd.init(); lcd.backlight();
pinMode(m2P,OUTPUT); pinMode(m2D,OUTPUT); pinMode(m2E,OUTPUT);
pinMode(m1P,OUTPUT); pinMode(m1D,OUTPUT); pinMode(m1E,OUTPUT);
pinMode(A3, OUTPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(m2E,HIGH);
digitalWrite(m1E,HIGH);
digitalWrite(relayPin,HIGH);
showMainMenu();
}
void loop(){
char k = keypad.getKey();
if(!k) return;
if(k == 'F') f1Flow();
else if(k == 'f') manualMode();
}
void showMainMenu(){
lcd.clear();
lcd.setCursor(0,0); lcd.print("F1 : New Bamboo");
lcd.setCursor(0,1); lcd.print("F2 : Manual");
}
// ---------------- MANUAL MODE ----------------
void manualMode() {
bool relayState = false;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Manual Mode");
lcd.setCursor(0,1);
lcd.print("Belt OFF");
while (true) {
keypad.getKeys();
for (int i = 0; i < LIST_MAX; i++) {
if (keypad.key[i].kchar != NO_KEY) {
char k = keypad.key[i].kchar;
KeyState state = keypad.key[i].kstate;
if (state == PRESSED) {
// Toggle relay with *
if (k == '*') {
relayState = !relayState;
digitalWrite(relayPin, relayState ? LOW : HIGH);
// Update only second line
lcd.setCursor(0,1);
if(relayState){
lcd.print("Belt ON ");
}
else{
lcd.print("Belt OFF");
}
delay(300);
}
// Motor controls
else {
runStepFor(k);
}
}
else if (state == HOLD) {
runStepFor(k);
}
else if (state == RELEASED) {
digitalWrite(m1E, HIGH);
digitalWrite(m2E, HIGH);
if (k == 'N' || k == 'C') {
// Relay OFF when exiting manual mode
digitalWrite(relayPin, HIGH);
relayState = false;
showMainMenu();
return;
}
}
}
}
}
}
void runStepFor(char key) {
if (key == 'U') {
digitalWrite(m2E, LOW);
runMotor(m2P, m2D, 1, true, stepDelayM2);
}
else if (key == 'D') {
digitalWrite(m2E, LOW);
runMotor(m2P, m2D, 1, false, stepDelayM2);
}
else if (key == 'L') {
digitalWrite(m1E, LOW);
runMotor(m1P, m1D, 1, true, stepDelayM2);
}
else if (key == 'R') {
digitalWrite(m1E, LOW);
runMotor(m1P, m1D, 1, false, stepDelayM2);
}
}
// ---------------- F1 FLOW ----------------
void f1Flow(){
long length;
int stage;
// Step 1: Length
lcd.clear(); lcd.print("Enter length:");
length = promptNumber();
if(lastKey=='C'){ showMainMenu(); return; }
// Step 2: Stage
while(true){
lcd.clear(); lcd.print("Wear stage 1-10:");
stage = promptNumber();
if(lastKey=='C'){
lcd.clear(); lcd.print("Enter length:");
length = promptNumber();
if(lastKey=='C'){ showMainMenu(); return; }
continue;
}
if(stage>=1 && stage<=10) break;
lcd.clear(); lcd.print("Invalid stage");
delay(1000);
}
// Confirmation
lcd.clear();
lcd.print("Len:"); lcd.print(length);
while(true){
lcd.setCursor(0,1);
lcd.print("Stg:"); lcd.print(stage);
char k = keypad.getKey();
if(!k) continue;
if(k=='C'){
stage = promptNumber();
if(lastKey=='C'){ showMainMenu(); return; }
continue;
}
if(k=='N') break;
}
digitalWrite(m2E,LOW);
digitalWrite(m1E,LOW);
lcd.clear(); lcd.print("In Progress");
int m2r1 = getStageRevs(stage);
int m2r2 = getStage2Revs(stage);
int m1r = getM1Revs(stage, length);
digitalWrite(relayPin, LOW);
runMotor(m2P, m2D, m2r1, false, stepDelayM2);
runMotor(m1P, m1D, m1r, true, stepDelayM1);
delay(5000);
runMotor(m1P, m1D, m1r, false, stepDelayM1);
delay(2000);
digitalWrite(relayPin, HIGH);
runMotor(m2P, m2D, m2r2, true, stepDelayM2);
lcd.clear(); lcd.print("Done.");
delay(1000);
digitalWrite(m2E,HIGH);
digitalWrite(m1E,HIGH);
// buzzer
digitalWrite(A3,HIGH); delay(50);
digitalWrite(A3,LOW); delay(50);
digitalWrite(A3,HIGH); delay(50);
digitalWrite(A3,LOW); delay(50);
digitalWrite(A3,HIGH); delay(500);
digitalWrite(A3,LOW);
showMainMenu();
}
// ---------------- INPUT WITH BACKSPACE ----------------
long promptNumber(){
String input = "";
lcd.setCursor(0,1);
lcd.print(" ");
while(true){
char k = keypad.getKey();
if(!k) continue;
lastKey = k;
if(isdigit(k)){
input += k;
}
else if(k == 'L'){ // ✅ Backspace
if(input.length() > 0){
input.remove(input.length() - 1);
}
}
else if(k == 'N'){ // Confirm
if(input.length() > 0){
return input.toInt();
}
}
else if(k == 'C'){ // Cancel
return 0;
}
// Refresh display
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(input);
}
}
// ---------------- STAGE LOGIC ----------------
int getStageRevs(int s){
if(s==1) return (4*4);
if(s==2) return (5*4);
if(s==3) return (7*4);
if(s==4) return (9*4);
if(s>=5 && s<=7) return (11*4);
return (12*4);
}
int getStage2Revs(int s){
if(s==1) return (24*4);
if(s==2) return (25*4);
if(s==3) return (27*4);
if(s==4) return (29*4);
if(s>=5 && s<=7) return (31*4);
return (32*4);
}
int getM1Revs(int stage, long length){
if(stage >= 1 && stage <= 3){
return (928 - length);
}
else if(stage >= 4 && stage <= 10){
return (926 - length);
}
return (923 - length);
}
// ---------------- MOTOR RUN ----------------
void runMotor(int P, int D, long revs, bool fwd, unsigned long stepDelay) {
digitalWrite(D, fwd ? HIGH : LOW);
long steps = revs * stepsPerRev;
for (long i = 0; i < steps; i++) {
digitalWrite(P, HIGH);
delayMicroseconds(stepDelay);
digitalWrite(P, LOW);
delayMicroseconds(stepDelay);
}
}