LCD4884 Shield For Arduino (SKU:DFR0092)

From Robot Wiki
DFR0092.jpg

Discontinued Product


Introduction

This LCD4884 Shield provides a 84x48 display. If your project needs more display capability, this LCD shield can help meet your needs. It is able to display in English, Chinese and even images. It also integrates a 5 DOF joystick. The shield has 6 Digital IO and 5 Analog IO on its face for easy prototyping.


Warning yellow.png

The LCD4884 is NOT compatible with Arudino IDE 1.6 since deprecated conversion, compatible with 1.0, 1.5.


Shield diagram

Specification

  • Power Supply: 5V
  • SPI Interface (using Arduino Digital Pin 2,3,4,5,6)
  • One Reset button
  • One 5 degree joystick (using Arduino Analog Pin 0)
  • Backlit control (Arduino DIO Pin 7)

PinOut

LCD4884 Pinout

Sample Code

Library for this code library

/*
Modified by Amy
version 0.4

Description:
  Update the library and sketch to compatible with IDE V1.0 and earlier
  Improve the key detection function to be compatible with the Arduino Leonardo
  Improve the waitOK function
  Move the bit map array to the main code

Any suggestions are welcome.
E-mail: Lauran.pan@gmail.com

Editor     : Amy from DFRobot
Date       : 20.12.2012


*/

#include "LCD4884.h"

/*------------------------------------------------------------------------------
; DFrobot bitmap - size 48x24 pixels, black/white image
------------------------------------------------------------------------------*/
unsigned char DFrobot_bmp[]=

{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x01,0x39,0x39,0x39,0x39,0x39,0x39,
0x01,0x01,0xFF,0xFF,0x01,0x01,0xC9,0xC9,0xC9,0xC9,0xC9,0xC9,0xFF,0xFF,0xFF,0xFF,
0xFF,0x19,0x19,0x19,0x19,0xFF,0xE6,0x00,0x7C,0xFE,0xFF,0xFF,0x83,0x01,0x01,0x01,
0x83,0xC6,0x7C,0x00,0x00,0xFF,0xFF,0xFF,0x19,0x19,0x19,0x99,0xFF,0xFE,0x00,0x38,
0xFE,0xFF,0xFF,0xC3,0x81,0x01,0x01,0x83,0x87,0xFE,0x3C,0x00,0x01,0x01,0xFF,0xFF,
0xFF,0xFF,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x02,0x02,
0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,
0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00
};
/******************************************************************************/


/*------------------------------------------------------------------------------
; DFrobot chinese - size 12x12  
------------------------------------------------------------------------------*/ 
unsigned char DFrobot_chinese[]=
{
  0x84,0x64,0xFF,0x24,0x44,0xFE,0x02,0x02,0xFF,0x02,0x00,0x00,0x01,0x00,0x07,0x04,
  0x02,0x01,0x00,0x00,0x07,0x04,0x07,0x00,
  
  0xA0,0xAF,0xA9,0xE9,0xAF,0x30,0xAF,0xA9,0xF9,0xAF,0xA0,0x00,0x00,0x07,0x04,0x04,
  0x07,0x00,0x07,0x04,0x04,0x07,0x00,0x00,
  
  0x00,0x00,0x00,0x80,0x60,0x1F,0x60,0x80,0x00,0x00,0x00,0x00,0x04,0x04,0x02,0x01,
  0x00,0x00,0x00,0x01,0x02,0x04,0x04,0x00,
  
  0x22,0x12,0x0A,0xBF,0x6A,0x52,0x4A,0x7F,0xCA,0x12,0x22,0x00,0x04,0x05,0x05,0x04,
  0x05,0x02,0x02,0x01,0x00,0x00,0x00,0x00,
  
  0x00,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x03,0x02,0x00,0x00,0x04,0x04,0x04,0x04,
  0x04,0x07,0x04,0x04,0x04,0x04,0x04,0x00,
  
  0x00,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x06,0x01,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
/******************************************************************************/

//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON  10
#define DEBOUNCE_OFF 3 

#define NUM_KEYS 5

#define NUM_MENU_ITEM	4

// joystick number
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 3
#define UP_KEY 4

// menu starting points

#define MENU_X	10		// 0-83
#define MENU_Y	1		// 0-5


int  adc_key_val[5] ={
  50, 200, 400, 600, 800 };

// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program 
byte button_flag[NUM_KEYS];

// menu definition
char menu_items[NUM_MENU_ITEM][12]={
  "TEMPERATURE",
  "CHAR MAP",
  "BITMAP",
  "ABOUT"	
};

void (*menu_funcs[NUM_MENU_ITEM])(void) = {
  temperature,
  charmap,
  bitmap,
  about
};

char current_menu_item;

void setup()
{

  // reset button arrays
  for(byte i=0; i<NUM_KEYS; i++){
    button_count[i]=0;
    button_status[i]=0;
    button_flag[i]=0;
  }

  lcd.LCD_init();
  lcd.LCD_clear();

  //menu initialization
  init_MENU();
  current_menu_item = 0;	

  lcd.backlight(ON);//Turn on the backlight
  //lcd.backlight(OFF); // Turn off the backlight  
}

unsigned long buttonFlasher = 0;

/* loop */

void loop()
{
  byte i;
  for(i=0; i<NUM_KEYS; i++){
    if(button_flag[i] !=0){

      button_flag[i]=0;  // reset button flag
      switch(i){

      case UP_KEY:
        // current item to normal display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
        current_menu_item -=1;
        if(current_menu_item <0)  current_menu_item = NUM_MENU_ITEM -1;
        // next item to highlight display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
        break;
      case DOWN_KEY:
        // current item to normal display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
        current_menu_item +=1;
        if(current_menu_item >(NUM_MENU_ITEM-1))  current_menu_item = 0;
        // next item to highlight display
        lcd.LCD_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
        break;
      case LEFT_KEY:
        init_MENU();
        current_menu_item = 0;
        break;   
      case CENTER_KEY:
        lcd.LCD_clear();
        (*menu_funcs[current_menu_item])();
        //(*menu_funcs[0])();        
        Serial.println("hello");
        lcd.LCD_clear();
        init_MENU();
        current_menu_item = 0;         
        break;	
      }

    }
  }
  if(millis() - buttonFlasher > 5){
    update_adc_key();
    buttonFlasher = millis();
   }    
}

/* menu functions */

void init_MENU(void){

  byte i;

  lcd.LCD_clear();

  lcd.LCD_write_string(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );

  for (i=1; i<NUM_MENU_ITEM; i++){
    lcd.LCD_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL);
  }


}

