Please help with my project ASAP

Hello, I am working on Tinkercad with Arduino code and I need help with my project. My project is a keypad with an LED, servo, and button. You have to type in a code (default code rn is 1234) and if it is correct, the LED will turn green and the servo will spin 90 like a latch. If the code is incorrect, the LED will turn red and the servo will not move. The button is back up and if you click it, the servo should turn and the LED should become green.

My problem right now is that I have if else statements so it is if the code is typed correctly or button is clicked, the LED is green and servo moves; else, the LED turns red and servo stays still. But when I start code, the LED immediately turns red and stays that way and when I type in correct code on keypad, nothing changes.

I am a beginner so please explain to me my mistakes and tell me the correct solution specifically. Also, I need to complete this project ASAP! Thank you!

Please share your < CODE/> with the volunteers and we'll see what we can do. :wink:

1 Like
// C++ code
//#include <Wire.h>

#include <Keypad.h>
#include <Servo.h>
//#include <LiquidCrystal_I2C.h>

const int button = A1;//Push Button
int val = 0;

const byte numRows = 4;         //number of rows on keypad
const byte numCols = 4; //number of columns on keypad

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

char keypressed;                 //Where the keys are stored it changes very often
char code[] = {'1', '2', '3', '4'}; //The default code

char check1[sizeof(code)];  //Where the new key is stored
char check2[sizeof(code)];  //Where the new key is stored again so it's compared to the previous one

short x = 0, i = 0, s = 0, y = 0; //Variables used later

byte rowPins[numRows] = {2, 3, 4, 5}; //Rows 0 to 3
byte colPins[numCols] = {6, 7, 8, 9}; //Columns 0 to 3

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Servo myservo;


#define LEDR 10
#define LEDG 13
#define LEDB 12

void setup()
{
  myservo.attach(11);
  pinMode(button, INPUT);
  
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  myservo.write(0);
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);

}


void loop()
{
    val = digitalRead(button);
  
  if (val == HIGH){ //check if val is high - button is pressed
     OpenDoor();
  }
    else {
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);
    }

  keypressed = myKeypad.getKey();               //Constantly waiting for a key to be pressed
  if (keypressed == '*') {                    // * to open the lock
    ReadCode();                          //Getting code function
    if (x == sizeof(code))        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      OpenDoor();

  //Open lock function if code is correct
    //turn led green
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, LOW);
  }
    else {
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);

    delay(2000);
//set led to red
  
  }

}

void ReadCode() {                 //Getting code sequence
  i = 0;                    //All variables set to 0
  x = 0;
  y = 0;

  while (keypressed != '#') {                                   //The user press A to confirm the code otherwise he can keep typing
    keypressed = myKeypad.getKey();
    if (keypressed != NO_KEY && keypressed != '#' ) {     //If the char typed isn't A and neither "nothing"
    //  y++;
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, HIGH);
      if (keypressed == code[i] && i < sizeof(code)) {       //if the char typed is correct a and i increments to verify the next caracter
        x++;
        i++;
      }
      else
        x--;                                               //if the character typed is wrong a decrements and cannot equal the size of code []
    }
  }
  keypressed = NO_KEY;

}


/*void GetNewCode1() {
  i = 0;
  y = 0;
  delay(2000);
  while (keypressed != 'A') {          //A to confirm and quits the loop
    keypressed = myKeypad.getKey();
    if (keypressed != NO_KEY && keypressed != 'A' ) {
      check1[i] = keypressed;   //Store caracters in the array
      i++;
      y++;
    }
  }
  keypressed = NO_KEY;
}

void GetNewCode2() {                        //This is exactly like the GetNewCode1 function but this time the code is stored in another array
  i = 0;
  y = 0;

  while (keypressed != 'A') {
    keypressed = myKeypad.getKey();
    if (keypressed != NO_KEY && keypressed != 'A' ) {
      check2[i] = keypressed;
      i++;
      y++;
    }
  }
  keypressed = NO_KEY;
}*/

