Reading 12 inputs

Hello,

I recently made a safe with 4 characters, an enter button, and a clear button. However, I want to take it up a notch using blynk and be able to enter all 10 characters, plus the two other buttons. However, sending signals through arduino pins will take up all of my Uno pins, and not leave any room for the lock mechanism or LCD display. Is there a way to read 12 virtual pin states and then use that data for my project? Here’s my code without Blynk:

#include <Liquid.Crystal.h>
#include <EEPROM.h>
#include <Servo.h>

int address = 0;
static unsigned long SaveTimer;                
static unsigned long SaveDelay = (30 * 1000); 

char CODE[10] = "123142E";  //change password here   
char Str[10]; 
char CodeLength = 6;
int Pos = 0;

bool Unlocked;
static unsigned long DisplayTimer; 
static unsigned long DisplayDelay = 200;

LiquidCrystal lcd(12, 11, 9, 8, 7, 6); 

int buttonPin1 = 2;   
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;
int enterbutton = 10; 
int clearlockbutton = 13;

Servo myServo;                    

void setup() {

  myServo.attach(A1);  

  Lock();

  int EEPROMCodeOK = true;

  for (Pos = 0; Pos <= (CodeLength); Pos++) {

    Str[Pos] =  EEPROM.read(Pos);

    if (!(strrchr("1123456789", Str[Pos]))) { 

      EEPROMCodeOK = false;

    }

  }

  Pos++;
  Str[Pos] =  EEPROM.read(Pos); 

  if (Str[CodeLength + 1] != 'E') EEPROMCodeOK = false; 

  if (EEPROMCodeOK) {

    Str[CodeLength + 2] = '\0';
    strncpy(CODE, Str, CodeLength + 1);

  }

  ClearCode();

  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(enterbutton, INPUT_PULLUP);
  pinMode(clearlockbutton, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Hello.");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Password:");
  DisplayTimer = millis() + 200;

}

void loop() {

  Lock();

  Pos = constrain(Pos, 0, CodeLength);

  int buttonState1 = digitalRead(buttonPin1);  
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);

  int clButtonState = digitalRead(clearlockbutton);
  int enterButtonState = digitalRead(enterbutton);

  lcd.setCursor(9, 0);

  if (buttonState1 == LOW) {

    Str[Pos] = '1';

    Pos++;
    Str[Pos] = '\0';
    delay(250); 

    while (digitalRead(buttonPin1) == LOW); 

  }

  else if (buttonState2 == LOW) {

    Str[Pos] = '2';

    Pos++;
    Str[Pos] = '\0';
    delay(250); 

    while (digitalRead(buttonPin2) == LOW);

  }

  else if (buttonState3 == LOW) {

    Str[Pos] = '3';

    Pos++;
    Str[Pos] = '\0';
    delay(250); 
    while (digitalRead(buttonPin3) == LOW);

  }

  else if (buttonState4 == LOW) {

    Str[Pos] = '4';
    Pos++;
    Str[Pos] = '\0';
    delay(250); 

    while (digitalRead(buttonPin4) == LOW); 

  }

  else if (enterButtonState == LOW) {

    Str[Pos] = 'E';
    Pos++;

    Str[Pos] = '\0';
    delay(250);
    lcd.setCursor(15, 0);
    lcd.print("E");
    delay(400);
    lcd.setCursor(15, 0);
    lcd.print(" ");

    while (digitalRead(buttonPin1) == LOW); 

     if (strcmp (Str,CODE) == 0) {

      Unlocked = true;
      lcd.setCursor(0, 0);
      lcd.print(" Access Granted");
      delay(2000);

      lcd.clear();
      lcd.print("    Unlocked");

    } 

    else { 

      lcd.clear();
      lcd.print(" Access Denied.");
      delay(2000);
      lcd.clear();
      lcd.print("Password:");

    }

    while (Unlocked) {

      Unlock();

      if (digitalRead(clearlockbutton) == LOW) {

        delay(200);
        lcd.clear();
        lcd.print("     Locked");
        delay(2000);
        lcd.clear();
        Unlocked = false;
        SaveTimer = millis() + 30000;

      }

    }

    ClearCode();

  }

  else if (clButtonState == LOW) {

    delay(500);

    while (clearlockbutton == LOW);

    if ((millis() - SaveTimer) > 4500) {

    }

    ClearCode();

  }

  if ( (long)( millis() - DisplayTimer ) >= 0) {

    DisplayTimer += DisplayDelay;

    lcd.setCursor(9, 0); 
    lcd.print(Str);
    lcd.setCursor(15, 0);
    lcd.print(" ");

    if (clButtonState == LOW) {

      lcd.clear();
      lcd.print("Password:");

    }

  }

}

void ClearCode() {

  Pos = 0;
  Str[Pos] = '\0';

  lcd.setCursor(0, 0);
  lcd.print("Password:");
  lcd.setCursor(0, 1);
  lcd.print("          ");

}

void Unlock() {

  myServo.write(117);

}

void Lock() {

  myServo.write(26);

}

Guidance and links would be much appreciated. Thanks,

marco

You can use virtual pins - something like this:

BLYNK_WRITE(V1) 
{          
      Str[Pos] = '1';
      Pos++;
      Str[Pos] = '\0';
      Pos = constrain(Pos, 0, CodeLength);
}
//etc x 12

void loop() {
    Blynk.run();
    if (strcmp (Str,CODE) == 0) {
        Unlocked = true;
        ...
    } else { 
       ...
    }
}

If you’re smart you can use functions to eliminate the tedious repetition.
(You should also remove the other delays in your code. use Simple Timers instead.)

Though have you considered using the Terminal widget? It’s much better for sending strings!

Thanks for the response! What you said make a lot of sense and I was thinking along the same lines of that. I didn’t know about the Terminal Widget, I’ll look into that too!

Thanks,

marco