LiquidCrystal_I2C.cpp (8584B)
1 // Based on the work by DFRobot 2 3 #include "LiquidCrystal_I2C.h" 4 #include <inttypes.h> 5 #if defined(ARDUINO) && ARDUINO >= 100 6 7 #include "Arduino.h" 8 9 #define printIIC(args) Wire.write(args) 10 inline size_t LiquidCrystal_I2C::write(uint8_t value) { 11 send(value, Rs); 12 return 1; 13 } 14 15 #else 16 #include "WProgram.h" 17 18 #define printIIC(args) Wire.send(args) 19 inline void LiquidCrystal_I2C::write(uint8_t value) { 20 send(value, Rs); 21 } 22 23 #endif 24 #include "Wire.h" 25 26 27 28 // When the display powers up, it is configured as follows: 29 // 30 // 1. Display clear 31 // 2. Function set: 32 // DL = 1; 8-bit interface data 33 // N = 0; 1-line display 34 // F = 0; 5x8 dot character font 35 // 3. Display on/off control: 36 // D = 0; Display off 37 // C = 0; Cursor off 38 // B = 0; Blinking off 39 // 4. Entry mode set: 40 // I/D = 1; Increment by 1 41 // S = 0; No shift 42 // 43 // Note, however, that resetting the Arduino doesn't reset the LCD, so we 44 // can't assume that its in that state when a sketch starts (and the 45 // LiquidCrystal constructor is called). 46 47 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) 48 { 49 _Addr = lcd_Addr; 50 _cols = lcd_cols; 51 _rows = lcd_rows; 52 _backlightval = LCD_NOBACKLIGHT; 53 } 54 55 void LiquidCrystal_I2C::init(){ 56 init_priv(); 57 } 58 59 void LiquidCrystal_I2C::init_priv() 60 { 61 Wire.begin(); 62 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 63 begin(_cols, _rows); 64 } 65 66 void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { 67 if (lines > 1) { 68 _displayfunction |= LCD_2LINE; 69 } 70 _numlines = lines; 71 72 // for some 1 line displays you can select a 10 pixel high font 73 if ((dotsize != 0) && (lines == 1)) { 74 _displayfunction |= LCD_5x10DOTS; 75 } 76 77 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! 78 // according to datasheet, we need at least 40ms after power rises above 2.7V 79 // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 80 delay(50); 81 82 // Now we pull both RS and R/W low to begin commands 83 expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) 84 delay(1000); 85 86 //put the LCD into 4 bit mode 87 // this is according to the hitachi HD44780 datasheet 88 // figure 24, pg 46 89 90 // we start in 8bit mode, try to set 4 bit mode 91 write4bits(0x03 << 4); 92 delayMicroseconds(4500); // wait min 4.1ms 93 94 // second try 95 write4bits(0x03 << 4); 96 delayMicroseconds(4500); // wait min 4.1ms 97 98 // third go! 99 write4bits(0x03 << 4); 100 delayMicroseconds(150); 101 102 // finally, set to 4-bit interface 103 write4bits(0x02 << 4); 104 105 106 // set # lines, font size, etc. 107 command(LCD_FUNCTIONSET | _displayfunction); 108 109 // turn the display on with no cursor or blinking default 110 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; 111 display(); 112 113 // clear it off 114 clear(); 115 116 // Initialize to default text direction (for roman languages) 117 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; 118 119 // set the entry mode 120 command(LCD_ENTRYMODESET | _displaymode); 121 122 home(); 123 124 } 125 126 /********** high level commands, for the user! */ 127 void LiquidCrystal_I2C::clear(){ 128 command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero 129 delayMicroseconds(2000); // this command takes a long time! 130 } 131 132 void LiquidCrystal_I2C::home(){ 133 command(LCD_RETURNHOME); // set cursor position to zero 134 delayMicroseconds(2000); // this command takes a long time! 135 } 136 137 void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){ 138 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; 139 if ( row > _numlines ) { 140 row = _numlines-1; // we count rows starting w/0 141 } 142 command(LCD_SETDDRAMADDR | (col + row_offsets[row])); 143 } 144 145 // Turn the display on/off (quickly) 146 void LiquidCrystal_I2C::noDisplay() { 147 _displaycontrol &= ~LCD_DISPLAYON; 148 command(LCD_DISPLAYCONTROL | _displaycontrol); 149 } 150 void LiquidCrystal_I2C::display() { 151 _displaycontrol |= LCD_DISPLAYON; 152 command(LCD_DISPLAYCONTROL | _displaycontrol); 153 } 154 155 // Turns the underline cursor on/off 156 void LiquidCrystal_I2C::noCursor() { 157 _displaycontrol &= ~LCD_CURSORON; 158 command(LCD_DISPLAYCONTROL | _displaycontrol); 159 } 160 void LiquidCrystal_I2C::cursor() { 161 _displaycontrol |= LCD_CURSORON; 162 command(LCD_DISPLAYCONTROL | _displaycontrol); 163 } 164 165 // Turn on and off the blinking cursor 166 void LiquidCrystal_I2C::noBlink() { 167 _displaycontrol &= ~LCD_BLINKON; 168 command(LCD_DISPLAYCONTROL | _displaycontrol); 169 } 170 void LiquidCrystal_I2C::blink() { 171 _displaycontrol |= LCD_BLINKON; 172 command(LCD_DISPLAYCONTROL | _displaycontrol); 173 } 174 175 // These commands scroll the display without changing the RAM 176 void LiquidCrystal_I2C::scrollDisplayLeft(void) { 177 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); 178 } 179 void LiquidCrystal_I2C::scrollDisplayRight(void) { 180 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); 181 } 182 183 // This is for text that flows Left to Right 184 void LiquidCrystal_I2C::leftToRight(void) { 185 _displaymode |= LCD_ENTRYLEFT; 186 command(LCD_ENTRYMODESET | _displaymode); 187 } 188 189 // This is for text that flows Right to Left 190 void LiquidCrystal_I2C::rightToLeft(void) { 191 _displaymode &= ~LCD_ENTRYLEFT; 192 command(LCD_ENTRYMODESET | _displaymode); 193 } 194 195 // This will 'right justify' text from the cursor 196 void LiquidCrystal_I2C::autoscroll(void) { 197 _displaymode |= LCD_ENTRYSHIFTINCREMENT; 198 command(LCD_ENTRYMODESET | _displaymode); 199 } 200 201 // This will 'left justify' text from the cursor 202 void LiquidCrystal_I2C::noAutoscroll(void) { 203 _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; 204 command(LCD_ENTRYMODESET | _displaymode); 205 } 206 207 // Allows us to fill the first 8 CGRAM locations 208 // with custom characters 209 void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { 210 location &= 0x7; // we only have 8 locations 0-7 211 command(LCD_SETCGRAMADDR | (location << 3)); 212 for (int i=0; i<8; i++) { 213 write(charmap[i]); 214 } 215 } 216 217 // Turn the (optional) backlight off/on 218 void LiquidCrystal_I2C::noBacklight(void) { 219 _backlightval=LCD_NOBACKLIGHT; 220 expanderWrite(0); 221 } 222 223 void LiquidCrystal_I2C::backlight(void) { 224 _backlightval=LCD_BACKLIGHT; 225 expanderWrite(0); 226 } 227 228 229 230 /*********** mid level commands, for sending data/cmds */ 231 232 inline void LiquidCrystal_I2C::command(uint8_t value) { 233 send(value, 0); 234 } 235 236 237 /************ low level data pushing commands **********/ 238 239 // write either command or data 240 void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { 241 uint8_t highnib=value&0xf0; 242 uint8_t lownib=(value<<4)&0xf0; 243 write4bits((highnib)|mode); 244 write4bits((lownib)|mode); 245 } 246 247 void LiquidCrystal_I2C::write4bits(uint8_t value) { 248 expanderWrite(value); 249 pulseEnable(value); 250 } 251 252 void LiquidCrystal_I2C::expanderWrite(uint8_t _data){ 253 Wire.beginTransmission(_Addr); 254 printIIC((int)(_data) | _backlightval); 255 Wire.endTransmission(); 256 } 257 258 void LiquidCrystal_I2C::pulseEnable(uint8_t _data){ 259 expanderWrite(_data | En); // En high 260 delayMicroseconds(1); // enable pulse must be >450ns 261 262 expanderWrite(_data & ~En); // En low 263 delayMicroseconds(50); // commands need > 37us to settle 264 } 265 266 267 // Alias functions 268 269 void LiquidCrystal_I2C::cursor_on(){ 270 cursor(); 271 } 272 273 void LiquidCrystal_I2C::cursor_off(){ 274 noCursor(); 275 } 276 277 void LiquidCrystal_I2C::blink_on(){ 278 blink(); 279 } 280 281 void LiquidCrystal_I2C::blink_off(){ 282 noBlink(); 283 } 284 285 void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){ 286 createChar(char_num, rows); 287 } 288 289 void LiquidCrystal_I2C::setBacklight(uint8_t new_val){ 290 if(new_val){ 291 backlight(); // turn backlight on 292 }else{ 293 noBacklight(); // turn backlight off 294 } 295 } 296 297 void LiquidCrystal_I2C::printstr(const char c[]){ 298 //This function is not identical to the function used for "real" I2C displays 299 //it's here so the user sketch doesn't have to be changed 300 print(c); 301 } 302 303 304 // unsupported API functions 305 void LiquidCrystal_I2C::off(){} 306 void LiquidCrystal_I2C::on(){} 307 void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {} 308 uint8_t LiquidCrystal_I2C::status(){return 0;} 309 uint8_t LiquidCrystal_I2C::keypad (){return 0;} 310 uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;} 311 void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){} 312 void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){} 313 void LiquidCrystal_I2C::setContrast(uint8_t new_val){} 314 315