Button always being read as HIGH

Hello,

I have a button connected to the Arduino MEGA2560. It is very frustrating as even though I am sure I wired it correctly with a resistor between the button and ground, the button is being read as HIGH even when it is not pressed. I've tried changing the wiring to no avail. I would like to know what is wrong with my circuit/code so that the button actually works and "System reset" isn't output on the LCD screen no matter whether I press the button or not.

picture of wiring attached

Edit: the problem has now been solved! I simply needed to change the wiring as suggested later in the thread and give the button longer legs, as well as pushing a few wires further in.

If your button series resistor is 1K or less, you can leave it there. Otherwise, remove it and connect that end of the button to GND. Then use

pinMode(button_pin, INPUT_PULLUP);

... OR you could use the resistor as an external pullup (between 5V and button) and keep your code as is.

dlloyd:
If your button series resistor is 1K or less, you can leave it there. Otherwise, remove it and connect that end of the button to GND. Then use

pinMode(button_pin, INPUT_PULLUP);

... OR you could use the resistor as an external pullup (between 5V and button) and keep your code as is.

Thank you for your reply! I did as you said and it turns out the button isn't responding at all? I'm very confused as I have connected one side to GND and one side to the pin 8 but nothing happens..

Why not use the built in LED to visually check the status of the button?

EDIT: Might need to rotate the button 90 degrees.

You might find this helpful
https://forum.arduino.cc/index.php?topic=719995.0

dlloyd:
EDIT: Might need to rotate the button 90 degrees.

The picture shows the button connected as often recommended here, by diagonally opposite pins and cannot be rotated 90° in any case.

The problem is that the pins are not contacting the breadboard connections. First try is using pliers to straighten the legs. If not successful, solder wires (resistor off-cuts are very handy) to the pins and insert them into the breadboard.

Make sure that your wiring is one of four ways (actually two because of symmetric)

#2 and #3 work no matter how the button gets rotated. #1 and #4 don't work correctly if the button has the wrong rotation.

There are very similar 2 pin buttons that

  1. Don't try to jump out of the breadboard
  2. Cannot be wired incorrectly
    Example: https://www.ebay.com/itm/100pcs-2pins-Tactile-Push-Button-Switch-Tact-Switch-6X6X5mm-Momentary-Pop_UK-dr/274465407735?pageci=501ac1ca-6adf-4771-af7e-3dd572b51661

Cute! Just bought some (albeit from a cheaper dealer, same place :grinning: ).

Bother! Substantially cheaper on Aliexpress as I so often find to be the case!


Aliexpress item

Hi,
Looking at your project picture, you do not appear to have the button wired correctly.


Try this with your original code setup.
Tom.. :slight_smile:

Generally better to wire the button between a pin and ground, and use a pinMode of INPUT_PULLUP.

Thank you for your replies everyone! I have tried all your suggestions and unfortunately it is still not working. I have soldered longer legs to the button so it should definitely be making a connection now. It just prints "system reset" no matter how I wire the button or how long I press it...

Hi,
Do you have a DMM to measure your circuit voltages?

If you connect the input pin8 to gnd and then to 5V you does your display show?
(Disconnect it from the button circuit first.)

Tom... :slight_smile:

Hello,

I don't have a DMM but I have a tabletop oscilloscope. After connecting one probe to the back side and one to the front of the button they both read 0V when the circuit is powered. When I changed the wires as you suggested the display still shows "System reset".

However, after pressing the button, the probe measuring the same side that is connected to +5V jumps to 20mV whilst the probe measuring ground stays at 0V.

Hi,
Try this edited code.

#include<LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int calibrationTime = 10;


//the time when the sensor outputs a low impulse
long unsigned int lowIn;


//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;


boolean lockLow = true;
boolean takeLowTime;


int pirPin = 7;    //the digital pin connected to the PIR sensor's output
int BUZZ_Pin = 10;
int button_pin = 8;

void setup() {
  lcd.begin(16, 2);
  pinMode(pirPin, INPUT);
  pinMode(BUZZ_Pin, OUTPUT);
  pinMode(button_pin, INPUT);

  digitalWrite(pirPin, LOW);
  //digitalWrite(button_pin, LOW);

  lcd.setCursor(0, 0);
  lcd.print("It works!");
  delay(1000);
  lcd.clear();

  lcd.print("Motion detector!");
  delay(1000);
  lcd.clear();
  for (int i = 1; i < calibrationTime; i++)
  {
    lcd.print(i);
    delay(1000);
    lcd.clear();
  }
  delay(500);
}

void loop() {

  if (digitalRead(button_pin) == HIGH)
  {
    //digitalWrite(LED_pin, HIGH);
    lcd.print("System reset");
    //Serial.println(digitalRead(button_pin));
    delay(500);
    lcd.clear();
    //digitalWrite(button_pin, LOW);
  }

  else if (digitalRead(button_pin) == LOW)
  {
    //digitalWrite(LED_pin, LOW);
    if (digitalRead(pirPin) == HIGH)
    {
      lcd.clear();
      //tone(BUZZ_Pin, 500);
      delay(1000);
      noTone(BUZZ_Pin);
      if (lockLow)
      {
        //makes sure we wait for a transition to LOW before any further output is made:
        lockLow = false;
        lcd.print("DO NOT TOUCH");
        lcd.setCursor(0, 1);
        lcd.print("YOUR PHONE");
        delay(500);
      }
      takeLowTime = true;
    }

    if (digitalRead(pirPin) == LOW)
    {
      if (takeLowTime)
      {
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
      }
      //if the sensor is low for more than the given pause,
      //we assume that no more motion is going to happen
      if (!lockLow && millis() - lowIn > pause) {
        //makes sure this block of code is only executed again after
        //a new motion sequence has been detected
        lockLow = true;
        lcd.setCursor(0, 1);
        lcd.print("END ");
        lcd.print((millis() - pause) / 1000);
        lcd.print(" sec");
        delay(500);
      }
    }
  }
}

This line ;

if(digitalRead(button_pin == HIGH))

Should be;

if(digitalRead(button_pin) == HIGH)

And this line;

if(digitalRead(button_pin == LOW))

Should be;

if(digitalRead(button_pin) == LOW)

Tom... :slight_smile:

Thank you for your suggestion, I've changed the code and uploaded it but no luck sadly!

Edit: actually, the LCD screen now prints 'do not touch your phone' instead of "system reset" so this is progress at least! The button doesn't change the message when pressed but it does make the message disappear

Hi,
Connect your scope gnd probe to gnd of your project and leave it there, all your measurements should basically be done with respect to gnd.
Connect the other scope probe to the digital input that the button is connected to.
See what trace you get when the button is pressed and not pressed.

Tom... :slight_smile:

Hello,

I have connected it as you have suggested and after I press the button nothing changes, the trace stays at 0V.

Hi,
Can you post some more pictures of your project from different angles so we can see where all your wires go?

Thanks.. Tom... :slight_smile: