LCD 2 pin 16x2 and character entry

by bovine0001 on Tue Jan 01, 2013 10:19 am

So for forthcoming projects demand an LCD and setting a number to be used as a goal for a thermostat. Many steps to go and as I am waiting on the temp probe, I thought I would work on the LCD part.

With the Uno R3 and Adafruit LCD shield with buttons and blue 16x2 LCD, I played with the LCD tutorial and some nice bit of code from unknown source (thought I had saved it, sorry to the person I can't thank more loudly ) and here we are:

Code: Select all | TOGGLE FULL SIZE
/*********************
 *
 * Example code for the Adafruit RGB Character LCD Shield and Library
 *
 * This code displays text on the shield, and also reads the buttons on the keypad.
 * When a button is pressed, the backlight changes color.
 *
 **********************/

// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

const int button1 = 7;
const int button2 = 10;

int pos = 0;
int cpos1 = 0;
int cpos2 = 0;

String output = "----------------xxxxxxxxxxxxxxxxxxxxxxxx----------------";

void setup() {
  // Debugging output
  Serial.begin(9600);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  // Print a message to the LCD. We track how long it takes since
  // this library has been optimized a bit and we're proud of it :)
  int time = millis();
  lcd.print(output);
  lcd.setBacklight(WHITE);
  //Setup some buttons
  pinMode (button1, INPUT);
  pinMode (button2, INPUT);
  //Turn the internal resistors on so the thing does go kaput
  digitalWrite(button1, HIGH);
  digitalWrite(button2, HIGH);
}

uint8_t i=0;
void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);

  uint8_t buttons = lcd.readButtons();

  //Change the position
  if (buttons) {
    lcd.setCursor(0,0);
    if (buttons & BUTTON_RIGHT)

      pos ++;
    cpos1 ++;
    delay (500);
  }   
  if (buttons) {
    lcd.setCursor(0,0);
    if (buttons & BUTTON_LEFT)

      pos --;
    cpos1 --;
    delay (500);
  }   
  if (pos >= 16 && pos <= 39)
  {
    pos = 40;
    cpos1 = 0;
    cpos2 = 1;
  }
  if (pos >= 56)
  {
    pos = 0;
    cpos1 = 0;
    cpos2 = 0;
  }


  // Cycles through the characters on the selected spot
  if (buttons) {

    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP)
    {
      lcd.clear();
      lcd.print(output);
      output [pos] = (output [pos] ++);
      lcd.clear();
      lcd.print(output);
      delay (400);
    }
      if (buttons & BUTTON_DOWN)
    {
      lcd.clear();
      lcd.print(output);
      output [pos] = (output [pos] --);
      lcd.clear();
      lcd.print(output);
      delay (400);
    }
    lcd.setCursor (cpos1, cpos2);
    lcd.blink();
  }
}




It works okay, if not a bit sluggish. The real problem is that I need to find a way to use the entered number as a variable for the thermostat. Since I am very new to C, I don't know how the values I generate on the LCD are stored. Could someone point that out so I can figure out how to make a real number with this?

thanks
bovine0001
 
Posts: 11
Joined: Fri Dec 21, 2012 10:47 am

Re: LCD 2 pin 16x2 and character entry

by adafruit_support_mike on Tue Jan 01, 2013 4:51 pm

A simplified version would be:

Code: Select all | TOGGLE FULL SIZE
#define WHITE 0x7

    lcd.setup( 16, 2 );    //  Tell the library it's a 16x2 LCD
    lcd.setBacklight( WHITE );    //  Turn on the backlight

    int temp = 32;    //  a variable that holds the temperature
    String output = "the temperature is: " + temp;    //  combines the number with text
    lcd.print(output);    //  sends the combined text-and-number to the LCD
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 8715
Joined: Thu Feb 11, 2010 1:51 pm

Re: LCD 2 pin 16x2 and character entry

by bovine0001 on Thu Jan 03, 2013 9:45 am

This example seems to require I set the number through code where as I am trying to set it through a button sequence on the LCD shield. I may have to use this type of solution while working on the final one, but I would hope there would be some way of determining the number displayed on the LCD to use as for math in the code later.
bovine0001
 
