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-SA 00005 // 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: No 00010 // Extendable: Yes 00011 // 00012 // @file LiquidCrystal_I2C.c 00013 // This file implements a basic liquid crystal library that comes as standard 00014 // in the Arduino SDK but using an I2C IO extension board. 00015 // 00016 // @brief 00017 // This is a basic implementation of the LiquidCrystal library of the 00018 // Arduino SDK. The original library has been reworked in such a way that 00019 // this class implements the all methods to command an LCD based 00020 // on the Hitachi HD44780 and compatible chipsets using I2C extension 00021 // backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC. 00022 // 00023 // The functionality provided by this class and its base class is identical 00024 // to the original functionality of the Arduino LiquidCrystal library. 00025 // 00026 // 00027 // 00028 // @author F. Malpartida - [email protected] 00029 // --------------------------------------------------------------------------- 00030 #if (ARDUINO < 100) 00031 #include <WProgram.h> 00032 #else 00033 #include <Arduino.h> 00034 #endif 00035 #include <inttypes.h> 00036 #include "I2CIO.h" 00037 #include "LiquidCrystal_I2C.h" 00038 00039 // CONSTANT definitions 00040 // --------------------------------------------------------------------------- 00041 00042 // flags for backlight control 00048 #define LCD_NOBACKLIGHT 0x00 00049 00055 #define LCD_BACKLIGHT 0xFF 00056 00057 00058 // Default library configuration parameters used by class constructor with 00059 // only the I2C address field. 00060 // --------------------------------------------------------------------------- 00066 #define EN 6 // Enable bit 00067 00073 #define RW 5 // Read/Write bit 00074 00080 #define RS 4 // Register select bit 00081 00088 #define D4 0 00089 #define D5 1 00090 #define D6 2 00091 #define D7 3 00092 00093 00094 // CONSTRUCTORS 00095 // --------------------------------------------------------------------------- 00096 LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr ) 00097 { 00098 config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7); 00099 } 00100 00101 00102 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t backlighPin, 00103 t_backlighPol pol = POSITIVE) 00104 { 00105 config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7); 00106 setBacklightPin(backlighPin, pol); 00107 } 00108 00109 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, 00110 uint8_t Rs) 00111 { 00112 config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7); 00113 } 00114 00115 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, 00116 uint8_t Rs, uint8_t backlighPin, 00117 t_backlighPol pol = POSITIVE) 00118 { 00119 config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7); 00120 setBacklightPin(backlighPin, pol); 00121 } 00122 00123 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, 00124 uint8_t Rs, uint8_t d4, uint8_t d5, 00125 uint8_t d6, uint8_t d7 ) 00126 { 00127 config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7); 00128 } 00129 00130 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, 00131 uint8_t Rs, uint8_t d4, uint8_t d5, 00132 uint8_t d6, uint8_t d7, uint8_t backlighPin, 00133 t_backlighPol pol = POSITIVE ) 00134 { 00135 config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7); 00136 setBacklightPin(backlighPin, pol); 00137 } 00138 00139 // PUBLIC METHODS 00140 // --------------------------------------------------------------------------- 00141 00142 // 00143 // begin 00144 void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 00145 { 00146 00147 init(); // Initialise the I2C expander interface 00148 LCD::begin ( cols, lines, dotsize ); 00149 } 00150 00151 00152 // User commands - users can expand this section 00153 //---------------------------------------------------------------------------- 00154 // Turn the (optional) backlight off/on 00155 00156 // 00157 // setBacklightPin 00158 void LiquidCrystal_I2C::setBacklightPin ( uint8_t value, t_backlighPol pol = POSITIVE ) 00159 { 00160 _backlightPinMask = ( 1 << value ); 00161 _polarity = pol; 00162 setBacklight(BACKLIGHT_OFF); 00163 } 00164 00165 // 00166 // setBacklight 00167 void LiquidCrystal_I2C::setBacklight( uint8_t value ) 00168 { 00169 // Check if backlight is available 00170 // ---------------------------------------------------- 00171 if ( _backlightPinMask != 0x0 ) 00172 { 00173 // Check for polarity to configure mask accordingly 00174 // ---------------------------------------------------------- 00175 if (((_polarity == POSITIVE) && (value > 0)) || 00176 ((_polarity == NEGATIVE ) && ( value == 0 ))) 00177 { 00178 _backlightStsMask = _backlightPinMask & LCD_BACKLIGHT; 00179 } 00180 else 00181 { 00182 _backlightStsMask = _backlightPinMask & LCD_NOBACKLIGHT; 00183 } 00184 _i2cio.write( _backlightStsMask ); 00185 } 00186 } 00187 00188 00189 // PRIVATE METHODS 00190 // --------------------------------------------------------------------------- 00191 00192 // 00193 // init 00194 int LiquidCrystal_I2C::init() 00195 { 00196 int status = 0; 00197 00198 // initialize the backpack IO expander 00199 // and display functions. 00200 // ------------------------------------------------------------------------ 00201 if ( _i2cio.begin ( _Addr ) == 1 ) 00202 { 00203 _i2cio.portMode ( OUTPUT ); // Set the entire IO extender to OUTPUT 00204 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 00205 status = 1; 00206 _i2cio.write(0); // Set the entire port to LOW 00207 } 00208 return ( status ); 00209 } 00210 00211 // 00212 // config 00213 void LiquidCrystal_I2C::config (uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs, 00214 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 ) 00215 { 00216 _Addr = lcd_Addr; 00217 00218 _backlightPinMask = 0; 00219 _backlightStsMask = LCD_NOBACKLIGHT; 00220 _polarity = POSITIVE; 00221 00222 _En = ( 1 << En ); 00223 _Rw = ( 1 << Rw ); 00224 _Rs = ( 1 << Rs ); 00225 00226 // Initialise pin mapping 00227 _data_pins[0] = ( 1 << d4 ); 00228 _data_pins[1] = ( 1 << d5 ); 00229 _data_pins[2] = ( 1 << d6 ); 00230 _data_pins[3] = ( 1 << d7 ); 00231 } 00232 00233 00234 00235 // low level data pushing commands 00236 //---------------------------------------------------------------------------- 00237 00238 // 00239 // send - write either command or data 00240 void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) 00241 { 00242 // No need to use the delay routines since the time taken to write takes 00243 // longer that what is needed both for toggling and enable pin an to execute 00244 // the command. 00245 00246 if ( mode == FOUR_BITS ) 00247 { 00248 write4bits( (value & 0x0F), COMMAND ); 00249 } 00250 else 00251 { 00252 write4bits( (value >> 4), mode ); 00253 write4bits( (value & 0x0F), mode); 00254 } 00255 } 00256 00257 // 00258 // write4bits 00259 void LiquidCrystal_I2C::write4bits ( uint8_t value, uint8_t mode ) 00260 { 00261 uint8_t pinMapValue = 0; 00262 00263 // Map the value to LCD pin mapping 00264 // -------------------------------- 00265 for ( uint8_t i = 0; i < 4; i++ ) 00266 { 00267 if ( ( value & 0x1 ) == 1 ) 00268 { 00269 pinMapValue |= _data_pins[i]; 00270 } 00271 value = ( value >> 1 ); 00272 } 00273 00274 // Is it a command or data 00275 // ----------------------- 00276 if ( mode == DATA ) 00277 { 00278 mode = _Rs; 00279 } 00280 00281 pinMapValue |= mode | _backlightStsMask; 00282 pulseEnable ( pinMapValue ); 00283 } 00284 00285 // 00286 // pulseEnable 00287 void LiquidCrystal_I2C::pulseEnable (uint8_t data) 00288 { 00289 _i2cio.write (data | _En); // En HIGH 00290 _i2cio.write (data & ~_En); // En LOW 00291 }