// waiting for center key press
void waitfor_OKkey(){
  byte i;
  byte key = 0xFE;
  for(byte i=0; i<NUM_KEYS; i++){
    button_count[i]=0;
    button_status[i]=0;
    button_flag[i]=0;
  }
  update_adc_key();
  while (key!= CENTER_KEY){
    for(i=0; i<NUM_KEYS; i++){
      if(button_flag[i] !=0){
        button_flag[i]=0;  // reset button flag
        if(i== CENTER_KEY) 
        {
          key=CENTER_KEY; 
        }
      }
      update_adc_key();
    }
  }
}

void temperature()
{
  lcd.LCD_write_string_big(10, 1, "+12.30", MENU_NORMAL);
  lcd.LCD_write_string(78, 2, "C", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();
}

void charmap(){
  char i,j;
  for(i=0; i<5; i++){
    for(j=0; j<14; j++){
      lcd.LCD_set_XY(j*6,i);
      lcd.LCD_write_char(i*14+j+32, MENU_NORMAL);
    }
  }


  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();   
}

void bitmap(){
  lcd.LCD_draw_bmp_pixel(0,0, DFrobot_bmp, 84,24);
  lcd.LCD_write_chinese(6,3, DFrobot_chinese,12,6,0,0);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();
}


void about(){

  lcd.LCD_write_string( 0, 1, "LCD4884 Shield", MENU_NORMAL);
  lcd.LCD_write_string( 0, 3, "www.DFrobot.cn", MENU_NORMAL);
  lcd.LCD_write_string(38, 5, "OK", MENU_HIGHLIGHT );
  waitfor_OKkey();


}

// which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection
// Convert ADC value to key number

char get_key(unsigned int input)
{
  char k;

  for (k = 0; k < NUM_KEYS; k++)
  {
    if (input < adc_key_val[k])
    {

      return k;
    }
  }

  if (k >= NUM_KEYS)
    k = -1;     // No valid key pressed

  return k;
}

void update_adc_key(){
  int adc_key_in;
  char key_in;
  byte i;

  adc_key_in = analogRead(0);
  key_in = get_key(adc_key_in);
  for(i=0; i<NUM_KEYS; i++)
  {
    if(key_in==i)  //one key is pressed 
    { 
      if(button_count[i]<DEBOUNCE_MAX)
      {
        button_count[i]++;
        if(button_count[i]>DEBOUNCE_ON)
        {
          if(button_status[i] == 0)
          {
            button_flag[i] = 1;
            button_status[i] = 1; //button debounced to 'pressed' status
          }

        }
      }

    }
    else // no button pressed
    {
      if (button_count[i] >0)
      {  
        button_flag[i] = 0;	
        button_count[i]--;
        if(button_count[i]<DEBOUNCE_OFF){
          button_status[i]=0;   //button debounced to 'released' status
        }
      }
    }
  }
}

The sketch for displaying a variable value on the screen

/*
 Modified by Lauren
 version 0.1
 
 Any suggestions are welcome.
 E-mail: Lauran.pan@gmail.com
 
 Editor     : Lauren from DFRobot
 Date       : 26.03.2012
 
 * This is a sample sketch for displaying a variable value on the LCD4884
 * This library and sample is compatible with the IDE V1.0 and earlier
 
 Connection:
 
 Directly stack the LCD4884 shield on your Arduino board
 
*/

#include "LCD4884.h"

#define MENU_X	10		// 0-83
#define MENU_Y	1		// 0-5

int counter = 0;
char string[10];

void setup()
{

  lcd.LCD_init();
  lcd.LCD_clear();

  //menu initialization
  init_MENU();
}

void init_MENU(void){

  byte i;
  lcd.LCD_clear();
  lcd.LCD_write_string(MENU_X, MENU_Y, "test screen", MENU_HIGHLIGHT );

}

void loop(){

  if(++counter < 1000){
    itoa(counter,string,10);
    lcd.LCD_write_string(MENU_X, MENU_Y + 1, string, MENU_NORMAL);
  }
  else  counter = 0,init_MENU();
  delay(10);

}

Multi DS18B20 sensors display example

/*
Description: multiple DS18B20 sensors reading display sample
Author: Amy
Thanks for your sharing your LCD4884 application
*/

#include <OneWire.h>                 //one wire sensor protocol library (V2.0) from http://www.pjrc.com/teensy/td_libs_OneWire.html 
#include <DallasTemperature.h>       //dallas one wire temperature library (V3.6.0) from http://milesburton.com/index.php/Dallas_Temperature_Control_Library 
#include <LCD4884.h>
//-----menu starting points--------------------------------------------------------------
#define MENU_X 10  // Horizontal position range available is 0-83 in pixels
#define MENU_Y 1  // Vertical Lines - range available is 0-5 in lines of text
//-----Menu Variables--------------------------------------------------------------
int analogstatus;  //Normal/center-1000-1200, Up->700-800, Down-300-400, Left-<100, Right-500-600
int page;  // value that determines what is displayed
int maxpage;
char buttonreadstring[10];
char pagestring[10];
//-----Temperature Variables--------------------------------------------------------------
int temperature_sensor_bus=9;                 //hardwired DS18B20 bus 
OneWire oneWire(temperature_sensor_bus);      //setup one wire and Dallas temperature sensor library 
DallasTemperature sensors(&oneWire);
float temp0;                                   //add more for additional sensors
float temp1;
char tempstring0[10];
char tempstring1[10];
int TEMPERATURE_PRECISION=9;                  //9 bit percision
int numberOfDevices;                          // Number of temperature devices found
DeviceAddress tempDeviceAddress;              // Temporarily store discovered device addresses
//Setup********************************************************************************************************************************************** 
void setup(){
  Serial.begin(9600);
  //--------------------Setup one-wire sensors ----------------------------------------
  sensors.begin(); // Start up the OneWire library
  delay(100);
  numberOfDevices = sensors.getDeviceCount();  // Get a count of sensors on the bus
  for(int xyz=0;xyz<numberOfDevices; xyz++)  // Loop through each device, print out address
  {
    if(sensors.getAddress(tempDeviceAddress, xyz))    // Search the wire for address
    {
      Serial.print("Found Sensor ");
      Serial.print(xyz, DEC);
      Serial.print(" with address: ");
      printAddress(tempDeviceAddress);
      Serial.println();
      Serial.print("Setting resolution to ");
      Serial.println(TEMPERATURE_PRECISION,DEC);
      delay(100);
      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);  // set the sensor resolution
    }
  }
  sensors.requestTemperatures();            //issue global request for each temp sensor on network to return a temp
  if(sensors.getAddress(tempDeviceAddress, 0))temp0=(sensors.getTempC(tempDeviceAddress));
  if(sensors.getAddress(tempDeviceAddress, 1))temp1=(sensors.getTempC(tempDeviceAddress));
  //----Initialize, clear and backlight LCD SCREEN---------------------------------  
  lcd.LCD_init();
  lcd.LCD_clear();
  lcd.backlight(ON);//Turn on the backlight
  maxpage = 5;  //  Maximum number of pages to scroll through
} //Setup End**********************************************************************************************************************************************
void loop(){   //****Begin Loop*************************************************************************************************************************
  //-----Button Loop---------------------------------------------------------------- 
  analogstatus = analogRead(0);  //Read Analog Pin 0
  //int analogstatus;  //Normal-1000-1200, Up->700-800, Down-300-400, Left-0, Right-500-600, Center-100-200
  // if (analogstatus > 1000 && analogstatus < 1200){Page = 0;}  //Use if when buttons are left alone, it should return to page 0
  while (analogstatus > 500 && analogstatus < 600){
    if (page == maxpage - 1){
      page = 0; 
      break;
    }
    else {
      page = page++; 
      break;
    }
  }
  while (analogstatus < 100){
    if (page == 0){
      page = maxpage-1; 
      break;
    }
    else {
      page = page--; 
      break;
    }
  }  
  itoa(page,pagestring,10);
  itoa(analogstatus,buttonreadstring,10);
  //-----Button Loop END----------------------------------------------------------------   
  //WIP***************************************************************    
  //WIP***************************************************************  
  //WIP***************************************************************  
  //WIP***************************************************************    
  //WIP***************************************************************  
  //WIP*************************************************************** 
  //--------------Read temperatuere sensors---------------------------------------------- 
  sensors.requestTemperatures();            //issue global request for each temp sensor on network to return a temp
  if(sensors.getAddress(tempDeviceAddress, 0))temp0=(sensors.getTempF(tempDeviceAddress));
  if(sensors.getAddress(tempDeviceAddress, 1))temp1=(sensors.getTempF(tempDeviceAddress));
  //--------------Page Definitions---------------------------------------------- 
  itoa(temp0,tempstring0,10);
  itoa(temp1,tempstring1,10);
  if (page ==0){ 
    lcd.LCD_clear();
    lcd.LCD_write_string(5, 0, "Page 1" , MENU_HIGHLIGHT); 
    lcd.LCD_write_string(5, 1, "Temp 1: " , MENU_NORMAL);
    lcd.LCD_write_string(50, 1, tempstring0, MENU_NORMAL);
    lcd.LCD_write_string(70, 1, "F" , MENU_NORMAL); 
    lcd.LCD_write_string(5, 2, "Temp 2: " , MENU_NORMAL);
    lcd.LCD_write_string(50, 2, tempstring1, MENU_NORMAL);
    lcd.LCD_write_string(70, 2, "F" , MENU_NORMAL);  
  }
  if (page ==1){
    lcd.LCD_clear();
    lcd.LCD_write_string(5, 0, "Page 2" , MENU_HIGHLIGHT); 
    lcd.LCD_write_string(5, 1, "Temp 1: " , MENU_NORMAL);
    lcd.LCD_write_string(50, 1, tempstring0, MENU_NORMAL);
    lcd.LCD_write_string(70, 1, "F" , MENU_NORMAL); 
  }
  if (page ==2){
    lcd.LCD_clear();
    lcd.LCD_write_string(5, 0, "Page 3" , MENU_HIGHLIGHT); 
    lcd.LCD_write_string(5, 1, "Temp 2: " , MENU_NORMAL);
    lcd.LCD_write_string(50, 1, tempstring1, MENU_NORMAL);
    lcd.LCD_write_string(70, 1, "F" , MENU_NORMAL); 
  }
  if (page ==3){
    lcd.LCD_clear();
    lcd.LCD_write_string(5, 0, "Page 4" , MENU_HIGHLIGHT); 
  }
  if (page ==4){
    lcd.LCD_clear();
    lcd.LCD_write_string(5, 0, "Page 5" , MENU_HIGHLIGHT); 
  }
  //-----------Displayed on every page---------------------------------
  lcd.LCD_write_string(0, 4, buttonreadstring, MENU_NORMAL);
  lcd.LCD_write_string(0, 5, pagestring , MENU_NORMAL);
  //WIP***************************************************************    
  //WIP***************************************************************  
  //WIP***************************************************************  
  //WIP***************************************************************    
  //WIP***************************************************************  
  //WIP***************************************************************  
}//Loop End********************************************************************************************************************************************************  
// FUNCTIONS********************************************************************************************************************************************************   
// function to print a devices address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t xyz = 0; xyz < 8; xyz++)
  {
    if (deviceAddress[xyz] < 16) Serial.print("0");
    Serial.print(deviceAddress[xyz], HEX);
  }
}

Related project