Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LiquidCrystal_I2C.cpp
00001 // Based on the work by DFRobot upgraded by DVSProductions 00002 #include "LiquidCrystal_I2C.h" 00003 #include <inttypes.h> 00004 /*********** mid level commands, for sending data/cmds */ 00005 #define COMMAND(value) send(value, 0) 00006 #define printIIC(args) i2c->write(_Addr, args, 1) 00007 size_t LiquidCrystal_I2C::write(uint8_t value) { 00008 send(value, Rs); 00009 return 1; 00010 } 00011 00012 inline void LiquidCrystal_I2C::command(uint8_t value) { 00013 send(value, 0); 00014 } 00015 00016 // When the display powers up, it is configured as follows: 00017 // 00018 // 1. Display clear 00019 // 2. Function set: 00020 // DL = 1; 8-bit interface data 00021 // N = 0; 1-line display 00022 // F = 0; 5x8 dot character font 00023 // 3. Display on/off control: 00024 // D = 0; Display off 00025 // C = 0; Cursor off 00026 // B = 0; Blinking off 00027 // 4. Entry mode set: 00028 // I/D = 1; Increment by 1 00029 // S = 0; No shift 00030 // 00031 // Note, however, that resetting the Arduino doesn't reset the LCD, so we 00032 // can't assume that its in that state when a sketch starts (and the 00033 // LiquidCrystal constructor is called). 00034 00035 /*! 00036 Creates a new LCD instance 00037 !*/ 00038 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows, PinName sda, PinName scl) { 00039 _Addr = lcd_Addr << 1; 00040 _cols = lcd_cols; 00041 _rows = lcd_rows; 00042 _backlightval = LCD_NOBACKLIGHT; 00043 i2c = new I2C(sda, scl); 00044 i2c->frequency(1000000); 00045 } 00046 00047 void LiquidCrystal_I2C::init() { 00048 init_priv(); 00049 } 00050 00051 void LiquidCrystal_I2C::init_priv() { 00052 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 00053 begin_priv(); 00054 } 00055 void LiquidCrystal_I2C::begin_priv(uint8_t dotsize) { 00056 if (_rows > 1) { 00057 _displayfunction |= LCD_2LINE; 00058 } 00059 _numlines = _rows; 00060 // for some 1 line displays you can select a 10 pixel high font 00061 if ((dotsize != 0) && (_rows == 1)) { 00062 _displayfunction |= LCD_5x10DOTS; 00063 } 00064 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 00065 // according to datasheet, we need at least 40ms after power rises above 2.7V 00066 // before sending commands. Nucleo can turn on way befer 4.5V so we'll wait 00067 // 50 00068 wait_ms(50); 00069 // Now we pull both RS and R/W low to begin commands 00070 expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) 00071 wait_ms(1000); 00072 // put the LCD into 4 bit mode 00073 // this is according to the hitachi HD44780 datasheet 00074 // figure 24, pg 46 00075 00076 // we start in 8bit mode, try to set 4 bit mode 00077 write4bits(0x03 << 4); 00078 wait_us(4100); // wait min 4.1ms 00079 // second try 00080 write4bits(0x03 << 4); 00081 wait_us(4100); // wait min 4.1ms 00082 // third go! 00083 write4bits(0x03 << 4); 00084 wait_us(150); 00085 // finally, set to 4-bit interface 00086 write4bits(0x02 << 4); 00087 // set # lines, font size, etc. 00088 COMMAND(LCD_FUNCTIONSET | _displayfunction); 00089 // turn the display on with no cursor or blinking default 00090 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 00091 display(); 00092 // clear it off 00093 clear(); 00094 // Initialize to default text direction (for roman languages) 00095 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 00096 // set the entry mode 00097 COMMAND(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT); 00098 home(); 00099 } 00100 void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { 00101 _cols = cols; 00102 _rows = lines; 00103 begin_priv(); 00104 } 00105 00106 /********** high level commands, for the user! */ 00107 void LiquidCrystal_I2C::clear() { 00108 COMMAND(LCD_CLEARDISPLAY); // clear display, set cursor position to zero 00109 wait_us(2000); // this command takes a long time! 00110 } 00111 00112 void LiquidCrystal_I2C::home() { 00113 COMMAND(LCD_RETURNHOME); // set cursor position to zero 00114 wait_us(2000); // this command takes a long time! 00115 } 00116 00117 void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row) { 00118 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; 00119 if (row > _numlines) 00120 row = _numlines - 1; // we count rows starting w/0 00121 COMMAND(LCD_SETDDRAMADDR | (col + row_offsets[row])); 00122 } 00123 00124 // Turn the display on/off (quickly) 00125 void LiquidCrystal_I2C::noDisplay() { 00126 _displaycontrol &= ~LCD_DISPLAYON; 00127 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00128 } 00129 void LiquidCrystal_I2C::display() { 00130 _displaycontrol |= LCD_DISPLAYON; 00131 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00132 } 00133 00134 // Turns the underline cursor on/off 00135 void LiquidCrystal_I2C::noCursor() { 00136 _displaycontrol &= ~LCD_CURSORON; 00137 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00138 } 00139 void LiquidCrystal_I2C::cursor() { 00140 _displaycontrol |= LCD_CURSORON; 00141 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00142 } 00143 00144 // Turn on and off the blinking cursor 00145 void LiquidCrystal_I2C::noBlink() { 00146 _displaycontrol &= ~LCD_BLINKON; 00147 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00148 } 00149 void LiquidCrystal_I2C::blink() { 00150 _displaycontrol |= LCD_BLINKON; 00151 COMMAND(LCD_DISPLAYCONTROL | _displaycontrol); 00152 } 00153 00154 // These commands scroll the display without changing the RAM 00155 void LiquidCrystal_I2C::scrollDisplayLeft(void) { 00156 COMMAND(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 00157 } 00158 void LiquidCrystal_I2C::scrollDisplayRight(void) { 00159 COMMAND(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 00160 } 00161 00162 // This is for text that flows Left to Right 00163 void LiquidCrystal_I2C::leftToRight(void) { 00164 _displaymode |= LCD_ENTRYLEFT; 00165 COMMAND(LCD_ENTRYMODESET | _displaymode); 00166 } 00167 00168 // This is for text that flows Right to Left 00169 void LiquidCrystal_I2C::rightToLeft(void) { 00170 _displaymode &= ~LCD_ENTRYLEFT; 00171 COMMAND(LCD_ENTRYMODESET | _displaymode); 00172 } 00173 00174 // This will 'right justify' text from the cursor 00175 void LiquidCrystal_I2C::autoscroll(void) { 00176 _displaymode |= LCD_ENTRYSHIFTINCREMENT; 00177 COMMAND(LCD_ENTRYMODESET | _displaymode); 00178 } 00179 00180 // This will 'left justify' text from the cursor 00181 void LiquidCrystal_I2C::noAutoscroll(void) { 00182 _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; 00183 COMMAND(LCD_ENTRYMODESET | _displaymode); 00184 } 00185 00186 // Allows us to fill the first 8 CGRAM locations 00187 // with custom characters 00188 void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { 00189 location &= 0x7; // we only have 8 locations 0-7 00190 COMMAND(LCD_SETCGRAMADDR | (location << 3)); 00191 for (uint8_t i = 0; i != 8; i++) 00192 write(charmap[i]); 00193 } 00194 00195 // Turn the (optional) backlight off/on 00196 void LiquidCrystal_I2C::noBacklight(void) { 00197 _backlightval = LCD_NOBACKLIGHT; 00198 expanderWrite(0); 00199 } 00200 00201 void LiquidCrystal_I2C::backlight(void) { 00202 _backlightval = LCD_BACKLIGHT; 00203 expanderWrite(0); 00204 } 00205 00206 /************ low level data pushing commands **********/ 00207 00208 // write either command or data 00209 void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { 00210 uint8_t highnib = value & 0xf0; 00211 uint8_t lownib = (value << 4) & 0xf0; 00212 write4bits((highnib) | mode); 00213 write4bits((lownib) | mode); 00214 } 00215 00216 void LiquidCrystal_I2C::write4bits(uint8_t value) { 00217 expanderWrite(value); 00218 pulseEnable(value); 00219 } 00220 char buff; 00221 inline void LiquidCrystal_I2C::expanderWrite(uint8_t _data) { 00222 buff = (_data) | _backlightval; 00223 printIIC(&buff); 00224 } 00225 00226 void LiquidCrystal_I2C::pulseEnable(uint8_t _data) { 00227 expanderWrite(_data | En); // En high 00228 wait_us(1); // enable pulse must be >450ns 00229 00230 expanderWrite(_data & ~En); // En low 00231 wait_us(10); // commands need > 37us to settle 00232 } 00233 00234 // Alias functions 00235 00236 inline void LiquidCrystal_I2C::cursor_on() { 00237 cursor(); 00238 } 00239 00240 inline void LiquidCrystal_I2C::cursor_off() { 00241 noCursor(); 00242 } 00243 00244 inline void LiquidCrystal_I2C::blink_on() { 00245 blink(); 00246 } 00247 00248 inline void LiquidCrystal_I2C::blink_off() { 00249 noBlink(); 00250 } 00251 00252 inline void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows) { 00253 createChar(char_num, rows); 00254 } 00255 00256 void LiquidCrystal_I2C::setBacklight(uint8_t new_val) { 00257 if (new_val) 00258 backlight(); // turn backlight on 00259 else 00260 noBacklight(); // turn backlight off 00261 } 00262 00263 void LiquidCrystal_I2C::printstr(const char c[]) { 00264 // This function is not identical to the function used for "real" I2C displays 00265 // it's here so the use sketch doesn't have to be changed 00266 print(c); 00267 } 00268 00269 // unsupported API functions 00270 void LiquidCrystal_I2C::off() { 00271 noBacklight(); 00272 } 00273 void LiquidCrystal_I2C::on() { 00274 begin_priv(); 00275 backlight(); 00276 } 00277 void LiquidCrystal_I2C::setDelay(int cmdDelay, int charDelay) {} 00278 uint8_t LiquidCrystal_I2C::status() { 00279 return 0; 00280 } 00281 uint8_t LiquidCrystal_I2C::keypad() { 00282 return 0; 00283 } 00284 uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype) { 00285 return 0; 00286 } 00287 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, 00288 uint8_t len, 00289 uint8_t pixel_col_end) { 00290 } 00291 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, 00292 uint8_t len, 00293 uint8_t pixel_row_end) { 00294 } 00295 void LiquidCrystal_I2C::setContrast(uint8_t new_val) {}
Generated on Wed Aug 17 2022 02:55:29 by
1.7.2