Source

New LiquidCrystal / LiquidCrystal_I2C.cpp

The default branch has multiple heads

// ---------------------------------------------------------------------------
// Created by Francisco Malpartida on 20/08/11.
// Copyright 2011 - Under creative commons license 3.0:
//        Attribution-ShareAlike CC BY-SA
//
// This software is furnished "as is", without technical support, and with no 
// warranty, express or implied, as to its usefulness for any purpose.
//
// Thread Safe: No
// Extendable: Yes
//
// @file LiquidCrystal_I2C.c
// This file implements a basic liquid crystal library that comes as standard
// in the Arduino SDK but using an I2C IO extension board.
// 
// @brief 
// This is a basic implementation of the LiquidCrystal library of the
// Arduino SDK. The original library has been reworked in such a way that 
// this class implements the all methods to command an LCD based
// on the Hitachi HD44780 and compatible chipsets using I2C extension
// backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC.
//
// The functionality provided by this class and its base class is identical
// to the original functionality of the Arduino LiquidCrystal library.
//
//
// This library is only compatible with Arduino's SDK version 1.0
//
//
// @author F. Malpartida - fmalpartida@gmail.com
// ---------------------------------------------------------------------------
#if (ARDUINO <  100)
#include <WProgram.h>
#else
#include <Arduino.h>
#endif
#include <inttypes.h>
#include <I2CIO.h>
#include <LiquidCrystal_I2C.h>



// When the 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 the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal_I2C constructor is called).
// A call to begin() will reinitialize the LCD.

// CONSTRUCTORS
// ---------------------------------------------------------------------------
LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr )
{
   _Addr = lcd_Addr;
   
   _backlightval = LCD_NOBACKLIGHT;
}


// PRIVATE METHODS
// ---------------------------------------------------------------------------

//
// init
int LiquidCrystal_I2C::init()
{
   int status = 0;
   
   // initialize the backpack IO expander
   // and display functions.
   // ------------------------------------------------------------------------
	if ( _i2cio.begin ( _Addr ) == 1 )
   {
      _i2cio.portMode ( OUTPUT );  // Set the entire IO extender to OUTPUT
      _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
      status = 1;
   }
   return ( status );
}


// PUBLIC METHODS
// ---------------------------------------------------------------------------

//
// begin
void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) 
{
   _cols = cols;
   _rows = lines;
   
   init();     // Initialise the I2C expander interface
   
	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, we need at least 40ms after power rises above 2.7V
	// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
	delayMicroseconds(50000); 
   
	// Now we pull both RS and R/W low to begin commands
	expanderWrite(_backlightval);	// reset expander and turn backlight off (Bit 8 =1)
	delay(1000);
   
  	//put the LCD into 4 bit mode
	// this is according to the hitachi HD44780 datasheet
	// figure 24, pg 46
	
	// we start in 8bit mode, try to set 4 bit mode
	write4bits(0x03);
	delayMicroseconds(4500); // wait min 4.1ms
	
	// second try
	write4bits(0x03);
	delayMicroseconds(4500); // wait min 4.1ms
	
	// third go!
	write4bits(0x03); 
	delayMicroseconds(150);
	
	// finally, set to 4-bit interface
	write4bits(0x02); 
   
   
	// set # lines, font size, etc.
	command(LCD_FUNCTIONSET | _displayfunction);  
	
	// turn the display on with no cursor or blinking default
	_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
	display();
	
	// clear it off
	clear();
	
	// Initialize to default text direction (for roman languages)
	_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
	
	// set the entry mode
	command(LCD_ENTRYMODESET | _displaymode);
	
	home();
   
}


// User commands - users can expand this section
//----------------------------------------------------------------------------

// Turn the (optional) backlight off/on
void LiquidCrystal_I2C::noBacklight(void) 
{
	_backlightval=LCD_NOBACKLIGHT;
	expanderWrite(0);
}

void LiquidCrystal_I2C::backlight(void) 
{
	_backlightval=LCD_BACKLIGHT;
	expanderWrite(0);
}

// PRIVATE METHODS
// ---------------------------------------------------------------------------

// low level data pushing commands
//----------------------------------------------------------------------------

//
// send - write either command or data
void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) 
{
   // Is it a command or data
   // -----------------------
   if ( mode == HIGH )
   {
      mode = Rs;
   }
   
	uint8_t highnib=value>>4;
	uint8_t lownib=value & 0x0F;
   
	write4bits((highnib)|mode);
	write4bits((lownib)|mode);
}

//
// write4bits
void LiquidCrystal_I2C::write4bits(uint8_t value) 
{
	expanderWrite(value);
	pulseEnable(value);
}

//
// write4bits
void LiquidCrystal_I2C::pulseEnable (uint8_t _data)
{
   // No need to use the delay routines since the time taken to write takes
   // longer that what is needed.
	expanderWrite (_data | En);	// En HIGH
	//delayMicroseconds(1);		   // enable pulse must be >450ns
   
	expanderWrite(_data & ~En);   // En low
	//delayMicroseconds(50);		// commands need > 37us to settle
} 

//
// expanderWrite
void LiquidCrystal_I2C::expanderWrite(uint8_t _data)
{                                        
   _i2cio.write ( _data );
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.