Monday, June 25, 2012

LCD / Keypad Shield

We are building a thermostat to control our furnace and A/C. We are using a DFRobot LCD / Keypad shield we received from Hacktronics.com to display the temperature, and to set the temperature ranges for both the heating and cooling modes. The following is a sketch that shows how the lcd and the buttons are utilized. Only one analog input is needed for the 6 buttons, as they are connected to resistors, and the resistance is measured to determine which button is being pushed. We will be customizing this with a Dallas DS18B20 temperature sensor, and MOSFET / SSR control over the Furnace and A/C. A video of how this works has been uploaded to YouTube.

//Sample using LiquidCrystal library
#include "LiquidCrystal.h"
/*******************************************************
This program will test the LCD panel and the buttons
Mark Bramwell, July 2010
********************************************************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 195)  return btnUP;
 if (adc_key_in < 380)  return btnDOWN;
 if (adc_key_in < 555)  return btnLEFT;
 if (adc_key_in < 790)  return btnSELECT;  
 return btnNONE;  // when all others fail, return this...
}
void setup()
{
 analogWrite(10, 50); // set brightness on pin 10 to 0-255
 lcd.begin(16, 2);              // start the library
 lcd.setCursor(0,0);
 lcd.print("Push the buttons"); // print a simple message
}
  
void loop()
{
 lcd.setCursor(9,1);            // move cursor to second line "1" and 9 spaces over
 lcd.print(millis()/1000);      // display seconds elapsed since power-up
 lcd.setCursor(0,1);            // move to the begining of the second line
 lcd_key = read_LCD_buttons();  // read the buttons
 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     lcd.print("RIGHT ");
     break;
     }
   case btnLEFT:
     {
     lcd.print("LEFT   ");
     break;
     }
   case btnUP:
     {
     lcd.print("UP    ");
     break;
     }
   case btnDOWN:
     {
     lcd.print("DOWN  ");
     break;
     }
   case btnSELECT:
     {
     lcd.print("SELECT");
     break;
     }
     case btnNONE:
     {
     lcd.print("NONE  ");
     break;
     }
 }
}

4 comments:

  1. I want to build one of these to run a small air conditioner. Could it be modified to read 2 or 3 temperature sensors and display the readings in f.
    Turn on the device when sensor 1 (room temperature) is above the set point and turn off the device when sensor 2 (the coils on the AC) drop below a certain point.
    Sensor 3 would just be informational, like outside temp.

    ReplyDelete
  2. That would be easy to do. Look at our DS18B20 projects we have posted here in the past. One had two sensors, 3 is just as easy.

    ReplyDelete
  3. Thanks for the reply. I found the other post "after" I submitted my question. Nice that the temp sensors are addressable. Ordered everything "I think I need" last night. Ordered a 4 line LCD so I can list set point, TS1, TS2 & TS3 all at the same time. Please don't tell me that can all be done with the 2 line LCD you used above as the LDC Shield would be easier to use and already has buttons.

    ReplyDelete
  4. I prefer 4 line lcd's, but even with a two line, you can have multiple "pages" for different functions.

    ReplyDelete