void OpenDoor() {
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, LOW);
  myservo.write(90); //
delay (200);


}

This is also a screenshot of my physical project that goes with the code.

This old person reads rn as registered nurse. lol. Best to skip acronyms when possible.

Hi legendarycoder6

try this

void Red() {
    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void Green() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
}

void Off() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void loop() {
  val = digitalRead(button);

  if (val == HIGH) {  //check if val is high - button is pressed
    Green();
    OpenDoor();
  }

  keypressed = myKeypad.getKey();  //Constantly waiting for a key to be pressed
  if (keypressed == '*') {         // * to open the lock
    ReadCode();                    //Getting code function
    if (x == sizeof(code)) {        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      Green();
      OpenDoor();
    }
    else {
      //set led to red for 2 seconds
      Red();
      delay(2000);
      Off();
    }
  }
}

Sorry! Will do

Thank you so much! Now, my LED has stopped turning red instantly, but the keypad with correct code or when the button is pushed still won't make the LED turn green and the servo move. Here is my code right now:

// C++ code
//#include <Wire.h>

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

const int button = A1;//Push Button
int val = 0;

const byte numRows = 4;         //number of rows on keypad
const byte numCols = 4; //number of columns on keypad

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

char keypressed;                 //Where the keys are stored it changes very often
char code[] = {'1', '2', '3', '4'}; //The default code

char check1[sizeof(code)];  //Where the new key is stored
char check2[sizeof(code)];  //Where the new key is stored again so it's compared to the previous one

short x = 0, i = 0, s = 0, y = 0; //Variables used later

byte rowPins[numRows] = {2, 3, 4, 5}; //Rows 0 to 3
byte colPins[numCols] = {6, 7, 8, 9}; //Columns 0 to 3

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Servo myservo;


#define LEDR 10
#define LEDG 13
#define LEDB 12

void setup()
{
  myservo.attach(11);
  pinMode(button, INPUT);
  
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  myservo.write(0);
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);

}

void Red() {
    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void Green() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
}

void Off() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void loop() {
  val = digitalRead(button);

  if (val == HIGH) {  //check if val is high - button is pressed
    Green();
    OpenDoor();
  }

  keypressed = myKeypad.getKey();  //Constantly waiting for a key to be pressed
  if (keypressed == '*') {         // * to open the lock
    ReadCode();                    //Getting code function
    if (x == sizeof(code)) {        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      Green();
      OpenDoor();
    }
    else {
      //set led to red for 2 seconds
      Red();
      delay(2000);
      Off();
    }
  }
}
  

  void ReadCode()  {               //Getting code sequence
  i = 0;                    //All variables set to 0
  x = 0;
  y = 0;

  while (keypressed != '#') {                                   //The user press A to confirm the code otherwise he can keep typing
    keypressed = myKeypad.getKey();
    if (keypressed != NO_KEY && keypressed != '*' ) {     //If the char typed isn't A and neither "nothing"
    //  y++;
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, HIGH);
      if (keypressed == code[i] && i < sizeof(code)) {       //if the char typed is correct a and i increments to verify the next caracter
        x++;
        i++;
      }
      else
        x--;                                             //if the character typed is wrong a decrements and cannot equal the size of code []
    }
  }
  keypressed = NO_KEY;

}

void OpenDoor(){
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, LOW);
  myservo.write(90); //
delay (200);


}

Does it make it red if the code is not correct? Is your button connected properly, it connected to analog, I think it should be connected to digital.

I connected it to digital and the LED still won't turn green and the servo still won't spin. When I type * and then type 1,2, or 3, the LED is blue. And when I reach 4 and type 4, the LED turns red and when I click #, it turns off.

