Go Down

Topic: Using analogRead for buttons (Read 209 times) previous topic - next topic

larmagost

I'm working on a project where I need to use multiple buttons to navigate through menus on an LCD screen.

I've used an LCD Shield to do something similar before. However, this time I can't have the buttons on the LCD itself, so I bought an I2C LCD and regular buttons. 

I tried using the digital inputs (attaching one end of the button to 5v and the other end on a digital pin), but the digitalRead wasn't working well. I read I needed to ground the button with a resistor to fix this, but I don't have the correct resistors at the moment.

As a result, I'm trying to approach this the same way I did the LCD Shield buttons, using analog pins.

This is what I used with the LCD Shield:
Code: [Select]

int lcd_key     =0;
int adc_key_in  =0;

#define btnRIGHT  0                                       //defining buttons
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

int read_LCD_buttons(){                                   // read the buttons
    adc_key_in = analogRead(0);                           // read the value from the sensor

    if (adc_key_in > 1000) return btnNONE;                //distinguishing buttons from analog read
    if (adc_key_in < 50)    return btnRIGHT; 
    if (adc_key_in < 150)  return btnUP;
    if (adc_key_in < 300)  return btnDOWN;
    if (adc_key_in < 450)  return btnLEFT;
    if (adc_key_in < 680)  return btnSELECT; 

    return btnNONE;
}



I would use read_LCD_buttons() and if statements to execute commands when certain buttons were pressed. This worked perfectly.

I'm trying to do something similar with the regular buttons now. The only difference is each button has its own analog pin. Both buttons are attached to the 5v pin and the other ends of the buttons are attached to A0 and A1 respectively.

The issue I'm having is that for some reason when I press button 2 (A1), it affects the reading of button 1 (A0). So I'll press the second button, and the reading for the first button will jump above 1000, making it seem like the first button is pressed.

I've tested both buttons with a multimeter and they work fine.

This is the code I'm using for the regular buttons (I've also attached the file):

Code: [Select]
//debounce

int buttonStates;
int lastButtonState = 0;

unsigned long lastDebounce = 0;
unsigned long debounceDelay = 60;

//buttons

int buttons(){
  if (analogRead(0) > 1000){
    return 1;
  }
  if (analogRead(1) > 1000){
    return 2;
  }
  else {
    return 0;
  }
}

void setup() {
  Serial.begin(9600);

}

void loop() {
  int reading = buttons();

  Serial.println(analogRead(0));
  //Serial.println(reading);

  if (reading != lastButtonState) {
    lastDebounce = millis();                                //Starting lastDebounce timing
  }

  if ((millis() - lastDebounce) > debounceDelay) {        //Check if delay has passed
    if (reading != buttonStates) {
      buttonStates = reading;                             //Set button state
        if (buttonStates == 1){
          Serial.println("Button 1");
        }
        if (buttonStates == 2){
          Serial.println("Button 2");
        }
    }
  }

  lastButtonState = reading;

}


Is there something I need to change in my code or is there an entirely different way I can approach this?

Thank you in advance, and I apologize if I haven't given enough information. I can provide more if necessary.

larmagost

I set the analog pins as outputs and for some reason that worked. I'm still curious as to what was happening before, though, and why this worked.

pert

I read I needed to ground the button with a resistor to fix this, but I don't have the correct resistors at the moment.
The microcontroller on your Arduino board has built-in internal resistors for this purpose. You don't need to add external resistors, you just need to enable the internal pull-up resistors in your code. See this tutorial to learn how:
https://www.arduino.cc/en/Tutorial/InputPullupSerial

BabyGeezer

you can actually use just *ONE* analog pin for all your buttons.

look for "resistor ladder" - i think the Arduino Playground also has a tutorial for this.
Attach your images to be viewed directly - THIS WAY;
https://forum.arduino.cc/index.php?topic=519037.0

septillion

#4
May 20, 2019, 10:04 am Last Edit: May 20, 2019, 10:05 am by septillion
To clear some stuff up:

- analog pins have analog as extra function, but like the rest they can be used as digital pin as well.
- You need a pull resistor indeed, mot common way is to connect the button between GND and a pin and use a pull up resistor.
- The Arduino has build in pull up resistors so you don't need external resistors. Can be enabled via pinMode(INPUT_PULLUP)
- Because of legacy, you can also enable them by calling digitalWrite(HIGH) on a pin set as input. This probably is what "fixed" it for you.

And yes, you can use a resistor ladder to read multiple buttons via a single analog pin. Downsides:
- need multiple resistors
- unable (/ hard) to detect multiple button presses at the same time
- slower
- harder to code (although a library can probably fix that)

So if you don't need to aka have pins to spare, I would just go for digitalRead() with internal pull up.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Go Up