Help using Adafruit I2C Controlled + Keypad Shield Kit for 16x2 LCD

Hey everyone,

Sorry in advance for what may be a silly question - I'm relatively new to all this (although I have looked around for a while and decided to make an account in order to ask because I couldn't find an answer).

I recently replaced an older LCD with a 16x2 LCD using the Adafruit I2C Controlled + Keypad Shield Kit for 16x2 LCD on an Arduino Uno project. The code I want to run with the new LCD has many embedded while loops, which are causing problems when trying to use the buttons on the LCD shield. I have narrowed the problem down to the while loop, so instead of reproducing my (somewhat long) code, I've created an example that illustrates the problem.

I've installed the necessary library, as exhibited by correct function when I execute the following code:

#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.setBacklight(0x7);
  lcd.setCursor(0,0);
}

void loop() {
  uint8_t buttons = lcd.readButtons();
  lcd.setCursor(0,0);
  if (buttons & BUTTON_UP) {
    lcd.print("IT WORKS!");
  }
  else {
    lcd.clear();
  }
}

However, when I try to add a while loop as seen below, the buttons stop responding. Again, please ignore the redundancy of this specific while loop; it only serves to represent a problem I'm having in a much longer code. I imagine the issue may have something to do with the bitwise operators (as opposed to boolean). However, I'm just speculating because I don't really understand bitwise operators; they're only in there because I took the setup from the "Hello World" example from the LCD shield's library.

#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.setBacklight(0x7);
  lcd.setCursor(0,0);
}

void loop() {
  uint8_t buttons = lcd.readButtons();
  while(1) {
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) {
      lcd.print("IT WORKS!");
    }
    else {
      lcd.clear();
    }
  }
}

When I say "the button stops responding," I mean that, in addition to the screen no longer displaying "IT WORKS!," I've added a "Serial.println(test)" in the first if-statement and nothing comes up no the serial monitor when the button is pressed either. Something about the while loop is stopping the program from recognizing the button press.

Any help on this matter is greatly appreciated.

Thanks!

You never read the buttons in your endless while loop.

groundfungus:
You never read the buttons in your endless while loop.

I don't really understand what you mean. Isn't the if-statement "if(buttons & BUTTON_UP) {...}" going to read whether or not the button is being pressed? I don't get why that doesn't occur in the while loop.

Would you mind possibly providing some input on how to fix this that would help me understand the issue better?

void loop() 
{
  uint8_t buttons = lcd.readButtons();  // this line seems to be where the value of buttons is assigned
  while(1) 
{
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) 
    {           
      lcd.print("IT WORKS!");
    }
    else {
      lcd.clear();
    }
  }
}

Where in the while loop is buttons read again?

if (buttons & BUTTON_UP) {

could be

if(lcd.readButtons() > 0 && BUTTON_UP > 0)  // i know the >0 is superfluous but is more clear.

That way the buttons are read every time through the while(1) loop. If a function returns a value the function takes on that value. Note the double && logical and in a comparison instead of bitwise and &.

 if (buttons) {
    lcd.clear();
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) {
      //your code here
    }

    else { // your code here}

   }

Not sure why but it seems like you were onto something with getting rid of defining buttons as lcd.readButtons() and using the library function in the if-statement. My code as follows functions as I would like:

#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {
   Serial.begin(9600);
   lcd.begin(16,2);
   lcd.setBacklight(0x7);
}

void loop()
{
  while(1) {
    lcd.setCursor(0,0);
    if(lcd.readButtons() & BUTTON_UP) {
      lcd.print("IT WORKS!");
    }
    else {
      lcd.clear();
  }
}

Thanks for all the feedback.