Your breadboard rails are not connected to anything in the picture which means your button is not connected properly. Is that true? You typically connect a 4 pin button using the diagonal corners so it doesn't matter if you rotate the button 90 degrees when installing it on the breadboard. Also better to connect one corner to ground and the other corner to your input pin and declare it as INPUT_PULLUP v. INPUT. This means it will be HIGH when not pressed and LOW when pressed.

Also, you should consider structuring your code like a state machine. You want to detect when a button is pressed, not if a button is pressed. Look at the State Change Detection example in the IDE (File->examples->02. Digital->State Change Detection) to learn how to do it.

If you keep track of what state you are in, you can then react properly when something changes rather than doing the same thing each time through loop()

Use this as a gude legendarycoder6 - Wokwi ESP32, STM32, Arduino Simulator

I incorporated the code, but when I type in code or click button, the LED stays off. And everytime I click *, doesn't matter when, the LED turns blue. This is my code right now:

// C++ code
//#include <Wire.h>

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

const int button = 1;//Push Button
int val = 0;

const byte numRows = 4;         //number of rows on keypad
const byte numCols = 4; //number of columns on keypad

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

char keypressed;                 //Where the keys are stored it changes very often
char code[] = {'1', '2', '3', '4'}; //The default code

char check1[sizeof(code)];  //Where the new key is stored
char check2[sizeof(code)];  //Where the new key is stored again so it's compared to the previous one

short x = 0, i = 0, s = 0, y = 0; //Variables used later

byte rowPins[numRows] = {2, 3, 4, 5}; //Rows 0 to 3
byte colPins[numCols] = {6, 7, 8, 9}; //Columns 0 to 3

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Servo myservo;


#define LEDR 10
#define LEDG 13
#define LEDB 12

void Red() {
    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void Green() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
}

void Blue() {
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, HIGH);
}


void Off() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}


void OpenDoor(){
  Green();
  myservo.write(90);
  delay (200);
}

  bool ReadCode()  {               //Getting code sequence
  char keypressed;
  int i = 0;
  Blue();  
  do {                                   //The user press A to confirm the code otherwise he can keep typing
    keypressed = myKeypad.getKey();
    if (keypressed == code[i] && i < sizeof(code)) {       //if the char typed is correct a and i increments to verify the next caracter
      i++;
    }
    else if (keypressed && keypressed != '#') {
      i = 0;
    }
  } while (keypressed != '#');
  Off();
  return i == sizeof(code);
}


void setup()
{
  Serial.begin(9600);
  while(!Serial);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  Off();
  myservo.attach(11);
  myservo.write(0);
  pinMode(button, INPUT_PULLUP); 
}



void loop() {
  auto val = digitalRead(button);
  if (val == LOW) {  //check if val is high - button is pressed
    OpenDoor();
  }

  char keypressed = myKeypad.getKey();  //Constantly waiting for a key to be pressed
  if (keypressed == '*') {         // * to open the lock                        
    if (ReadCode()) {        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      OpenDoor();
    }
    else {
      //set led to red for 2 seconds
      Red();
      delay(2000);
      Off();
    }
  }
}

These things are all over the internet , tried and proven designs.
Search Google...example ...... https://www.youtube.com/watch?v=vl1-R6NsejM

It might be worthwhile to explore how you power the servo.

the Arduino boards are not ‘power supplies’ for anything but the lightest loads.

Your arrays describing the pin layout for the keypad are wrong. Make sure that your components are connected properly and you can read and write the values. Best way is to use Serial.print() to debug. Serial.print() - Arduino Reference

Which exactly?

Like this?

// C++ code
//#include <Wire.h>

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

const int button = 1;//Push Button
int val = 0;

const byte numRows = 4;         //number of rows on keypad
const byte numCols = 4; //number of columns on keypad

Serial.print();

char keypressed;                 //Where the keys are stored it changes very often
char code[] = {'1', '2', '3', '4'}; //The default code

char check1[sizeof(code)];  //Where the new key is stored
char check2[sizeof(code)];  //Where the new key is stored again so it's compared to the previous one

