Esempio n. 1
0
// write either command or data, burst it to the expander over I2C.
void LiquidTWI::send(uint8_t value, uint8_t mode) {
	// BURST SPEED, OH MY GOD
	// the (now High Speed!) I/O expander pinout
	// RS pin = 1
	// Enable pin = 2
	// Data pin 4 = 3
	// Data pin 5 = 4
	// Data pin 6 = 5
	// Data pin 7 = 6
	byte buf;
	// crunch the high 4 bits
	buf = (value & B11110000) >> 1; // isolate high 4 bits, shift over to data pins (bits 6-3: x1111xxx)
	if (mode) buf |= 3 << 1; // here we can just enable enable, since the value is immediately written to the pins
	else buf |= 2 << 1; // if RS (mode), turn RS and enable on. otherwise, just enable. (bits 2-1: xxxxx11x)
	buf |= _displaycontrol & LCD_BACKLIGHT; // LCD_BACKLIGHT = 0x80 backlight bit (1xxxxxxx) = convenient!
	burstBits(buf); // bits are now present at LCD with enable active in the same write
	// no need to delay since these things take WAY, WAY longer than the time required for enable to settle (1us in LCD implementation?)
	buf &= ~(1<<2); // toggle enable low
	burstBits(buf); // send out the same bits but with enable low now; LCD crunches these 4 bits.
	// crunch the low 4 bits
	buf = (value & B1111) << 3; // isolate low 4 bits, shift over to data pins (bits 6-3: x1111xxx)
	if (mode) buf |= 3 << 1; // here we can just enable enable, since the value is immediately written to the pins
	else buf |= 2 << 1; // if RS (mode), turn RS and enable on. otherwise, just enable. (bits 2-1: xxxxx11x)
	buf |= _displaycontrol & LCD_BACKLIGHT; // LCD_BACKLIGHT = 0x80 = LCD_DISPLAYCOMMAND = backlight bit (1xxxxxxx) = convenient!
	burstBits(buf);
	buf &= ~( 1 << 2 ); // toggle enable low (1<<2 = 00000100; NOT = 11111011; with "and", this turns off only that one bit)
	burstBits(buf);
}
Esempio n. 2
0
void LiquidTWI::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
	Wire.begin();
	// first thing we do is get the GPIO expander's head working straight, with a boatload of junk data.
	Wire.beginTransmission(MCP23008_ADDRESS | _i2cAddr);
	Wire.send(MCP23008_IODIR);
	Wire.send(0xFF);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);	
	Wire.endTransmission();

	// now we set the GPIO expander's I/O direction to output since it's soldered to an LCD output.
	Wire.beginTransmission(MCP23008_ADDRESS | _i2cAddr);
	Wire.send(MCP23008_IODIR);
	Wire.send(0x00); // all output: 00000000 for pins 1...8
	Wire.endTransmission();

	if (lines > 1) {
		_displayfunction |= LCD_2LINE;
	}
	_numlines = lines;
	_currline = 0;

	// 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 befer 4.5V so we'll wait 50
	delay(50);

	//put the LCD into 4 bit mode
	// start with a non-standard command to make it realize we're speaking 4-bit here
	// per LCD datasheet, first command is a single 4-bit burst, 0011.
	burstBits(B10010100); // buffer that out to I/O pins: 1001110x with enable and backlight on
	burstBits(B10010000); // buffer that out to I/O pins: 1001100x with enable low, backlight on
	delay(5); // this shouldn't be necessary, but sometimes 16MHz is stupid-fast.
	
	command(LCD_FUNCTIONSET | _displayfunction); // then send 0010NF00 (N=lines, F=font)
	delay(5); // for safe keeping...
	command(LCD_FUNCTIONSET | _displayfunction); // ... twice.
	delay(5); // done!

	// turn on the LCD with our defaults. since these libs seem to use personal preference, I like a cursor.
	_displaycontrol = LCD_DISPLAYON;  
	display();
	// clear it off
	clear();

	_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
	// set the entry mode
	command(LCD_ENTRYMODESET | _displaymode);

	setBacklight(HIGH); // turn the backlight on if so equipped.
}
Esempio n. 3
0
// Allows to set the backlight, if the LCD backpack is used
void LiquidTWI::setBacklight(uint8_t status) {
	bitWrite(_displaycontrol,7,status); // flag that the backlight is enabled, for burst commands
	burstBits(_displaycontrol & LCD_BACKLIGHT);
}
void LiquidTWI::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
	// 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 befer 4.5V so we'll wait 50
	delay(50);

	Wire.begin();
	// first thing we do is get the GPIO expander's head working straight, with a boatload of junk data.
	Wire.beginTransmission(MCP23008_ADDRESS | _i2cAddr);
#if ARDUINO >= 100
	Wire.write((byte)MCP23008_IODIR);
	Wire.write((byte)0xFF);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
	Wire.write((byte)0x00);
#else
	Wire.send(MCP23008_IODIR);
	Wire.send(0xFF);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
	Wire.send(0x00);
#endif
	Wire.endTransmission();

	// now we set the GPIO expander's I/O direction to output since it's soldered to an LCD output.
	Wire.beginTransmission(MCP23008_ADDRESS | _i2cAddr);
#if ARDUINO >= 100
	Wire.write((byte)MCP23008_IODIR);
	Wire.write((byte)0x00); // all output: 00000000 for pins 1...8
#else
	Wire.send(MCP23008_IODIR);
	Wire.send(0x00); // all output: 00000000 for pins 1...8
#endif
	Wire.endTransmission();

	if (lines > 1) {
		_displayfunction |= LCD_2LINE;
	}
	_numlines = lines;
	_currline = 0;

	// for some 1 line displays you can select a 10 pixel high font
	if ((dotsize != 0) && (lines == 1)) {
		_displayfunction |= LCD_5x10DOTS;
	}

	//put the LCD into 4 bit mode
	// start with a non-standard command to make it realize we're speaking 4-bit here
	// per LCD datasheet, first command is a single 4-bit burst, 0011.
        //-----
        //  we cannot assume that the LCD panel is powered at the same time as
        //  the arduino, so we have to perform a software reset as per page 45
        //  of the HD44780 datasheet - (kch)
        //-----
        // bit pattern for the burstBits function is
        //
        //  7   6   5   4   3   2   1   0
        // LT  D7  D6  D5  D4  EN  RS  n/c
        //-----
        burstBits(B10011100); // send LITE D4 D5 high with enable
        burstBits(B10011000); // send LITE D4 D5 high with !enable
        burstBits(B10011100); //
        burstBits(B10011000); //
        burstBits(B10011100); // repeat twice more
        burstBits(B10011000); //
        burstBits(B10010100); // send D4 low and LITE D5 high with enable
        burstBits(B10010000); // send D4 low and LITE D5 high with !enable
	delay(5); // this shouldn't be necessary, but sometimes 16MHz is stupid-fast.
	
	command(LCD_FUNCTIONSET | _displayfunction); // then send 0010NF00 (N=lines, F=font)
	delay(5); // for safe keeping...
	command(LCD_FUNCTIONSET | _displayfunction); // ... twice.
	delay(5); // done!

	// turn on the LCD with our defaults. since these libs seem to use personal preference, I like a cursor.
	_displaycontrol = LCD_DISPLAYON;  
	display();
	// clear it off
	clear();

	_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
	// set the entry mode
	command(LCD_ENTRYMODESET | _displaymode);

	setBacklight(HIGH); // turn the backlight on if so equipped.
}