![]() | LCD Library 1.2.1 LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library. |
00001 // ---------------------------------------------------------------------------00002 // Created by Francisco Malpartida on 20/08/11.00003 // Copyright 2011 - Under creative commons license 3.0:00004 // Attribution-ShareAlike CC BY-SA00005 //00006 // This software is furnished "as is", without technical support, and with no 00007 // warranty, express or implied, as to its usefulness for any purpose.00008 //00009 // Thread Safe: No00010 // Extendable: Yes00011 //00012 // @file LCD.cpp00013 // This file implements a basic liquid crystal library that comes as standard00014 // in the Arduino SDK.00015 // 00016 // @brief 00017 // This is a basic implementation of the HD44780 library of the00018 // Arduino SDK. This library is a refactored version of the one supplied00019 // in the Arduino SDK in such a way that it simplifies its extension00020 // to support other mechanism to communicate to LCDs such as I2C, Serial, SR, ...00021 // The original library has been reworked in such a way that this will be00022 // the base class implementing all generic methods to command an LCD based00023 // on the Hitachi HD44780 and compatible chipsets.00024 //00025 // This base class is a pure abstract class and needs to be extended. As reference,00026 // it has been extended to drive 4 and 8 bit mode control, LCDs and I2C extension00027 // backpacks such as the I2CLCDextraIO using the PCF8574* I2C IO Expander ASIC.00028 //00029 //00030 // @version API 1.1.000031 //00032 // 2012.03.29 bperrybap - changed comparision to use LCD_5x8DOTS rather than 000033 // @author F. Malpartida - fmalpartida@gmail.com00034 // ---------------------------------------------------------------------------00035 #include <stdio.h>00036 #include <string.h>00037 #include <inttypes.h>00038 00039 #if (ARDUINO < 100)00040 #include <WProgram.h>00041 #else00042 #include <Arduino.h>00043 #endif00044 #include "LCD.h"00045 00046 // CLASS CONSTRUCTORS00047 // ---------------------------------------------------------------------------00048 // Constructor00049LCD::LCD () 00050 { 00051 00052 } 00053 00054 // PUBLIC METHODS00055 // ---------------------------------------------------------------------------00056 // When the display powers up, it is configured as follows:00057 //00058 // 1. Display clear00059 // 2. Function set: 00060 // DL = 1; 8-bit interface data 00061 // N = 0; 1-line display 00062 // F = 0; 5x8 dot character font 00063 // 3. Display on/off control: 00064 // D = 0; Display off 00065 // C = 0; Cursor off 00066 // B = 0; Blinking off 00067 // 4. Entry mode set: 00068 // I/D = 1; Increment by 1 00069 // S = 0; No shift 00070 //00071 // Note, however, that resetting the Arduino doesn't reset the LCD, so we00072 // can't assume that its in that state when a sketch starts (and the00073 // LiquidCrystal constructor is called).00074 // A call to begin() will reinitialize the LCD.00075 //00076voidLCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 00077 { 00078 if (lines > 1) 00079 { 00080 _displayfunction |= LCD_2LINE; 00081 } 00082 _numlines = lines; 00083 _cols = cols; 00084 00085 // for some 1 line displays you can select a 10 pixel high font00086 // ------------------------------------------------------------00087 if ((dotsize != LCD_5x8DOTS) && (lines == 1)) 00088 { 00089 _displayfunction |= LCD_5x10DOTS; 00090 } 00091 00092 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!00093 // according to datasheet, we need at least 40ms after power rises above 2.7V00094 // before sending commands. Arduino can turn on way before 4.5V so we'll wait 00095 // 5000096 // ---------------------------------------------------------------------------00097 delay (100); // 100ms delay00098 00099 //put the LCD into 4 bit or 8 bit mode00100 // -------------------------------------00101 if (! (_displayfunction & LCD_8BITMODE)) 00102 { 00103 // this is according to the hitachi HD44780 datasheet00104 // figure 24, pg 4600105 00106 // we start in 8bit mode, try to set 4 bit mode00107 send(0x03, FOUR_BITS); 00108 delayMicroseconds(4500); // wait min 4.1ms00109 00110 // second try00111 send ( 0x03, FOUR_BITS ); 00112 delayMicroseconds(4500); // wait min 4.1ms00113 00114 // third go!00115 send( 0x03, FOUR_BITS ); 00116 delayMicroseconds(150); 00117 00118 // finally, set to 4-bit interface00119 send ( 0x02, FOUR_BITS ); 00120 } 00121 else00122 { 00123 // this is according to the hitachi HD44780 datasheet00124 // page 45 figure 2300125 00126 // Send function set command sequence00127 command(LCD_FUNCTIONSET | _displayfunction); 00128 delayMicroseconds(4500); // wait more than 4.1ms00129 00130 // second try00131 command(LCD_FUNCTIONSET | _displayfunction); 00132 delayMicroseconds(150); 00133 00134 // third go00135 command(LCD_FUNCTIONSET | _displayfunction); 00136 } 00137 00138 // finally, set # lines, font size, etc.00139 command(LCD_FUNCTIONSET | _displayfunction); 00140 00141 // turn the display on with no cursor or blinking default00142 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 00143 display(); 00144 00145 // clear the LCD00146 clear(); 00147 00148 // Initialize to default text direction (for romance languages)00149 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 00150 // set the entry mode00151 command(LCD_ENTRYMODESET | _displaymode); 00152 00153 backlight(); 00154 00155 } 00156 00157 // Common LCD Commands00158 // ---------------------------------------------------------------------------00159voidLCD::clear() 00160 { 00161 command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero00162 delayMicroseconds(HOME_CLEAR_EXEC); // this command is time consuming00163 } 00164 00165voidLCD::home() 00166 { 00167 command(LCD_RETURNHOME); // set cursor position to zero00168 delayMicroseconds(HOME_CLEAR_EXEC); // This command is time consuming00169 } 00170 00171voidLCD::setCursor(uint8_t col, uint8_t row) 00172 { 00173 const byte row_offsetsDef[] = { 0x00, 0x40, 0x14, 0x54 }; // For regular LCDs00174 const byte row_offsetsLarge[] = { 0x00, 0x40, 0x10, 0x50 }; // For 16x4 LCDs00175 00176 if ( row >= _numlines ) 00177 { 00178 row = _numlines-1; // rows start at 000179 } 00180 00181 // 16x4 LCDs have special memory map layout00182 // ----------------------------------------00183 if ( _cols == 16 && _numlines == 4 ) 00184 { 00185 command(LCD_SETDDRAMADDR | (col + row_offsetsLarge[row])); 00186 } 00187 else00188 { 00189 command(LCD_SETDDRAMADDR | (col + row_offsetsDef[row])); 00190 } 00191 00192 } 00193 00194 // Turn the display on/off00195voidLCD::noDisplay() 00196 { 00197 _displaycontrol &= ~LCD_DISPLAYON; 00198 command(LCD_DISPLAYCONTROL | _displaycontrol); 00199 } 00200 00201voidLCD::display() 00202 { 00203 _displaycontrol |= LCD_DISPLAYON; 00204 command(LCD_DISPLAYCONTROL | _displaycontrol); 00205 } 00206 00207 // Turns the underline cursor on/off00208voidLCD::noCursor() 00209 { 00210 _displaycontrol &= ~LCD_CURSORON; 00211 command(LCD_DISPLAYCONTROL | _displaycontrol); 00212 } 00213voidLCD::cursor() 00214 { 00215 _displaycontrol |= LCD_CURSORON; 00216 command(LCD_DISPLAYCONTROL | _displaycontrol); 00217 } 00218 00219 // Turns on/off the blinking cursor00220voidLCD::noBlink() 00221 { 00222 _displaycontrol &= ~LCD_BLINKON; 00223 command(LCD_DISPLAYCONTROL | _displaycontrol); 00224 } 00225 00226voidLCD::blink() 00227 { 00228 _displaycontrol |= LCD_BLINKON; 00229 command(LCD_DISPLAYCONTROL | _displaycontrol); 00230 } 00231 00232 // These commands scroll the display without changing the RAM00233voidLCD::scrollDisplayLeft(void) 00234 { 00235 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 00236 } 00237 00238voidLCD::scrollDisplayRight(void) 00239 { 00240 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 00241 } 00242 00243 // This is for text that flows Left to Right00244voidLCD::leftToRight(void) 00245 { 00246 _displaymode |= LCD_ENTRYLEFT; 00247 command(LCD_ENTRYMODESET | _displaymode); 00248 } 00249 00250 // This is for text that flows Right to Left00251voidLCD::rightToLeft(void) 00252 { 00253 _displaymode &= ~LCD_ENTRYLEFT; 00254 command(LCD_ENTRYMODESET | _displaymode); 00255 } 00256 00257 // This method moves the cursor one space to the right00258voidLCD::moveCursorRight(void) 00259 { 00260 command(LCD_CURSORSHIFT | LCD_CURSORMOVE | LCD_MOVERIGHT); 00261 } 00262 00263 // This method moves the cursor one space to the left00264voidLCD::moveCursorLeft(void) 00265 { 00266 command(LCD_CURSORSHIFT | LCD_CURSORMOVE | LCD_MOVELEFT); 00267 } 00268 00269 00270 // This will 'right justify' text from the cursor00271voidLCD::autoscroll(void) 00272 { 00273 _displaymode |= LCD_ENTRYSHIFTINCREMENT; 00274 command(LCD_ENTRYMODESET | _displaymode); 00275 } 00276 00277 // This will 'left justify' text from the cursor00278voidLCD::noAutoscroll(void) 00279 { 00280 _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; 00281 command(LCD_ENTRYMODESET | _displaymode); 00282 } 00283 00284 // Write to CGRAM of new characters00285voidLCD::createChar(uint8_t location, uint8_t charmap[]) 00286 { 00287 location &= 0x7; // we only have 8 locations 0-700288 00289 command(LCD_SETCGRAMADDR | (location << 3)); 00290 delayMicroseconds(30); 00291 00292 for (int i=0; i<8; i++) 00293 { 00294 write(charmap[i]); // call the virtual write method00295 delayMicroseconds(40); 00296 } 00297 } 00298 00299 //00300 // Switch on the backlight00301voidLCD::backlight ( void ) 00302 { 00303 setBacklight(255); 00304 } 00305 00306 //00307 // Switch off the backlight00308voidLCD::noBacklight ( void ) 00309 { 00310 setBacklight(0); 00311 } 00312 00313 //00314 // Switch fully on the LCD (backlight and LCD)00315voidLCD::on ( void ) 00316 { 00317 display(); 00318 backlight(); 00319 } 00320 00321 //00322 // Switch fully off the LCD (backlight and LCD) 00323voidLCD::off ( void ) 00324 { 00325 noBacklight(); 00326 noDisplay(); 00327 } 00328 00329 // General LCD commands - generic methods used by the rest of the commands00330 // ---------------------------------------------------------------------------00331 void LCD::command(uint8_t value) 00332 { 00333 send(value, COMMAND); 00334 } 00335 00336 #if (ARDUINO < 100)00337voidLCD::write(uint8_t value) 00338 { 00339 send(value, DATA); 00340 } 00341 #else00342 size_tLCD::write(uint8_t value) 00343 { 00344 send(value, DATA); 00345 return 1; // assume OK00346 } 00347 #endif