Code gets stuck after first run

I am working on my University Project. It's a DMT and IDMT relay. The following code runs fine the first time but it gets stuck after the first run as void loop() runs for the second time. it just keep on printing the IDMT Mode and DMT Mode again and again.

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

LiquidCrystal_I2C lcd(0x20,16,2);

#define relayPin1  9
#define relayPin2  10
#define timerPin 7
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {31,33, 35, 37};
byte colPins[COLS] = {39,41, 43, 45};

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void begin();
void input_Value();
void dmt_Mode();
void idmt_Mode();
void input_Delay();
char key_IN();
void common_Function1();
void common_Function2();


float inputNumber = 0;
float act_Voltage = 2000;
int inputState = 0;
int inputDigit = 0;
int inputState_D = 0;
int inputDigit_D = 0;
float inputNumber_D = 0;
char flag = 0; //This controls loops.



void setup(){
  pinMode(timerPin,OUTPUT);
  digitalWrite(timerPin,LOW);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.println("Welcome");
  lcd.setCursor(0, 1);
  lcd.print("Intializing.....");
  pinMode(relayPin1,OUTPUT);
  pinMode(relayPin2,OUTPUT);
  digitalWrite(relayPin1,HIGH);
  digitalWrite(relayPin2,HIGH);
  delay(100);

}
void loop(){
    begin(); 
}

void begin(){
  char mode; 
  lcd.setCursor(0, 0);
  lcd.print("A.DMT Operation");
  lcd.setCursor(0,1);
  lcd.print("B.IDMT Operation");
  delay(200);
  mode = key_IN();
  if (mode == 'A'){
    lcd.setCursor(0,1);
    lcd.println(mode);       
    dmt_Mode();
  }
  else if(mode == 'B'){
    lcd.setCursor(0,1);
    lcd.println(mode);
    idmt_Mode(); 
}
}


char key_IN(){
   char key_ = customKeypad.getKey();
   return key_;
}
void common_Function1(){
  char dmtFlag = 0;
   lcd.clear();    
       lcd.setCursor(0,0);
       lcd.print("Set Voltage:");
    flag = 1; 
     inputNumber = 0;
     inputState = 0;
     inputDigit = 0;          
    input_Value();
    {
       dmtFlag =1;
       while(dmtFlag !=0){     
         char mode; 
         mode = key_IN();
         if (mode == 'A'){
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.println("Enter Again");
            inputNumber = 0;
            inputState = 0;
            inputDigit = 0;                               
            input_Value();
         }
         else if(mode == 'B'){
            lcd.clear();        
            lcd.setCursor(0,0);
             lcd.println("Proceed"); 
            delay(200);
            dmtFlag = 0;  
          }  
          } 
    }    
    delay(500);
    lcd.clear();    
    lcd.setCursor(0,0);
    lcd.print("Set Time:");
    input_Delay();
    {
       dmtFlag =1;
       while(dmtFlag !=0){     
         char mode; 
         mode = key_IN();
         if (mode == 'A'){
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.println("Enter Again");
            inputNumber_D = 0;
            inputState_D = 0;
            inputDigit_D = 0;                               
            input_Delay();
         }
         else if(mode == 'B'){
            lcd.clear();        
            lcd.setCursor(0,0);
            lcd.println("Proceed"); 
            delay(200);
            dmtFlag = 0;  
          }
       }            
          }
}

void common_Function2(){
  lcd.setCursor(0, 0);
  lcd.print("A.Overvoltage   ");
  lcd.setCursor(0, 1);
  lcd.print("B.Undervoltage  ");
}

