Lock with Passcode

I've been working on a project in school and I've ran into an issue.

This project includes 4 buttons, an LCD screen, and a servo motor. The idea is that when button 1 is pressed, the number 1 will be displayed. As follows with 2, 3, and 4. Then, if the correct code is entered, a servo motor will turn, to unlock the door.

So far, my lcd screen is set up, as well as my four buttons. The code is written just to display numbers when the buttons are typed. However, when I upload the code, 'Hello.' is printed and cleared after 2 seconds as planned, but then '1234' immediately is displayed afterwards.

#include <LiquidCrystal.h>

int buttonPin1= 6;    //sets pins buttons are connected to
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;

const int buttonState1 = 0;
const int buttonState2 = 0;
const int buttonState3 = 0;
const int buttonState4 = 0;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //sets pins lcd is connected to, running in 4 bit mode, RW pin tied to gnd

void setup() {
  
  pinMode(buttonPin1, INPUT);  //assigns button pins as inputs
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);


  lcd.begin(16, 2); //screen size
  lcd.print("  Hello."); //introduction
  delay(2000); //delay
  lcd.clear(); //clears screen
  
}


void loop() {

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

  lcd.setCursor(0, 0); 
  
  if(buttonState1 == HIGH) {
    lcd.print("1");  //if button 1 is pressed, print 1. 
    delay(250);
    
  }
  
  if(buttonState2 == HIGH) {
    lcd.print("2"); //if button 2 is pressed, print 2. 
    delay(250);
    
  }  
  
  if(buttonState3 == HIGH) {
    lcd.print("3"); //if button 3 is pressed, print 3. 
    delay(250);
    
  }  
  
  if(buttonState4 == HIGH) {
    lcd.print("4"); //if button 4 is pressed, print 4. 
    delay(350);
   
  }

}

Why is that the outcome? Is it a coding error, or a circuit error?

Each button is connected to power, and on the other end, it is connected to ground, and their repective arduino pins. Any help would be greatly appreciated!

Your buttons are floating, they need a pull down resistor to ground. Google can help with a wiring diagram.

HazardsMind:
Your buttons are floating, they need a pull down resistor to ground. Google can help with a wiring diagram.

Thank you for the tip. I'll look into it.

#include <LiquidCrystal.h>

int buttonPin1= 6;    //sets pins buttons are connected to
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //sets pins lcd is connected to

void setup() {
  
  pinMode(buttonPin1, INPUT);  //assigns button pins as inputs
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);


  lcd.begin(16, 2); //screen size
  lcd.setCursor(0, 0);
  lcd.print("Hello."); //introduction
  delay(2000); //delay
  lcd.clear(); //clears screen
  
}


void loop() {

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

  
  if(buttonState1 == HIGH) {
    lcd.print("1");  //if button 1 is pressed, print 1. 
    delay(250);
    
  }
  
  else if(buttonState2 == HIGH) {
    lcd.print("2"); //if button 2 is pressed, print 2. 
    delay(250);

  }

  else if(buttonState3 == HIGH) {
    lcd.print("3"); //if button 3 is pressed, print 3. 
    delay(250);
    
  }  
  
  else if(buttonState4 == HIGH) {
    lcd.print("4"); //if button 4 is pressed, print 4. 
    delay(350);
   
  }

}

Now, after the Hello sequence, the number 2 is spammed.

If that is how you have it wired, it is wrong. The resistor needs to be on the same wire going to the Arduino. Just move them over to the other side on where you have them connected to the button.

HazardsMind:
If that is how you have it wired, it is wrong. The resistor needs to be on the same wire going to the Arduino. Just move them over to the other side on where you have them connected to the button.

That's how it was originally, and you said it was 'floating'. I'll move them back and see what happens.

Now, after the "hello", 1 is repeatedly spammed on the screen. I think it's a coding issue. I just don't know what.

Your first description sounded exactly like floating buttons. Use the serial monitor to show he states of your buttons. See if any are a 1 when they shouldn't be.

HazardsMind:
Your first description sounded exactly like floating buttons. Use the serial monitor to show he states of your buttons. See if any are a 1 when they shouldn't be.

