LiquidCrystal_I2C.cpp
#include <&LiquidCrystal_I2C.h>
#write LiquidCrystal_I2c oled_init init
init_priv begin clear home
setCursor noDisplay display noCursor
cursor noBlink blink scrollDisplayLeft
scrollDisplayRight leftToRight rightToLeft autoscroll
no-autoscroll createChar noBacklight backlight
send write4bits expanderWrite pulseEnable
cursor_on cursor_off blink_on load_custom_character
setBacklight printstr
/*F********************************************************************
* Based on the work by DFRobot
**********************************************************************/
#include "LiquidCrystal_I2C.h"
#include 
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"

//************** DEFINES ********************************
#define printIIC( args )    Wire.write( args )


/*F******************************************************************** * **********************************************************************/ inline size_t LiquidCrystal_I2C:: write( uint8_t value ) { send( value, Rs); return 1; } #else #include "WProgram.h" #define printIIC(args) Wire.send(args) inline void LiquidCrystal_I2C:: write( uint8_t value ) { send( value, Rs); } #endif #include "Wire.h" // When display powers up, it is configured as follows: // 1. Display clear // 2. Function set: // DL = 1; 8-bit interface data // N = 0; 1-line display // F = 0; 5x8 dot character font // 3. Display on/off control: // D = 0; Display off // C = 0; Cursor off // B = 0; Blinking off // 4. Entry mode set: // I/D = 1; Increment by 1 // S = 0; No shift // // Note, however, that resetting the Arduino doesn't reset LCD, so // can't assume that its in that state when a sketch starts (and the // LiquidCrystal constructor is called).
/*F******************************************************************** * **********************************************************************/ LiquidCrystal_I2C:: LiquidCrystal_I2C( uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows ) { _Addr = lcd_Addr; _cols = lcd_cols; _rows = lcd_rows; _backlightval = LCD_NOBACKLIGHT; }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: oled_init() { _oled = true; init_priv(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: init() { init_priv(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: init_priv() { Wire.begin(); _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; begin(_cols, _rows); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: begin( uint8_t cols, uint8_t lines, uint8_t dotsize) { if( lines > 1) _displayfunction |= LCD_2LINE; _numlines = lines; // for some 1 line displays you can select a 10 pixel high font if( (dotsize != 0) && (lines == 1)) _displayfunction |= LCD_5x10DOTS; // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, need at least 40ms after power rises above 2.7V // before sending commands. Arduino can turn on way befer 4.5V so wait 50 delay( 50 ); // Now we pull both RS and R/W low to begin commands expanderWrite( _backlightval ); // reset expanderand turn backlight off (Bit 8 =1) delay( 1000 ); // put LCD into 4 bit mode // this is according to hitachi HD44780 datasheet // figure 24, pg 46 // start in 8bit mode, try to set 4 bit mode write4bits( 0x03 << 4); delayMicroseconds( 4500 ); // wait min 4.1ms // second try write4bits( 0x03 << 4 ); delayMicroseconds( 4500 ); // wait min 4.1ms // third go! write4bits( 0x03 << 4 ); delayMicroseconds( 150 ); // finally, set to 4-bit interface write4bits( 0x02 << 4 ); // set # lines, font size, etc. command( LCD_FUNCTIONSET | _displayfunction); // turn display on with no cursor or blinking default _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; display(); clear(); // clear it off // Initialize to default text direction (for roman languages) _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; // set the entry mode command( LCD_ENTRYMODESET | _displaymode); home(); } /********** high level commands, for the user! */
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: clear() { command( LCD_CLEARDISPLAY );// clear display, set cursor position to zero delayMicroseconds( 2000 ); // this command takes a long time! if( _oled) setCursor( 0, 0 ); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: home() { command( LCD_RETURNHOME ); // set cursor position to zero delayMicroseconds( 2000 ); // this command takes a long time! }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: setCursor( uint8_t col, uint8_t row) { int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; if( row > _numlines ) row = _numlines-1; // we count rows starting w/0 command( LCD_SETDDRAMADDR | (col + row_offsets[row])); }
/*F******************************************************************** * Turn display on/off (quickly) **********************************************************************/ void LiquidCrystal_I2C:: noDisplay() { _displaycontrol &= ~LCD_DISPLAYON; command(LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: display() { _displaycontrol |= LCD_DISPLAYON; command(LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * Turns underline cursor on/off **********************************************************************/ void LiquidCrystal_I2C:: noCursor() { _displaycontrol &= ~LCD_CURSORON; command(LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: cursor() { _displaycontrol |= LCD_CURSORON; command( LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * Turn on and off the blinking cursor **********************************************************************/ void LiquidCrystal_I2C:: noBlink() { _displaycontrol &= ~LCD_BLINKON; command(LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: blink() { _displaycontrol |= LCD_BLINKON; command(LCD_DISPLAYCONTROL | _displaycontrol); }
/*F******************************************************************** * These commands scroll the display without changing the RAM **********************************************************************/ void LiquidCrystal_I2C:: scrollDisplayLeft( void ) { command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: scrollDisplayRight( void ) { command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); }
/*F******************************************************************** * This is for text that flows Left to Right **********************************************************************/ void LiquidCrystal_I2C:: leftToRight( void ) { _displaymode |= LCD_ENTRYLEFT; command(LCD_ENTRYMODESET | _displaymode); }
/*F******************************************************************** * This is for text that flows Right to Left **********************************************************************/ void LiquidCrystal_I2C:: rightToLeft( void ) { _displaymode &= ~LCD_ENTRYLEFT; command(LCD_ENTRYMODESET | _displaymode); }
/*F******************************************************************** * This will 'right justify' text from the cursor **********************************************************************/ void LiquidCrystal_I2C:: autoscroll( void ) { _displaymode |= LCD_ENTRYSHIFTINCREMENT; command(LCD_ENTRYMODESET | _displaymode); }
/*F******************************************************************** * This will 'left justify' text from the cursor **********************************************************************/ void LiquidCrystal_I2C:: noAutoscroll( void ) { _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; command(LCD_ENTRYMODESET | _displaymode); }
/*F******************************************************************** * Allows us to fill the first 8 CGRAM locations with custom characters **********************************************************************/ void LiquidCrystal_I2C:: createChar( uint8_t location, uint8_t charmap[] ) { location &= 0x7; // we only have 8 locations 0-7 command(LCD_SETCGRAMADDR | (location << 3)); for (int i=0; i<8; i++) write(charmap[i]); } /*F******************************************************************** * createChar with PROGMEM input **********************************************************************/ void LiquidCrystal_I2C:: createChar( uint8_t location, const char *charmap ) { location &= 0x7; // we only have 8 locations 0-7 command(LCD_SETCGRAMADDR | (location << 3)); for (int i=0; i<8; i++) { write(pgm_read_byte_near(charmap++)); } }
/*F******************************************************************** * Turn (optional) backlight off/on **********************************************************************/ void LiquidCrystal_I2C:: noBacklight( void ) { _backlightval = LCD_NOBACKLIGHT; expanderWrite( 0 ); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: backlight( void ) { _backlightval = LCD_BACKLIGHT; expanderWrite( 0 ); } /*********** mid level commands, for sending data/cmds */ /*F******************************************************************** * **********************************************************************/ inline void LiquidCrystal_I2C:: command( uint8_t value ) { send(value, 0); } /************ low level data pushing commands **********/
/*F******************************************************************** * write either command or data **********************************************************************/ void LiquidCrystal_I2C:: send( uint8_t value, uint8_t mode ) { uint8_t highnib=value&0xf0; uint8_t lownib=(value<<4)&0xf0; write4bits((highnib)|mode); write4bits((lownib)|mode); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: write4bits( uint8_t value ) { expanderWrite(value); pulseEnable(value); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: expanderWrite( uint8_t _data ) { Wire.beginTransmission(_Addr); printIIC((int)(_data) | _backlightval); Wire.endTransmission(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: pulseEnable( uint8_t _data ) { expanderWrite(_data | En); // En high delayMicroseconds(1); // enable pulse must be >450ns expanderWrite(_data & ~En); // En low delayMicroseconds(50); // commands need > 37us to settle }
/*F******************************************************************** * Alias functions **********************************************************************/ void LiquidCrystal_I2C:: cursor_on() { cursor(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: cursor_off() { noCursor(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: blink_on() { blink(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: blink_off() { noBlink(); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: load_custom_character( uint8_t char_num, uint8_t *rows ) { createChar(char_num, rows); }
/*F******************************************************************** * **********************************************************************/ void LiquidCrystal_I2C:: setBacklight( uint8_t new_val ) { if( new_val ) backlight(); // turn backlight on else noBacklight(); // turn backlight off }
/*F******************************************************************** * This function is not identical to the function used for "real" I2C displays it's here so the user sketch doesn't have to be changed **********************************************************************/ void LiquidCrystal_I2C:: printstr( const char c[] ) { print( c ); } // unsupported API functions #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" void LiquidCrystal_I2C::off(){} void LiquidCrystal_I2C::on(){} void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {} uint8_t LiquidCrystal_I2C::status(){return 0;} uint8_t LiquidCrystal_I2C::keypad (){return 0;} uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;} void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){} void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){} void LiquidCrystal_I2C::setContrast(uint8_t new_val){} #pragma GCC diagnostic pop