void common_Function3(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("No Fault:");
  lcd.setCursor(0,1);
  lcd.print("Normal Voltage");
}
void dmt_Mode(){
  lcd.clear();  
  while(flag == 0){  
  common_Function2();
  char mode_D = key_IN();
  if (mode_D == 'A'){
    common_Function1(); 
    delay(1000);    
    {
     char check_Flag = 1;            
     while(check_Flag != 0){
       if(inputNumber<act_Voltage){
          digitalWrite(relayPin1,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0,1);
          lcd.print("Overvoltage");
          digitalWrite(timerPin,HIGH);
          delay(inputNumber_D*1000);
          digitalWrite(relayPin2,LOW);
          digitalWrite(timerPin,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Relay Tripped:");
          lcd.setCursor(0,1);
          lcd.print(inputNumber_D);
          lcd.print(" sec");
          delay(1000);
          check_Flag = 0;
         }
       else{
          common_Function3();
         } 
         }
    }             
  }  
  else if(mode_D == 'B'){
    common_Function1(); 
    delay(1000);    
    {
     char check_Flag = 1;            
     while(check_Flag != 0){
       if(inputNumber>act_Voltage){
          digitalWrite(relayPin1,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0,1);
          lcd.print("Undervoltage");
          digitalWrite(timerPin,HIGH);
          delay(inputNumber_D*1000);
          digitalWrite(relayPin2,LOW);
          digitalWrite(timerPin,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Relay Tripped:");
          lcd.setCursor(0,1);
          lcd.print(inputNumber_D);
          lcd.print(" sec");
          delay(1000);
          check_Flag = 0;
         }
       else{
          common_Function3();
         } 
         }
    }
} 
  }
  }

void idmt_Mode(){
  lcd.clear();  
  while(flag == 0){  
  common_Function2();
  char mode_D = key_IN();
  if (mode_D == 'A'){
    common_Function1(); 
    delay(1000);    
    {
     char check_Flag = 1;            
     while(check_Flag != 0){
       if(inputNumber<act_Voltage){
          digitalWrite(relayPin1,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0,1);
          lcd.print("Overvoltage");
          digitalWrite(timerPin,HIGH);
          delay(inputNumber_D*1000);
          digitalWrite(relayPin2,LOW);
          digitalWrite(timerPin,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Relay Tripped:");
          lcd.setCursor(0,1);
          lcd.print(inputNumber_D);
          lcd.print(" sec");
          delay(1000);
          check_Flag = 0;
         }
       else{
          common_Function3();
          delay(1000);
         } 
         }
    }             
  }  
  else if(mode_D == 'B'){
    common_Function1(); 
    delay(1000);    
    {
     char check_Flag = 1;            
     while(check_Flag != 0){
       if(inputNumber>act_Voltage){
          digitalWrite(relayPin1,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0,1);
          lcd.print("Undervoltage");
          digitalWrite(timerPin,HIGH);
          delay(inputNumber_D*1000);
          digitalWrite(relayPin2,LOW);
          digitalWrite(timerPin,LOW);
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Relay Tripped:");
          lcd.setCursor(0,1);
          lcd.print(inputNumber_D);
          lcd.print(" sec");
          delay(1000);
          check_Flag = 0;
         }
       else{
          common_Function3();
          delay(1000);
         } 
         }
    }
} 
  }  
}

void input_Value(){
   if (inputState == 0) {
        lcd.setCursor(inputState,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print(" ");
    }
  while(inputState<5){    
    char key = customKeypad.getKey();
    if (key != NO_KEY){
    if (inputState == 0){
      inputNumber = (key - '0') * 100;
      inputState = 1;
      inputDigit = key - '0';
      lcd.setCursor(0,1);
      lcd.print(inputDigit);
    }
    else if (inputState == 1){
      inputNumber += (key - '0') * 10;
      inputState = 2;
      inputDigit = key - '0';
      lcd.setCursor(1,1);
      lcd.print(inputDigit);      
    }
    else if (inputState == 2){
      inputNumber += key - '0';
      inputState = 3;
      inputDigit = key - '0';
      lcd.setCursor(2,1);
      lcd.print(inputDigit);
      lcd.setCursor(3,1);
      lcd.print(".");
    }
    else if (inputState == 3){
      inputNumber += (key - '0') * 0.1;
      inputState = 4;
      inputDigit = key - '0';
      lcd.setCursor(4,1);
      lcd.print(inputDigit);  
    }
    else if (inputState == 4){
      inputNumber += (key - '0') * 0.01;
      inputState = 5;
      inputDigit = key - '0';
      lcd.setCursor(5,1);
      lcd.print(inputDigit);
      lcd.setCursor(7, 1);
      lcd.print("V");   
    }
     if (inputState == 5){
      Serial.println(inputNumber);
      lcd.setCursor(0,1);
      if(inputNumber<80){
        inputNumber = 080.00;
      }
      else if(inputNumber >260){
        inputNumber = 260;
      }
      lcd.print(inputNumber);
      lcd.setCursor(7, 1);
      lcd.print("V");     
      }  
    if (inputState <3) {
        lcd.setCursor(inputState,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState,1);
        lcd.print(" ");
    }
    else if(inputState == 3){
        lcd.setCursor(inputState+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print(" ");      
    }
    else if(inputState == 4){
        lcd.setCursor(inputState+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState+1,1);
        lcd.print(" ");      
    }     
      delay(50);
    
   }
  }  
}


void input_Delay(){
   if (inputState_D == 0) {
        lcd.setCursor(inputState_D,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print(" ");
    }     
  while(inputState_D<4){    
  char key = customKeypad.getKey();
  if (key != NO_KEY){
   if (inputState_D == 0){
      inputNumber_D += (key - '0') * 10;
      inputState_D = 1;
      inputDigit_D = key - '0';
      lcd.setCursor(0,1);
      lcd.print(inputDigit_D);      
    }
    else if (inputState_D == 1){
      inputNumber_D += key - '0';
      inputState_D = 2;
      inputDigit_D = key - '0';
      lcd.setCursor(1,1);
      lcd.print(inputDigit_D);
      lcd.setCursor(2,1);
      lcd.print(".");
    }
    else if (inputState_D == 2){
      inputNumber_D += (key - '0') * 0.1;
      inputState_D = 3;
      inputDigit_D = key - '0';
      lcd.setCursor(3,1);
      lcd.print(inputDigit_D);  
    }
    else if (inputState_D == 3){
      inputNumber_D += (key - '0') * 0.01;
      inputState_D = 4;
      inputDigit_D = key - '0';
      if(inputNumber_D>50){
        inputNumber_D = 50;
      }
      lcd.setCursor(4,1);
      lcd.print(inputDigit_D);
      lcd.setCursor(6, 1);
      lcd.print("sec");   
    }
     if (inputState_D == 4){
      Serial.println(inputNumber_D);
      lcd.setCursor(0,1);
      lcd.print(inputNumber_D);
      lcd.setCursor(6, 1);
      lcd.print("sec");     
      }  
    if (inputState_D <2) {
        lcd.setCursor(inputState_D,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D,1);
        lcd.print(" ");
    }
    else if(inputState_D == 2){
        lcd.setCursor(inputState_D+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print(" ");      
    }
    else if(inputState_D == 3){
        lcd.setCursor(inputState_D+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print(" ");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print("_");
        delay(50);
        lcd.setCursor(inputState_D+1,1);
        lcd.print(" ");      
    }      
    }
    }
    }

Could you please use the auto format tool on your code and repost?
I'm getting motion sickness reading it.

What @anon56112670 said and please explain what the code is supposed to do. It is extremely hard to follow.

OK i will repost after adding comments and proper formatting.

Hello janni_abdullah

I have checked the code a little.
This sketch seems to have grown organically through nested and dupilcate function calls.
This leads to spaghetti code and nodes in the logic that are functionally undesirable.

All of these delay() and while() functions are causing a none realtime behaiviour of the sketch.

	Line  58:   delay(100);
	Line  71:   delay(200);
	Line 118:         delay(200);
	Line 123:   delay(500);
	Line 146:         delay(200);
	Line 174:       delay(1000);
	Line 186:             delay(inputNumber_D * 1000);
	Line 195:             delay(1000);
	Line 206:       delay(1000);
	Line 218:             delay(inputNumber_D * 1000);
	Line 227:             delay(1000);
	Line 246:       delay(1000);
	Line 258:             delay(inputNumber_D * 1000);
	Line 267:             delay(1000);
	Line 272:             delay(1000);
	Line 279:       delay(1000);
	Line 291:             delay(inputNumber_D * 1000);
	Line 300:             delay(1000);
	Line 305:             delay(1000);
	Line 317:     delay(50);
	Line 320:     delay(50);
	Line 323:     delay(50);
	Line 385:         delay(50);
	Line 388:         delay(50);
	Line 391:         delay(50);
	Line 398:         delay(50);
	Line 401:         delay(50);
	Line 404:         delay(50);
	Line 411:         delay(50);
	Line 414:         delay(50);
	Line 417:         delay(50);
	Line 421:       delay(50);
	Line 432:     delay(50);
	Line 435:     delay(50);
	Line 438:     delay(50);
	Line 490:         delay(50);
	Line 493:         delay(50);
	Line 496:         delay(50);
	Line 503:         delay(50);
	Line 506:         delay(50);
	Line 509:         delay(50);
	Line 516:         delay(50);
	Line 519:         delay(50);
	Line 522:         delay(50);	Line  27: void input_Delay();
	Line  58:   delay(100);
	Line  71:   delay(200);
	Line 118:         delay(200);
	Line 123:   delay(500);
	Line 140:         input_Delay();
	Line 146:         delay(200);
	Line 174:       delay(1000);
	Line 186:             delay(inputNumber_D * 1000);
	Line 195:             delay(1000);
	Line 206:       delay(1000);
	Line 218:             delay(inputNumber_D * 1000);
	Line 227:             delay(1000);
	Line 246:       delay(1000);
	Line 258:             delay(inputNumber_D * 1000);
	Line 267:             delay(1000);
	Line 272:             delay(1000);
	Line 279:       delay(1000);
	Line 291:             delay(inputNumber_D * 1000);
	Line 300:             delay(1000);
	Line 305:             delay(1000);
	Line 317:     delay(50);
	Line 320:     delay(50);
	Line 323:     delay(50);
	Line 385:         delay(50);
	Line 388:         delay(50);
	Line 391:         delay(50);
	Line 398:         delay(50);
	Line 401:         delay(50);
	Line 404:         delay(50);
	Line 411:         delay(50);
	Line 414:         delay(50);
	Line 417:         delay(50);
	Line 421:       delay(50);
	Line 432:     delay(50);
	Line 435:     delay(50);
	Line 438:     delay(50);
	Line 490:         delay(50);
	Line 493:         delay(50);
	Line 496:         delay(50);
	Line 503:         delay(50);
	Line 506:         delay(50);
	Line 509:         delay(50);
	Line 516:         delay(50);
	Line 519:         delay(50);
	Line 522:         delay(50);

and

Line 102:     while (dmtFlag != 0) {
	Line 130:     while (dmtFlag != 0) {
	Line 169:   while (flag == 0) {
	Line 177:         while (check_Flag != 0) {
	Line 209:         while (check_Flag != 0) {
	Line 241:   while (flag == 0) {
	Line 249:         while (check_Flag != 0) {
	Line 282:         while (check_Flag != 0) {
	Line 327:   while (inputState < 5) {
	Line 442:   while (inputState_D < 4) {

What to do.
There are two options.
Debug, using multiple Serial.println()'s to see what happens under different conditions. Nodes can be solved this way, but new ones can also be created in the process.
The second option is to rearrange the sketch. Based on the IPO model, structure the desired function of the sketch into basic functions. Take a sheet of paper and a pencil and draw a programme structure to identify the required functions, e.g. button, timer and display functions. All these functions can be coded and tested separately. To complete the project, you also need to design a control structure that uses events to call the above functions. In this way keep in mind to design objects and related services thus handle input/output actions.
That is all that needs to be done. Try them out.

Have a nice day and enjoy coding in C++.

1 Like

Thanks.

Your function looks like it is mostly a blinking underline (cursor). Have you tried the library calls for lcd.cursor() and lcd.blink()

You could , as mentioned, add Serial.print() statements all over the place to find out where the program is getting stuck and address each problem as you discover it.

However, it looks like the main function if the device you are building is to monitor voltage and handle a fault situation. A fault appears to be defined in terms of the extent of the over/under voltage and the length of time that condition has persisted for.

In itself, that sounds easy enough. The problem is that the program has got very top heavy with the code to collect the operating parameters from the user through the keyboard and display.

It gets more complicated if, during normal operation of the device, the user can use the keyboard to adjust the operating parameters, because you are doing multiple things simultaneously. It gets worse if you have to start handling timeouts to force the resumption of normal operations after an abandoned attempt, by the user, to adjust a parameter etc.

Anyway, you'll soon discover the limitations of "spaghetti" code.

I'd be looking at using a finite state machine type design model for this. Even going through the exercise of drawing finite state machine diagram could be useful.

1 Like

Thanks for your kind suggestions. I have started doing it through finite state machine model and it is coming along nicely.

Here is the modified code based on suggestions(and it works). Thanks everyone who helped. It is based on state machine model.

#include <Arduino.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <PZEM004Tv30.h>
#include <math.h>

#if !defined(PZEM_RX_PIN) && !defined(PZEM_TX_PIN)
#define PZEM_RX_PIN 16
#define PZEM_TX_PIN 17
#endif
#if !defined(PZEM_SERIAL)
#define PZEM_SERIAL Serial2
#endif
PZEM004Tv30 pzem(PZEM_SERIAL);

LiquidCrystal_I2C lcd(0x20, 16, 2);

#define relayPin1 9
#define relayPin2 10
#define timerPin 7
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};
byte rowPins[ROWS] = { 31, 33, 35, 37 };
byte colPins[COLS] = { 39, 41, 43, 45 };

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
char key = customKeypad.getKey();

enum class codeStates : uint8_t {
  codeStart = 0,
  modeSelect,
  inputVoltage,
  againV,
  again,
  inputTMS,
  againTMS,
  delayDisplay,
  delayDisplay1,
  delayDisplay2,
  delayDisplay3,
  inputDelay,
  againD,
  delayCalc,
  delay,
  underVoltage,
  overVoltage
};

codeStates States = codeStates ::codeStart;
bool mode = false;
bool operationMode = false;
bool cont = false;
float act_Voltage = 160;
float inputNumber = 0;
float timeDelay = 0;
float tms = 1.0;
int inputState = 0;
int inputDigit = 0;
int inputState_D = 0;
int inputDigit_D = 0;
float inputNumber_D = 0;
uint32_t lastSwitchTime = 0;
uint32_t nextSwitchInterval = 0;
uint32_t timeMS;

void initialization();
void stateMachine();
void setup() {
  // put your setup code here, to run once:
  initialization();
}

void loop() {
  // put your main code here, to run repeatedly:
  act_Voltage = pzem.voltage();
  timeMS = millis();
  stateMachine();
}

void initialization() {
  pinMode(timerPin, OUTPUT);
  digitalWrite(timerPin, LOW);
  Serial.begin(9600);
  lcd.init();
  lcd.clear();
  lcd.backlight();
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  digitalWrite(relayPin1, HIGH);
  digitalWrite(relayPin2, HIGH);
}

char key_IN() {
  char key_ = customKeypad.getKey();
  return key_;
}

void stateMachine() {
  switch (States) {
    case codeStates::codeStart:
      {
        lcd.setCursor(0, 0);
        lcd.print("A.DMT Operation");
        lcd.setCursor(0, 1);
        lcd.print("B.IDMT Operation");
        key = customKeypad.getKey();
        if (key == 'A') {
          mode = false;
          States = codeStates::modeSelect;
          lcd.clear();
        } else if (key == 'B') {
          mode = true;
          inputState = 0;
          inputDigit = 0;
          inputNumber = 0;
          States = codeStates::modeSelect;
          lcd.clear();
        }
        break;
      }


    case codeStates::modeSelect:
      {
        lcd.setCursor(0, 0);
        lcd.print("A.UnderVoltage     ");
        lcd.setCursor(0, 1);
        lcd.print("B.OverVoltage      ");
        key = customKeypad.getKey();
        if (key == 'A') {
          operationMode = false;
          inputState = 0;
          inputDigit = 0;
          inputNumber = 0;
          States = codeStates::inputVoltage;
          lcd.clear();

        } else if (key == 'B') {
          operationMode = true;
          inputState = 0;
          inputDigit = 0;
          inputNumber = 0;
          States = codeStates::inputVoltage;
          lcd.clear();
        }
        break;
      }


    case codeStates::inputVoltage:
      {
        lcd.setCursor(0, 0);
        lcd.print("Set Voltage:");
        if (inputState < 3) {
          lcd.setCursor(inputState, 1);
        } else if (inputState >= 3) {
          lcd.setCursor(inputState + 1, 1);
        }
        lcd.cursor();
        if (inputState < 5) {
          key = customKeypad.getKey();
          if (key != NO_KEY) {
            if (inputState == 0) {
              inputNumber = (key - '0') * 100;
              inputState = 1;
              inputDigit = key - '0';
              lcd.setCursor(0, 1);
              lcd.print(inputDigit);
            } else if (inputState == 1) {
              inputNumber += (key - '0') * 10;
              inputState = 2;
              inputDigit = key - '0';
              lcd.setCursor(1, 1);
              lcd.print(inputDigit);
            } else if (inputState == 2) {
              inputNumber += key - '0';
              inputState = 3;
              inputDigit = key - '0';
              lcd.setCursor(2, 1);
              lcd.print(inputDigit);
              lcd.setCursor(3, 1);
              lcd.print(".");
            } else if (inputState == 3) {
              inputNumber += (key - '0') * 0.1;
              inputState = 4;
              inputDigit = key - '0';
              lcd.setCursor(4, 1);
              lcd.print(inputDigit);
            } else if (inputState == 4) {
              inputNumber += (key - '0') * 0.01;
              inputState = 5;
              inputDigit = key - '0';
              lcd.setCursor(5, 1);
              lcd.print(inputDigit);
              lcd.setCursor(7, 1);
              lcd.print("V");
            }
            if (inputState == 5) {
              Serial.println(inputNumber);
              lcd.setCursor(0, 1);
              if (inputNumber < 80) {
                inputNumber = 080.00;
              } else if (inputNumber > 260) {
                inputNumber = 260;
              }
              lcd.print(inputNumber);
              lcd.setCursor(7, 1);
              lcd.print("V");
              nextSwitchInterval = 1000;
              States = codeStates::delayDisplay;
              lastSwitchTime = timeMS;
            }
          }
        }
        lcd.noCursor();
        break;
      }


    case codeStates::delayDisplay:
      {
        if ((timeMS - lastSwitchTime) >= nextSwitchInterval) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("A.Enter Again   ");
          lcd.setCursor(0, 1);
          lcd.print("B.Continue          ");
          States = codeStates::againV;
        }
        break;
      }


    case codeStates::againV:
      {
        key = customKeypad.getKey();
        if (key != NO_KEY) {
          if (key == 'A') {
            inputNumber = 0;
            inputState = 0;
            inputDigit = 0;
            States = codeStates::inputVoltage;
            lcd.clear();
          } else if (key == 'B') {
            inputDigit_D = 0;
            inputState_D = 0;
            inputNumber_D = 0;
            if (mode == false) {
              States = codeStates::inputDelay;
            } else if (mode == true) {
              inputDigit_D = 0;
              inputState_D = 0;
              inputNumber_D = 0;
              States = codeStates::inputTMS;
            }
            lcd.clear();
          }
        }
        break;
      }

    case codeStates::inputTMS:
      {
        lcd.setCursor(0, 0);
        lcd.print("TMS:    ");
        //lcd.cursor();
        if (inputState_D < 2) {
          char key = customKeypad.getKey();
          if (key != NO_KEY) {
            if (inputState_D == 0) {
              inputNumber_D += key - '0';
              inputState_D = 1;
              inputDigit_D = key - '0';
              lcd.setCursor(0, 1);
              lcd.print(inputDigit_D);
              lcd.setCursor(1, 1);
              lcd.print(".");
            } else if (inputState_D == 1) {
              inputNumber_D += (key - '0') * 0.1;
              inputState_D = 2;
              inputDigit_D = key - '0';
              lcd.setCursor(2, 1);
              lcd.print(inputDigit_D);
            }
            if (inputState_D == 2) {
              tms = inputNumber_D;
              lcd.setCursor(0, 1);
              lcd.print(tms);
              nextSwitchInterval = 1000;
              States = codeStates::delayDisplay3;
              lastSwitchTime = timeMS;
            }
          }
        }
        lcd.noCursor();
        break;
      }

    case codeStates::delayDisplay3:
      {
        if ((timeMS - lastSwitchTime) >= nextSwitchInterval) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("A.Enter Again   ");
          lcd.setCursor(0, 1);
          lcd.print("B.Continue          ");
          States = codeStates::againTMS;
        }
        break;
      }

    case codeStates::againTMS:
      {
        key = customKeypad.getKey();
        if (key != NO_KEY) {
          if (key == 'A') {
            inputNumber_D = 0;
            inputState_D = 0;
            inputDigit_D = 0;
            States = codeStates::inputTMS;
            lcd.clear();
          } else if (key == 'B') {
            timeDelay = 0;
            States = codeStates::delayCalc;
            lcd.clear();
          }
        }
        break;
      }


    case codeStates::inputDelay:
      {
        lcd.setCursor(0, 0);
        lcd.print("Time Delay:    ");
        if (inputState_D < 2) {
          lcd.setCursor(inputState_D, 1);
        } else if (inputState_D >= 2) {
          lcd.setCursor(inputState_D + 1, 1);
        }
        lcd.cursor();
        if (inputState_D < 4) {
          char key = customKeypad.getKey();
          if (key != NO_KEY) {
            if (inputState_D == 0) {
              inputNumber_D += (key - '0') * 10;
              inputState_D = 1;
              inputDigit_D = key - '0';
              lcd.setCursor(0, 1);
              lcd.print(inputDigit_D);
            } else if (inputState_D == 1) {
              inputNumber_D += key - '0';
              inputState_D = 2;
              inputDigit_D = key - '0';
              lcd.setCursor(1, 1);
              lcd.print(inputDigit_D);
              lcd.setCursor(2, 1);
              lcd.print(".");
            } else if (inputState_D == 2) {
              inputNumber_D += (key - '0') * 0.1;
              inputState_D = 3;
              inputDigit_D = key - '0';
              lcd.setCursor(3, 1);
              lcd.print(inputDigit_D);
            } else if (inputState_D == 3) {
              inputNumber_D += (key - '0') * 0.01;
              inputState_D = 4;
              inputDigit_D = key - '0';
              if (inputNumber_D > 50) {
                inputNumber_D = 50;
              }
              lcd.setCursor(4, 1);
              lcd.print(inputDigit_D);
              lcd.setCursor(6, 1);
              lcd.print("sec");
            }
            if (inputState_D == 4) {
              Serial.println(inputNumber_D);
              lcd.setCursor(0, 1);
              lcd.print(inputNumber_D);
              lcd.setCursor(6, 1);
              lcd.print("sec");
              nextSwitchInterval = 1000;
              States = codeStates::delayDisplay1;
              lastSwitchTime = timeMS;
            }
          }
        }
        lcd.noCursor();
        break;
      }


    case codeStates::delayDisplay1:
      {
        if ((timeMS - lastSwitchTime) >= nextSwitchInterval) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("A.Enter Again   ");
          lcd.setCursor(0, 1);
          lcd.print("B.Continue          ");
          States = codeStates::againD;
        }
        break;
      }

    case codeStates::againD:
      {
        key = customKeypad.getKey();
        if (key != NO_KEY) {
          if (key == 'A') {
            inputNumber_D = 0;
            inputState_D = 0;
            inputDigit_D = 0;
            States = codeStates::inputDelay;
            lcd.clear();
          } else if (key == 'B') {
            timeDelay = 0;
            States = codeStates::delayCalc;
            lcd.clear();
          }
        }
        break;
      }

    case codeStates::delayCalc:
      {
        if (mode == false) {
          timeDelay = inputNumber_D * 1000;
          if (operationMode == false) {
            States = codeStates::underVoltage;
            lcd.clear();
          } else if (operationMode == true) {
            States = codeStates::overVoltage;
            lcd.clear();
          }
        } else if (mode == true) {
          if (operationMode == false) {
            timeDelay = (tms * (0.14 / (1 - pow((act_Voltage / inputNumber), 0.02)))) * 1000;
            States = codeStates::underVoltage;
            lcd.clear();
          } else if (operationMode == true) {
            timeDelay = (tms * (0.14 / (pow((act_Voltage / inputNumber), 0.02) - 1))) * 1000;
            States = codeStates::overVoltage;
          }
        }
        break;
      }

    case codeStates::underVoltage:
      {
        act_Voltage = pzem.voltage();
        if (inputNumber > act_Voltage) {
          digitalWrite(relayPin1, LOW);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0, 1);
          lcd.print(act_Voltage);
          lcd.print(" V U/V");
          digitalWrite(timerPin, HIGH);
          lastSwitchTime = timeMS;
          States = codeStates::delay;
        } else {
          lcd.setCursor(0, 0);
          lcd.print("No Fault:");
          lcd.setCursor(0, 1);
          lcd.print("Normal Voltage");
        }
        break;
      }


    case codeStates::overVoltage:
      {
        act_Voltage = pzem.voltage();
        if (inputNumber < act_Voltage) {
          digitalWrite(relayPin1, LOW);
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Fault Detected:");
          lcd.setCursor(0, 1);
          lcd.print(act_Voltage);
          lcd.print(" V O/V     ");
          digitalWrite(timerPin, HIGH);
          lastSwitchTime = timeMS;
          States = codeStates::delay;
        } else {
          lcd.setCursor(0, 0);
          lcd.print("No Fault:");
          lcd.setCursor(0, 1);
          lcd.print("Normal Voltage");
        }
        break;
      }

    case codeStates::delay:
      {
        if ((timeMS - lastSwitchTime) >= (timeDelay)) {
          if (cont == false) {
            digitalWrite(relayPin2, LOW);
            digitalWrite(timerPin, LOW);
            lcd.setCursor(0, 0);
            lcd.print("Tripped:");
            lcd.print(timeDelay / 1000);
            lcd.print("sec");
            lcd.setCursor(0, 1);
            lcd.print("Press Any Key...");
            cont = true;
          }
          key = customKeypad.getKey();
          if (key != NO_KEY) {
            States = codeStates::delayDisplay2;
          }
        }
        break;
      }

    case codeStates::delayDisplay2:
      {
        if ((timeMS - lastSwitchTime) >= nextSwitchInterval) {
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("A.Restart        ");
          lcd.setCursor(0, 1);
          lcd.print("B.Continue         ");
          States = codeStates::again;
        }
        break;
      }

    case codeStates::again:
      {
        key = customKeypad.getKey();
        if (key != NO_KEY) {
          if (key == 'A') {
            inputNumber = 0;
            inputState = 0;
            inputDigit = 0;
            cont = false;
            States = codeStates::codeStart;
            lcd.clear();
          } else if (key == 'B') {
            inputNumber = 0;
            inputState = 0;
            inputDigit = 0;
            cont = false;
            States = codeStates::inputVoltage;
            lcd.clear();
          }
        }
        break;
      }

    default:
      States = codeStates::codeStart;
      break;
  }
}

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