With the resistors set up like you instructed, all 4 buttons are floating according to the Serial Monitor.


If this still doesn't work then the problem may be with the arduino board itself.

OK, let's go through a few things here.

In general, you do not connect buttons to the 5 V Vcc.

OK, I know the tutorials here tend to show that, but unfortunately due to the way the website is run, they cannot be replaced with corrected versions.

The proper way to connect the buttons is from a pin to ground. While you can then use pull-up resistors to Vcc, the ATmega chip is especially designed to provide an internal pull-up resistor (of the order of 35k) for you by using the INPUT_PULLUP function in pinMode (effectively setting them as inputs but then writing them HIGH). You may need to provide "stronger" pull-ups of lower resistance in some situations.

Now of course, this means that the pins will read LOW with the respective button pressed, so you need to write your logic accordingly. Purportedly, beginners might find this somewhat difficult to conceptualise which is why many tutorials describe using pull-downs and buttons connected to Vcc, but that is an extremely bad practice to exemplify as the concept of negative logic is elemental to programming.

Now for some reason you show a resistor in series with the Vcc to the backlight. Most of the displays you will find have a SMD resistor labelled "R8" of "101" or 100 Ohm (which might possibly be swapped with "R9" of zero ohms) controlling the LED current so an additional resistor is quite unnecessary unless you need to dim the LED.

I recommend you sort out the button wiring (and adjust your code for that), then we can sort out the other details.

Paul__B:
Purportedly, beginners might find this somewhat difficult to conceptualize.

I'd still call myself a beginner so forgive me if I didn't completely understand what you said.

Paul__B:
OK, let's go through a few things here.

In general, you do not connect buttons to the 5 V Vcc.

OK, I know the tutorials here tend to show that, but unfortunately due to the way the website is run, they cannot be replaced with corrected versions.

The proper way to connect the buttons is from a pin to ground. While you can then use pull-up resistors to Vcc, the ATmega chip is especially designed to provide an internal pull-up resistor (of the order of 35k) for you by using the INPUT_PULLUP function in pinMode (effectively setting them as inputs but then writing them HIGH). You may need to provide "stronger" pull-ups of lower resistance in some situations.

So would the buttons be set up somewhat like this?

And would the code be along the lines for this? (this is just a simple serial communication test)

void setup() {

  Serial.begin(9600);

  pinMode(2, INPUT_PULLUP);


}

void loop() {

  int sensorVal = digitalRead(2);

  Serial.println(sensorVal);

}

Paul__B:
Now for some reason you show a resistor in series with the Vcc to the backlight. Most of the displays you will find have a SMD resistor labelled "R8" of "101" or 100 Ohm (which might possibly be swapped with "R9" of zero ohms) controlling the LED current so an additional resistor is quite unnecessary unless you need to dim the LED.

This 16x2 screen came with the Arduino Starter kit and for all of my projects, I've put a resistor there. I don't know if it is necessary or not, but for that one project in the book it was like that, and I assumed it was necessary for all projects with LCD screens.

I really appreciate your help, and I apologize if this concept completely flew over my head.

Yes, that's the sort of tricky problem with these "starter" projects and kits.

Yes, that's how to wire and code the pushbuttons.

Well, perhaps or perhaps not! Note that on the pushbuttons, two pins on each side are connected together, and the button connects one pair to the other when pushed. The problem is that it might be the two pins on each side, or the two top and two bottom pins., depending on how the button is constructed. In order not to worry which is which, it is safest to make your connections to diagonally opposite pins of the button, thus ensuring that you will get it right in either case. :astonished:

That might be the problem in one, otherwise I can look at your code when you have it all sorted - when I get up tomorrow that is - it's bedtime for me now!

Check R8 on your LCD. If it is as I say, "101", then you do not need the extra resistor on pin 15.

Originally, there's actually a potentiometer where the resistor is in the starter kits. However, they don't fit nicely on the breadboard so I experimented with resistors. Without resistors, the backlight is so bright that you cannot see text at all.

With the code and wiring attached, still no luck... :confused:

#include <LiquidCrystal.h>

