Timer will not work alongside password entry

/*
   please not that String.remove(); is EXTREMELY useful for
   removing excess characters on LCD that overflow into
   other code stages even after pressing "*"
*/
#include <TM1637.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x26, 16, 3);

String tms;

String ipass;
String ipass2;
String ipass3;
String ipass4;

int timer = -2;
int disarm = 1;

int code_pos = -1;
int code_pos2 = -1;

const int ROW_NUM = 4;
const int COLUMN_NUM = 4;

const String rand1 = "4478";
const String rand2 = "6940";
const String rand3 = "3312";
const String rand4 = "1675";

char inputSequence[4] = "    ";

int inputNumber = -1;
int inputNumber2 = 0;
int inputNumber3 = 0;
int inputNumber4 = 0;


char keys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};

byte pin_rows[ROW_NUM] = {34, 36, 38, 40};
byte pin_column[COLUMN_NUM] = {26, 28, 30, 32};

Keypad customKeypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );

int CLK = 45;
int DIO = 43;

TM1637 tm(CLK, DIO);

const int ledPin =  LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

void setup() {

  ipass.reserve(32);
  ipass2.reserve(32);
  ipass3.reserve(32);
  ipass4.reserve(32);

  lcd.init();
  lcd.clear();
  lcd.backlight();

  tm.init();
  tm.set(2);
  tm.display(3, 0);

  lcd.setCursor(3, 0);
  lcd.print("Enter SECONDS!");
  lcd.setCursor(7, 2);
  lcd.print("{");
  lcd.setCursor(12, 2);
  lcd.print("}");
  lcd.setCursor(2, 3);
  lcd.print("Press # to ENTER");
  lcd.setCursor(8, 2);
}

