Multiple Void Loop ..

I’m trying to get a modified code from a tutorial to have multiple loops… is it possible?

void loop()
{
  int l;
  
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(12,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode4[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 3)
        {
          unlockDoor4();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
    
  }
}

I want it to have multiple answers for the definition of the input code:

//set our code
char* ourCode = "123A";
int currentPosition = 0;

char* ourCode4 = "145";
int currentPosition4 = 0;

Why cant i just do the following?

void loop()
{
  int l;
  
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(12,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode4[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 3)
        {
          unlockDoor4();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
     if (key == ourCode[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 4)
        {
          unlockDoor();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
  }
}

Full Code here:

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

//constants for LEDs
int greenLED = 12;
int redLED = 13;

//set our code
char* ourCode = "123A";
int currentPosition = 0;

char* ourCode4 = "145";
int currentPosition4 = 0;

//define the keypad
const byte rows = 4;
const byte cols = 4;

char keys[rows][cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[rows] = {11,10,9,8};
byte colPins[cols] = {7,6,5,4};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

#define GPIO_ADDR   0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);    // set the LCD I2C address

void setup() {

lcd.begin(16,2);

}

void loop()
{
  int l;
  
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(12,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode4[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 3)
        {
          unlockDoor4();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
    
  }
}

void invalidCode()
{
  digitalWrite(redLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("No Letter Found");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("");
  
  delay(2000);
  digitalWrite(redLED, LOW);
  displayCodeEntryScreen();
}

void unlockDoor()
{
  digitalWrite(greenLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("**  WELCOME!  **");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("********************");
  
  "1235" ;//add any code to unlock the door here
  delay(2000);
  digitalWrite(greenLED, LOW);
  displayCodeEntryScreen();
}

void unlockDoor4()
{
  digitalWrite(greenLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("*  Letter: D  *");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("");
  
  "145" ; //add any code to unlock the door here
  delay(5000);
  digitalWrite(greenLED, LOW);
  displayCodeEntryScreen();
}


void displayCodeEntryScreen()
{
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("Tactus");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("Enter:");
}

void clearScreen()
{
  lcd.setCursor(0,0);
  lcd.print("                    ");
  lcd.setCursor(0,1);
  lcd.print("                    ");
  lcd.setCursor(0,2);
  lcd.print("                    ");
  lcd.setCursor(0,3);
  lcd.print("                    ");

Why cant i just do the following?

What happens when you try ?

What’s the purpose of unlockDoor()…it’s never called. Also, clearScreen() is missing its closing parenthesis and could also be written:

void clearScreen()
{
  for (int i = 0; i < rows; i++) {

     lcd.setCursor(0,i);
     lcd.print("                    ");
  }
}

I don’t have a hex pad, so I can’t test the code.

It tells me unlock door is not declared…

void loop()
{
  int l;
  
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(12,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode4[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 3)
        {
          unlockDoor();
          currentPosition = 0;
        }
        if (key == ourCode[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 4)
        {
          unlockDoor();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
    
  }
}

Error:
C:\Users\q\Documents\Arduino\Tuesday_Morning_Working2\Tuesday_Morning_Working2.ino: In function ‘void loop()’:
Tuesday_Morning_Working2:62: error: ‘unlockDoor’ was not declared in this scope

  • unlockDoor();*
  • ^*
    Tuesday_Morning_Working2:70: error: ‘unlockDoor’ was not declared in this scope
  • unlockDoor();*
  • ^*
    Tuesday_Morning_Working2:74: error: ‘invalidCode’ was not declared in this scope
  • invalidCode();*
  • ^*
    Tuesday_Morning_Working2:82: error: a function-definition is not allowed here before ‘{’ token
    {
    ^
    Tuesday_Morning_Working2:100: error: a function-definition is not allowed here before ‘{’ token
    {
    ^
    Tuesday_Morning_Working2:119: error: a function-definition is not allowed here before ‘{’ token
    {
    ^
    Tuesday_Morning_Working2:139: error: a function-definition is not allowed here before ‘{’ token
    {
    ^
    Tuesday_Morning_Working2:150: error: a function-definition is not allowed here before ‘{’ token
    {
    ^
    Tuesday_Morning_Working2:159: error: expected ‘}’ at end of input
    }
    ^
    exit status 1
    ‘unlockDoor’ was not declared in this scope

Please post the full program that generates the errors.

And this line is supposed to do.... what?

"1235" ;//add any code to unlock the door here

Regards,
Ray L.

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

//constants for LEDs
int greenLED = 12;
int redLED = 13;

//set our code
char* ourCode = "123A";
int currentPosition = 0;

char* ourCode4 = "145";
int currentPosition4 = 0;

//define the keypad
const byte rows = 4;
const byte cols = 4;

char keys[rows][cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[rows] = {11,10,9,8};
byte colPins[cols] = {7,6,5,4};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

#define GPIO_ADDR   0x27
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);    // set the LCD I2C address

void setup() {

lcd.begin(16,2);

}

void loop()
{
  int l;
  
  char key = keypad.getKey();
  
  if (int(key) != 0) {
    lcd.setCursor(14,3);
    lcd.print("    ");
    lcd.setCursor(12,3);
    
    for (l=0; l<=currentPosition; ++l)
    {
      lcd.print("*");
    }
    
    if (key == ourCode4[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 3)
        {
          unlockDoor4();
          currentPosition = 0;
        }
         if (key == ourCode[currentPosition])
      {
        ++currentPosition;
        if (currentPosition == 4)
        {
          unlockDoor();
          currentPosition = 0;
        }
      } else {
        invalidCode();
        currentPosition = 0;
      }
    
  }
}

void invalidCode()
{
  digitalWrite(redLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("No Letter Found");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("");
  
  delay(2000);
  digitalWrite(redLED, LOW);
  displayCodeEntryScreen();
}

void unlockDoor()
{
  digitalWrite(greenLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("**  WELCOME!  **");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("");
  
  "1235" ;//add any code to unlock the door here
  delay(2000);
  digitalWrite(greenLED, LOW);
  displayCodeEntryScreen();
}

void unlockDoor4()
{
  digitalWrite(greenLED, HIGH);
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("*  Letter: D  *");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("");
  lcd.setCursor(0,3);
  lcd.print("");
  
  "145" ; //add any code to unlock the door here
  delay(5000);
  digitalWrite(greenLED, LOW);
  displayCodeEntryScreen();
}


void displayCodeEntryScreen()
{
  clearScreen();
  lcd.setCursor(0,0);
  lcd.print("Tactus");
  lcd.setCursor(0,1);
  lcd.print("");
  lcd.setCursor(0,2);
  lcd.print("Enter:");
}

void clearScreen()
{
  for (int i = 0; i < rows; i++) {

     lcd.setCursor(0,i);
     lcd.print("                    ");
  }
}

Hi Ray, thats nonsense from the original code… so nothing

Where does the loop() function end ?
Auto Formatting the code (Ctrl/T in the IDE) shows the problem immediately.

My Auto format says no changes necessary? Does the loop not end before void invalidCode() ?

When I copy the code you posted into the IDE and Auto Format it the message is "Auto Format finished"

Does the loop not end before void invalidCode() ?

Not in the version that you posted.

After Auto Format

    }
  }

  void invalidCode()
  {

Note that the void keyword is not on the left margin.

How would I fix this?

Put a closing brace at the end of the loop() function.

Thanks! And the issue with it saying that I haven't declared unlockdoor4.. it's confusing me

Where did you put the closing brace for the loop() function ?
With it in the correct place the code compiles for me, although I can't guarantee that it actually works.

Aha! It compiles on mine now thanks.. Really hates it more now though.

Please explain why you think that comparing the key against ourcode[CurrentPosition] will ever be executed (when currentPosition equals 1) and the second key was anything but 4.

    if (key == ourCode4[currentPosition])
    {
      ...
      ...
      if (key == ourCode[currentPosition])

The second test will only be executed if the first test passes. But unless the characters are the same, the second test will always fail.

Your approach is basically wrong; it will be difficult to maintain if you add more codes (you were already having problems :wink: ).

First of all, I would wait for a complete input by the user and not check character by character. You can write a function for that to keep things organised.

/*
  read keypad
  return user input when maximum number of characters is reached or '#' is entered, else NULL
*/
char* getPincode()
{
  // buffer to store keystrokes; max MAXPINSIZE keystrokes and terminating null character
  static char userInput[MAXPINSIZE + 1];
  // character index in keystroke buffer
  static byte index = 0;

  // if index equals 0
  if(index == 0)
  {
    // remove previous content
    memset(userInput, 0, sizeof(userInput);
  }

  // read a key
  char key = keypad.getKey();

  // if there was a key
  if (key != NO_KEY)
  {
    // store in keystroke buffer and increment index
    userInput[index++] = key;
  }

  // if MAXPINSIZE characters entered or less characters followed by '#'
  if (index == MAXPINSIZE || key == '#')
  {
    // replace # by null terminator if needed
    if (key == '#')
    {
      userInput[index - 1] = '\0';
    }
    // reset index for next read
    index = 0;

    // return user input
    return userInput;
  }

  // user input not complete yet
  return null;
}

Next I would use a multidimensional character array to store the valid pincodes; you can place the below just before the setup() function (as shown).

...
...

// number of pin codes
#define NUMPINCODES 2
// maximum size of pin code
#define MAXPINSIZE  4
// the pin codes; for each pinCode, we allocate on extra char for a terminating null character
char pinCodes[NUMPINCODES][MAXPINSIZE + 1] = {
  "123",
  "4567"
};

void setup()
{
  ...
  ...
}

Next we can write a function to compare the entered pincode against the above pincodes

/*
  validate pinCode; compares a given pin code with the 'valid' pin codes
  returns true if the pinCode exists in pinCodes, else false
*/
bool validatePincode(char* pinCode)
{
  // for each pin code in pinCodes
  for (int cnt = 0; cnt < NUMPINCODES; cnt++)
  {
    // compare
    if (strcmp(pinCode, pinCodes[cnt]) == 0)
    {
      // got it
      return true;
    }
  }
  // not found
  return false;
}

And lastly we can use the two new functions in loop()

void loop()
{
  // read pincode
  char* pinCode = getPincode();

  // if user input complete
  if (pinCode != null)
  {
    // validate entry
    if (validatePincode(pinCode) == true)
    {
      // open door
    }
    else
    {
      // keep door locked
    }
  }
}