int buttonPin1= 6;    //sets pins buttons are connected to
int buttonPin2= 7;
int buttonPin3= 8;
int buttonPin4= 9;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //sets pins lcd is connected to, running in 4 bit mode, RW pin tied to gnd

void setup() {
  
  pinMode(buttonPin1, INPUT_PULLUP);  //assigns button pins as inputs
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  
  lcd.begin(16, 2); //screen size
  lcd.setCursor(0, 0);
  lcd.print("Hello."); //introduction
  delay(2000); //delay
  lcd.clear(); //clears screen
  
}


void loop() {

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

 
  
  if(buttonState1 == LOW) {
    lcd.print("1");  //if button 1 is pressed, print 1. 
    delay(250);
    
  }
  
  else if(buttonState2 == LOW) {
    lcd.print("2"); //if button 2 is pressed, print 2. 
    delay(250);

  }

  else if(buttonState3 == LOW) {
    lcd.print("3"); //if button 3 is pressed, print 3. 
    delay(250);
    
  }  
  
  else if(buttonState4 == LOW) {
    lcd.print("4"); //if button 4 is pressed, print 4. 
    delay(350);
   
  }

}

There's no longer any spam of characters, but I'm not getting any response after pressing the buttons.

Your LCD looks upside down to me. The "resistor" looks like red-red-brown i.e. 220R which is very high for a backlight.

Does your LCD say "Hello" ?

As Paul said, your pushbuttons can be rotated 90 degrees. If you have them "shorted", they would read permanent LOW. If they are connected correctly, they would only read LOW when pressed.

Follow Paul's advice and connect to opposite corners. Then they will always work correctly.

With any problem, always:

  1. say what you expected.
  2. say what you actually got.

David,

david_prentice:
Does your LCD say "Hello" ?

Yes.

david_prentice:
As Paul said, your pushbuttons can be rotated 90 degrees. If you have them "shorted", they would read permanent LOW. If they are connected correctly, they would only read LOW when pressed.

I'll try that..

david_prentice:
With any problem, always:

  1. say what you expected.
  2. say what you actually got.

David,

  1. When a button is pressed, the number corresponding to the button will appear on the screen after the hello sequence.

  2. Hello sequence, and unresponsive buttons.

I misread what Paul said, and I'll give it a try.

So like this?

No. Paul meant diagonal pins.

If the switches were correct. You would see 1 when button 1 is pressed.
If the switches were 90 degrees, You would see 1234 at all times.

Always break a problem into small steps. e.g.

  1. check LCD is working.
  2. connect one button. check that works.
  3. add the other buttons.

David.

david_prentice:
No. Paul meant diagonal pins.

If the switches were correct. You would see 1 when button 1 is pressed.
If the switches were 90 degrees, You would see 1234 at all times.

Always break a problem into small steps. e.g.

  1. check LCD is working.
  2. connect one button. check that works.
  3. add the other buttons.

David.

So like this? I'm really sorry if I'm not following.

And I'll check the buttons.

But the numbers are only supposed to show up if the corresponding button is pressed.

chummer1010:

So like this? I'm really sorry if I'm not following.

That's more like it!

The code looks OK, though it will of course, only respond to the lowest numbered button.

david_prentice:
Your LCD looks upside down to me.

That's OK, purely for Fritzing convenience. As long as the connections are correct - but there's a point!

And note that 220R is I believe the default Fritzing resistor. You have to do extra work to illustrate a different value.

david_prentice:
The "resistor" looks like red-red-brown i.e. 220R which is very high for a backlight.

Very high? Given that R8 on the LCD module is 100 Ohms, 220 Ohms will only reduce the LED current to a third of the direct connection, which is only a minor reduction in brightness. 1k would be noticeable.

chummer1010:
Originally, there's actually a potentiometer where the resistor is in the starter kits. However, they don't fit nicely on the breadboard so I experimented with resistors. Without resistors, the backlight is so bright that you cannot see text at all.

I don't think so. A 10k potentiometer will generally be used to set the contrast voltage on pin 3 and if in fact you had difficulty with contrast as you indicate (not brightness as such), you need to experiment with different resistor values up to 1k between pin 3 and ground instead of the direct connection, to get the best contrast.