Posts: 11
Joined: Fri Dec 21, 2012 10:47 am

Re: LCD 2 pin 16x2 and character entry

by adafruit_support_mike on Thu Jan 03, 2013 4:38 pm

Let me paraphrase what you said to make sure I understand what you want: you want to use buttons and LCD as an input device, and you want to read the number from the LCD into the Arduino so you can use it in other calculations.

If that's what you meant, the LCD shield doesn't work that way.

The LCD itself is what's called a 'dumb' output device. It displays the characters the Arduino tells it to, but doesn't 'know' anything the Arduino hasn't told it.

To control a counter with the buttons on the LCD shield, you'd use the function "lcd.readButtons()" to see if any of the buttons have been pressed, adjust your counter based on which buttons were pressed, then tell the LCD what output to display.

Here's what that would look like:

Code: Select all | TOGGLE FULL SIZE
    uint8_t buttons = lcd.readButtons();
    int counter = 0;
    String output;

    if (buttons & BUTTON_RIGHT) {
        counter++;
        output = "The value is: " + counter;
        lcd.clear();
        lcd.print( output );
    }
    if (buttons & BUTTON_LEFT) {
        counter--;
        output = "The value is: " + counter;
        lcd.clear();
        lcd.print( output );
    }
    delay( 500 );
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 8715
Joined: Thu Feb 11, 2010 1:51 pm

Re: LCD 2 pin 16x2 and character entry

by bovine0001 on Thu Jan 03, 2013 11:56 pm

ooh, that looks cool. Yeah, I figured the device was simply output, but I thought I would ask. There is so much I don't know. The example definitely points me in the way I need to go. I probably should try to find a better source for C language to look up these commands, but that task seems kinda daunting as well.

Thanks so much.
bovine0001
 
Posts: 11
Joined: Fri Dec 21, 2012 10:47 am

Re: LCD 2 pin 16x2 and character entry

by bovine0001 on Fri Jan 04, 2013 11:01 am

So, it didn't quite work:
Code: Select all | TOGGLE FULL SIZE
/*********************

Example code for the Adafruit RGB Character LCD Shield and Library

This code displays text on the shield, and also reads the buttons on the keypad.
When a button is pressed, the backlight changes color.

**********************/

// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

void setup() {
  // Debugging output
  Serial.begin(9600);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

uint8_t i=0;
void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);

  uint8_t buttons = lcd.readButtons();
    int counter = 0;
    String output;

    if (buttons & BUTTON_RIGHT) {
        counter++;
        output = "The value: " + counter;
        lcd.clear();
        lcd.print( output );
    }
    if (buttons & BUTTON_LEFT) {
        counter--;
        output = "The value is: " + counter;
        lcd.clear();
        lcd.print( output );
    }
    delay( 500 );}



Pressing the buttons gives a "he value:". It is cutting the T off the beginning and not displaying the numbers I presume it should be making. I tried playing around with the code to see if a simple version would work better:
Code: Select all | TOGGLE FULL SIZE
SAME AS BEFORE
 uint8_t buttons = lcd.readButtons();
    int counter = 0;
    int output;

    if (buttons & BUTTON_RIGHT) {
        counter ++;
        output = counter;
        lcd.clear();
        lcd.print("Temp: ");
        lcd.println( output );
    }
 //   if (buttons & BUTTON_LEFT) {
   //     counter--;
     //   output = "Value: " + counter;
       // lcd.clear();
      //  lcd.print( output );
    }
  //  delay( 500 );}


This only gives me a "Temp: 1(gibberish)". I think I don't understand the incremental function of ++ and -- and perhaps how to produce a String. Any thoughts?
bovine0001
 
Posts: 11
Joined: Fri Dec 21, 2012 10:47 am

Re: LCD 2 pin 16x2 and character entry

by bovine0001 on Fri Jan 04, 2013 7:55 pm

after some mild torment I got this to work:
Code: Select all | TOGGLE FULL SIZE
/*********************
 *
 * Example code for the Adafruit RGB Character LCD Shield and Library
 *
 * This code displays text on the shield, and also reads the buttons on the keypad.
 * When a button is pressed, the backlight changes color.
 *
 **********************/

// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color
//#define RED 0x1
//#define YELLOW 0x3
//#define GREEN 0x2
//#define TEAL 0x6
#define BLUE 0x4
//#define VIOLET 0x5
#define WHITE 0x7
byte counter=0;
void setup() {
  // Debugging output
  Serial.begin(9600);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
}

uint8_t i=0;
void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  lcd.print ("Goal Temp: ");
  uint8_t buttons = lcd.readButtons();
  //int counter = 0;
  //  String output;
  int dtemp;
  //int dtemp=(155+counter);
  if (buttons & BUTTON_UP) {
    counter++;
    //    lcd.print ("Temp: ");
    (dtemp=155+counter);
    //  output = " Temp: " + counter;
    //  lcd.clear();
    lcd.println( dtemp );
  }
  delay (100);
  if (buttons & BUTTON_DOWN) {
    counter--;
    (dtemp=155+counter);
    //    output = " fsd" + counter;
    //    lcd.clear();
    lcd.println( dtemp );
    //  }
    delay( 100 );
  }
}




I need to take out the extra stuff, but it works for now.
bovine0001
 
Posts: 11
Joined: Fri Dec 21, 2012 10:47 am

Re: LCD 2 pin 16x2 and character entry

by adafruit_support_mike on Sat Jan 05, 2013 5:53 pm

bovine0001 wrote:This only gives me a "Temp: 1(gibberish)". I think I don't understand the incremental function of ++ and -- and perhaps how to produce a String. Any thoughts?

The '++' and '--' operators are what's called 'syntactic sugar'.. convenient ways of saying something you could do equally well another way. Here's what they actually do:

Code: Select all | TOGGLE FULL SIZE
    int c;
   
//  This sequence of operations:
    c = 0;
    doSomethingWith( c++ );

// says exactly the same thing as this sequence:
    c = 0;
    doSomethingWith( c );
    c = c + 1;

//  and this sequence:
    c = 10;
    doSomethingWith( c-- );

//  says exactly the same thing as this sequence:
    c = 10;
    doSomethingWith( c );
    c = c - 1;

The operations are called 'postincrement' and 'postdecrement' because you do something with the original value before adding or subtracting 1. There are also 'preincrement' and 'predecrement' operators:

Code: Select all | TOGGLE FULL SIZE
    int c;
   
//  This sequence of operations:
    c = 0;
    doSomethingWith( ++c );

// says exactly the same thing as this sequence:
    c = 0;
    c = c + 1;
    doSomethingWith( c );

//  and this sequence:
    c = 10;
    doSomethingWith( --c );

//  says exactly the same thing as this sequence:
    c = 10;
    c = c - 1;
    doSomethingWith( c );

which add or subtract 1 before using the value.

Both forms are useful in loops. The standard way of copying strings in C looks like this:

Code: Select all | TOGGLE FULL SIZE
    char[15] src = "hello, world.\n";
    char[15] dst;
    int i = 0;

    while (dst[ i++ ] = src[ i++ ]) {
    }
    dst[ i ] = 0;

//  longer way of saying the same thing:
    i = 0;

    while ( src[ i ] != 0 ) {
        dst[ i ] = src[ i ];
        i = i + 1;
    }
    dst[ i ] = 0;

They make it easier to write compact code, and once you get used to them you can glance at a block of code and say, "okay, something simple is happening here." They can make code 'subtle' though (aka: 'WTF?') so it's good manners to arrange things so the 'okay, we need to add/subtract 1' meaning is easy to understand.

As far as a reference for C goes, the classic is "The C Programming Language," written by the two guys who created the language: Brian Kernighan and Dennis Ritchie. It's a step-by-step introduction to the language and its ideas, with each step following the pattern, "here's the idea, here's some code that does what we just said, and now let's talk about the details."

Here's an online version: http://net.pku.edu.cn/~course/cs101/200 ... nguage.pdf

The 'String' data structure isn't actually part of C itself. It's something that was built into the Arduino programming environment. The official documentation for that is here: http://arduino.cc/en/Reference/StringObject
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 8715
Joined: Thu Feb 11, 2010 1:51 pm