0

I"m kinda new here and new to the arduino framework.

I want to build a "menu" using LCD 20*4, so I want to detect "button clicked" event.

I've connected button to pin 8 and to ground, like this(please ignore the other wiring): enter image description here

int leftButton = 8;   

void setup() {
  pinMode(leftButton, INPUT);   
  digitalWrite(leftButton, HIGH);
  Serial.begin(9600);


}
bool leftButtonClicked(){
  return digitalRead(leftButton);
}
void loop(){
  delay(20);
  Serial.println(digitalRead(leftButton));   
}

I am receiveing on the serial 1 while the button is not clicked, and when its clicked I receive 0.

What is the problem? Thank you guys.

8
  • 2
    That's normal to wire a button so that it connects to ground when pressed. That way you can use INPUT_PULLUP in your pinMode and you don't need any pull-up resistor. So in normal cases your code will read a pressed button as 0 if you wired it the normal way. – Delta_G Apr 9 '20 at 23:19
  • Why do you think that this is a problem? – chrisl Apr 9 '20 at 23:19
  • @Delta_G so according to your saying, 1 mean unclicked, and 0 mean clicked. is this the acceptable way for doing this? there is an preffer method to isolate the clicked event? – itzikb Apr 9 '20 at 23:27
  • According to my saying it depends on how you wire the button, but most people prefer to wire it so that 0 is pressed and 1 is unpressed. You can wire it so that 1 is pressed, but that requires an extra resistor. – Delta_G Apr 9 '20 at 23:34
  • Also you need to change your pinMode to INPUT_PULLUP instead of just INPUT or you will start seeing random phantom button presses as the floating input picks up noise from the environment. – Delta_G Apr 9 '20 at 23:35
2

As you are a beginner, you seem to have some misconceptions:

  • Reading button state with digitalRead(): You thought something is wrong, because you thought that digitalRead() returns, if the button was pressed (thus 1 would mean pressed). But that is not directly the case. digitalRead() returns the electrical state of the corresponding pin (if the pin voltage is at ground level (0) or Vcc (supply voltage) level) (1)). This corresponds with the button depending on your wiring. I guess you copied the wiring somewhere in the internet. It shows the most common way of connecting a button. The button consists only of two contacts, which get pressed together, when you press the button. So the button can connect the pin to either ground or Vcc, but not to both. When the button is not pressed, the pin is connected to nothing, thus it is floating and the value changes erratically. This is solved with a pullup or pulldown resistor (a rather big resistor from the pin to either Vcc or ground), which sets the value of the pin, when the button is not pressed. That means, that you need 1 resistor for each button, that you want to use. The good news is: The Arduino already has internal pullup resistors, that you can activate via pinMode(pin, INPUT_PULLUP). That way you can save 1 extra component. Since it is a pullup resistor, which connects the pin with Vcc, you need to connect the button with ground.

    That also gives you the inverted logic. In the end it is determined by you, what the digitalRead() value means. Think electrically about it.

  • Events: In Arduino programming there are not events. You are programming very much directly the hardware. There is no OS or GUI system, that would handle events for you. The program, that you write, runs command after command with a specific speed (determined by the Arduinos clock frequency; 16MHz for the Uno), pretty much linearly. Though there is one exception for that: interrupts. Microcontrollers have some peripherals build into them (ADC, communication interfaces, Timers, ...) and many of them work parallel to the main program (since their function does not need code, but is implemented in hardware). These peripherals can generate interrupts (for example to service the peripheral), which pauses the normal run of the program, runs an ISR (Interrupt Service Routine) and then returns to the main program. That is somewhat like an event, but very hardware specific and not nearly as generically usable as events on a PC.

  • Reading a button click: In your code you don't read the "button click", but only the state of the button. Thus you get multiple times 0 for one long enough button press. For the real click action you need to look for the transition from 1 to 0, which ideally only happens one time per button press. I write "ideally", because real life buttons bounce. In the moment of contact the value changes rapidly multiple times, until the button contacts have settled. So you need to debounce the button. You have already done basic debouncing by using delay(20) (because the button may need about that time to stabilize). You can see more sophisticated debouncing in the Bounce2 library, which is also easy to use for reading button clicks and presses.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.