void loop() {

  if (code_pos2 == -1) {
    char keyT = customKeypad.getKey();
    if (keyT) {
      lcd.setCursor(8, 2);

    }
    if (keyT == '0') {
      tms = tms + 0;
      lcd.print(tms);
    }
    if (keyT == '1') {
      tms = tms + 1;
      lcd.print(tms);
    }
    if (keyT == '2') {
      tms = tms + 2;
      lcd.print(tms);
    }
    if (keyT == '3') {
      tms = tms + 3;
      lcd.print(tms);
    }
    if (keyT == '4') {
      tms = tms + 4;
      lcd.print(tms);
    }
    if (keyT == '5') {
      tms = tms + 5;
      lcd.print(tms);
    }
    if (keyT == '6') {
      tms = tms + 6;
      lcd.print(tms);
    }
    if (keyT == '7') {
      tms = tms + 7;
      lcd.print(tms);
    }
    if (keyT == '8') {
      tms = tms + 8;
      lcd.print(tms);
    }
    if (keyT == '9') {
      tms = tms + 9;
      lcd.print(tms);
    }
    if (keyT == '#') {
      timer = tms.toInt();
      timer = timer + 1;

      lcd.clear();
      delay(2000);
      lcd.setCursor(0, 0);
      lcd.print(rand1);
      lcd.setCursor(5, 0);
      lcd.print(rand2);
      lcd.setCursor(10, 0);
      lcd.print(rand3);
      lcd.setCursor(15, 0);
      lcd.print(rand4);

      lcd.setCursor(4, 0);
      lcd.print('|');
      lcd.setCursor(4, 1);
      lcd.print('|');
      lcd.setCursor(4, 2);
      lcd.print('|');
      lcd.setCursor(4, 3);
      lcd.print('|');

      lcd.setCursor(9, 0);
      lcd.print('|');
      lcd.setCursor(9, 1);
      lcd.print('|');
      lcd.setCursor(9, 2);
      lcd.print('|');
      lcd.setCursor(9, 3);
      lcd.print('|');

      lcd.setCursor(14, 0);
      lcd.print('|');
      lcd.setCursor(14, 1);
      lcd.print('|');
      lcd.setCursor(14, 2);
      lcd.print('|');
      lcd.setCursor(14, 3);
      lcd.print('|');
      code_pos2 = 0;
      code_pos = 0;
    }
    if (keyT == '*') {
      tms.remove(0, 32);
    }
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (timer >= 0) {
      timer--;
      int sec = timer;
      int mins = sec / 60;
      int secs = sec % 60;
      tm.display(3, secs % 10);
      tm.display(2, secs / 10 % 10);
      tm.point(1);
      tm.display(1, mins % 10);
      tm.display(0, mins / 10 % 10);
      if (timer == -1) {
        //disarm = 0;//USE THIS LATER FOR DISARMING FMP!
        tm.display(3, 0);
      }
    }
  }
}
void passv() {
  if (code_pos == 0) {
    tms.remove(0, 4);
    char key = customKeypad.getKey();
    if (key) {

      inputSequence[inputNumber] = customKeypad.getKey();
      inputNumber++;
      lcd.setCursor(inputNumber, 3);
      lcd.print(key);
      if (key == '*') {
        lcd.setCursor(0, 3);
        lcd.print("    ");
        inputNumber = -1;
        ipass = "";
      }
      else if (key == '#') {
        if (rand1 == ipass) {

          lcd.setCursor(4, 3);
          lcd.print("|");
          lcd.setCursor(0, 1);
          lcd.print("crct");
          code_pos = 1;
        }
        else {

          lcd.setCursor(0, 2);
          lcd.print("icrt");
          lcd.setCursor(0, 3);
          lcd.print("    ");
          inputNumber = -1;
        }
        ipass = "";
      }
      else {
        ipass += key;
      }
    }
  }
  if (code_pos == 1) {
    char key2 = customKeypad.getKey();
    if (key2) {
      inputSequence[inputNumber2] = customKeypad.getKey();
      inputNumber++;
      lcd.setCursor(inputNumber, 3);
      lcd.print(key2);

      if (key2 == '*') {
        lcd.setCursor(5, 3);
        lcd.print("    ");
        inputNumber = 4;
        ipass2 = "";
      }
      else if (key2 == '#') {
        if (rand2 == ipass2) {

          lcd.setCursor(9, 3);
          lcd.print("|");
          lcd.setCursor(5, 1);
          lcd.print("crct");
          code_pos = 2;
        }
        else {

          lcd.setCursor(5, 2);
          lcd.print("icrt");
          lcd.setCursor(5, 3);
          lcd.print("    ");
          inputNumber = 4;
        }
        ipass2 = "";
      }
      else {
        ipass2 += key2;
      }
    }
  }
  if (code_pos == 2) {
    char key3 = customKeypad.getKey();
    if (key3) {
      inputSequence[inputNumber3] = customKeypad.getKey();
      inputNumber++;
      lcd.setCursor(inputNumber, 3);
      lcd.print(key3);

      if (key3 == '*') {
        lcd.setCursor(10, 3);
        lcd.print("    ");
        inputNumber = 9;
        ipass3 = "";
      }
      else if (key3 == '#') {
        if (rand3 == ipass3) {

          lcd.setCursor(14, 3);
          lcd.print("|");
          lcd.setCursor(10, 1);
          lcd.print("crct");
          code_pos = 3;
        }
        else {

          lcd.setCursor(10, 2);
          lcd.print("icrt");
          lcd.setCursor(10, 3);
          lcd.print("    ");
          inputNumber = 9;
        }
        ipass3 = "";
      }
      else {
        ipass3 += key3;
      }
    }
  }
  if (code_pos == 3) {
    char key4 = customKeypad.getKey();
    if (key4) {
      inputSequence[inputNumber4] = customKeypad.getKey();
      inputNumber++;
      lcd.setCursor(inputNumber, 3);
      lcd.print(key4);

      if (key4 == '*') {
        lcd.setCursor(15, 3);
        lcd.print("    ");
        inputNumber = 14;
        ipass4 = "";
      }
      else if (key4 == '#') {
        if (rand4 == ipass4) {

          lcd.setCursor(19, 3);
          lcd.print("|");
          lcd.setCursor(15, 1);
          lcd.print("crct");
          code_pos = 4;
        }
        else {

          lcd.setCursor(15, 2);
          lcd.print("icrt");
          lcd.setCursor(15, 3);
          lcd.print("    ");
          inputNumber = 14;
        }
        ipass4 = "";
      }
      else {
        ipass4 += key4;
      }
    }
  }
}

this is code for an objective device for airsoft/paintball. the objective is for attackers to "diffuse" said device by entering a 4-stage, 4-digit password that is provided by the LCD. alongside this the timer HAS TO control a TM1637 and actively count down while im able to enter these codes and have them verified for being correct. the timer WILL start AND operate properly, but the code verification barely works due to some blockage caused by the timer. i have tried everything that i could find to try to get around this and i cant figure it out. if i spam a keypad button, it will EVENTUALLY print the number and allow the code in void passv to operate. void passv was an attempt at trying to see if i can solve the issue and somehow work it out. there was an issue beforehand where it would get hung on the cursor of keyT and cause the time entered to be intertwined with the 4-stage code and cause it to return as incorrect due to the time being included. void passv fixed that issue and made my code easier to modify/follow.

One mistake that I immediately see that will cause havoc and should be fixed first. Not saying that it will your problem.

char inputSequence[4] = "    ";

To store 4 spaces in a so-called c-string, you need an array of 5 characters.

char inputSequence[5] = "    ";

the code SURPRISINGLY worked flawlessly the way it was. i created the timer and pass portion separately then merged them together. ill check that out after i get the code complete and see what difference it makes.

i doubt anyone is going to want to comb through 359 lines of code so i doubt anyone is going to solve it

$10 cashapp for anyone willing to solve this. i have spent hours upon hours of planning and research to build this and im out of options. next step im about to take is to use the built in timer but what fun is that?

Mixing these coding techniques in the loop( ) is not a good idea.

Do I understand correctly. Your basic problem is that you want simultaneously to display a countdown on the LCD while also displaying a password which the user may be in the process of entering?

You're right. So let's see if we can teach you some techniques to shrink it first. Here's one:

    if (keyT == '0') {
      tms = tms + 0;
      lcd.print(tms);
    }
    ...
    if (keyT == '9') {
      tms = tms + 9;
      lcd.print(tms);
    }

can be reduced to:

    if (keyT >= '0' && ketT <= '9') {
      tms = tms + keyT - '0';
      lcd.print(tms);
    }

very helpful! my goal was to get a working code THEN study on how to improve it. i really need something to run WITH the password portion while the timer counts down.

That's just luck :wink: I think because you never acess anything but the first element (but might be mistaken).

I think that most of the more experienced users here have combed through more to solve problems :wink:
.

Here's another: any time you find yourself making variables or constants with digits in their names, you should probably be using an array.

const String rand1 = "4478";
const String rand2 = "6940";
const String rand3 = "3312";
const String rand4 = "1675";

becomes

const String rand[4] = { "4478", "6940", "3312", "1675" };

exit status 1
no match for 'operator-' (operand types are 'StringSumHelper' and 'char')

that is the error it gave me. ill figure it out later

i have it set up like that because im eventually adding 4 random number generators. in order to make that easy to come back to i assigned them like that

lol... wow 359.

If I hit the "#" key... then this will never be true will it?

  if (code_pos2 == -1) 
1 Like

i use that to terminate the keypad for keyT considering it uses a different method to append to the TM1637. keyT interfered with passv. its supposed to be false. if i didnt declare code_pos2 = 0, then the cursor AND data will hang up.

What? If you were able to articulate your problem in a clearer way, you might find someone that understands what you are trying to say.

int code_pos2 = -1;

... that you now don't call?

Oops!

Maybe

const String rand[4] = { String("4478"), String("6940"), String("3312"), String("1675") };
1 Like

i did call it but you apparently didnt find it. let me make this easier for you

        lcd.setCursor(9, 0);
        lcd.print('|');
        lcd.setCursor(9, 1);
        lcd.print('|');
        lcd.setCursor(9, 2);
        lcd.print('|');
        lcd.setCursor(9, 3);
        lcd.print('|');
  
        lcd.setCursor(14, 0);
        lcd.print('|');
        lcd.setCursor(14, 1);
        lcd.print('|');
        lcd.setCursor(14, 2);
        lcd.print('|');
        lcd.setCursor(14, 3);
        lcd.print('|');
        code_pos2 = 0;
        code_pos = 0;

that can be found within if (code_pos2 == -1)

Can't see where that code calls passv ? Maybe I'm missing something?

1 Like

yes. i called it as void it was causing the lcd screen to clear but i just solved that so i may can call it with the timer but it will most likely fail me