short x = 0, i = 0, s = 0, y = 0; //Variables used later

byte rowPins[numRows] = {2, 3, 4, 5}; //Rows 0 to 3
byte colPins[numCols] = {6, 7, 8, 9}; //Columns 0 to 3

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
Servo myservo;


#define LEDR 10
#define LEDG 13
#define LEDB 12

void Red() {
    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void Green() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
}

void Blue() {
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, HIGH);
}


void Off() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}


void OpenDoor(){
  Green();
  myservo.write(90);
  delay (200);
}

  bool ReadCode()  {               //Getting code sequence
  char keypressed;
  int i = 0;
  Blue();  
  do {                                   //The user press A to confirm the code otherwise he can keep typing
    keypressed = myKeypad.getKey();
    if (keypressed == code[i] && i < sizeof(code)) {       //if the char typed is correct a and i increments to verify the next caracter
      i++;
    }
    else if (keypressed && keypressed != '#') {
      i = 0;
    }
  } while (keypressed != '#');
  Off();
  return i == sizeof(code);
}


void setup()
{
  Serial.begin(9600);
  while(!Serial);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  Off();
  myservo.attach(11);
  myservo.write(0);
  pinMode(button, INPUT_PULLUP); 
}



void loop() {
  auto val = digitalRead(button);
  if (val == LOW) {  //check if val is high - button is pressed
    OpenDoor();
  }

  char keypressed = myKeypad.getKey();  //Constantly waiting for a key to be pressed
  if (keypressed == '*') {         // * to open the lock                        
    if (ReadCode()) {        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      OpenDoor();
    }
    else {
      //set led to red for 2 seconds
      Red();
      delay(2000);
      Off();
    }
  }
}

So, everything in my code works including my LED, except my servo, which won't turn. This is my code below:

#include <Keypad.h>
#include <Servo.h>

byte rowPins[] = {9, 8, 7, 6}; //Rows 0 to 3
byte colPins[] = {5, 4, 3, 2}; //Columns 0 to 3

char keymap[sizeof(rowPins)][sizeof(colPins)] =
{
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, sizeof(rowPins), sizeof(colPins));
Servo myservo;

char code[] = {'1', '2', '3', '4'}; //The default code

#define LEDR 10
#define LEDG 13
#define LEDB 12

void Red() {
    digitalWrite(LEDR, HIGH);
    digitalWrite(LEDG, LOW);
    digitalWrite(LEDB, LOW);
}

void Green() {
    digitalWrite(LEDR, LOW);
    digitalWrite(LEDG, HIGH);
    digitalWrite(LEDB, LOW);
}

void Blue() {
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, HIGH);
}

void Off() {
  digitalWrite(LEDR, LOW);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDB, LOW);
}

void OpenDoor(){
  Green();
  myservo.write(90);
  delay (200);
}

bool ReadCode()  {          //Getting code sequence
  char keypressed;
  int i = 0;
  Blue();  
  do {                                   //The user press A to confirm the code otherwise he can keep typing
    keypressed = myKeypad.getKey();
    if (keypressed == code[i] && i < sizeof(code)) {       //if the char typed is correct a and i increments to verify the next caracter
      i++;
    }
    else if (keypressed && keypressed != '#') {
      i = 0;
    }
  } while (keypressed != '#');
  Off();
  return i == sizeof(code);
}

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  Off();
  myservo.attach(11);
  myservo.write(0);
}

void loop() {

  char keypressed = myKeypad.getKey();  //Constantly waiting for a key to be pressed
  if (keypressed == '*') {         // * to open the lock                        
    if (ReadCode()) {        //The ReadCode function assign a value to a (it's correct when it has the size of the code array)
      OpenDoor();
    }
    else {
      //set led to red for 2 seconds
      Red();
      delay(2000);
      Off();
    }
  }
}

It works in the emulator, correct? Make sure your connections and code match the emulator