arduinoprojects

git clone https://git.tarina.org/arduinoprojects
Log | Files | Refs

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