extern "C" { #include } #include "twiLCD.h" #ifdef TWI_LCD_DPOT_CTRL #include "../ds1803/ds1803.h" #endif twiLCD::twiLCD() { #if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL) #if defined(TWI_LCD_CTRL) && !defined(TWI_LCD_BL_PWM) backlightStatus = 0; #endif #ifdef TWI_LCD_BL_PWM pinMode(TWI_LCD_BACKLIGHT, HIGH); #endif displayStatus = false; #endif #ifdef WIRE_LIB_SCAN_MOD /*if (!Wire.isStarted())*/ Wire.begin(); #else Wire.begin(); #endif } twiLCD LCD = twiLCD(); void twiLCD::Init() { #ifdef TWI_LCD_CTRL backlightOff(); #ifdef TWI_LCD_DPOT_CTRL setBrightness(0); #endif #endif delay(20); /////////// 4 pin initialization writeCommand(0x03); // function set: 4 pin initialization delay(5); writeCommand(0x03); // function set: 4 pin initialization delay(1); writeCommand(0x03); // function set: 4 pin initialization delay(1); writeCommand(0x02); // function set: 4 pin initialization /////////// end of 4 pin initialization writeCommand(LCD_FUNCTION_SET); // function set: 4-bit interface, 1 display lines, 5x7 font writeCommand(LCD_ENTRY_MODE); writeCommand(LCD_CURSOR); clearScreen(); writeCommand(LCD_CLOSE_INIT); #if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL) #ifdef TWI_LCD_CTRL #if defined(TWI_LCD_BL_PWM) || defined(TWI_LCD_DPOT_CTRL) #ifdef TWI_LCD_DPOT_CTRL setBrightness(); #endif backlightOn(TWI_LCD_BL_LEVEL); #else backlightOn(); #endif #endif displayStatus = true; #endif } boolean twiLCD::checkLCDBusy(void) { Wire.requestFrom(PCF8574_RADDR, 1); while (!Wire.available()); return (Wire.receive() & TWI_LCD_BUSY ? true : false); } void twiLCD::writeCommand(uint8_t value) { int value1 = 0; int control = 0; // stores RS and RW #ifdef TWI_LCD_USE_TIMEOUT previousMillis = millis(); #endif control = value >> 8; // get the control signals RS and RW control >>= 5; // shift the control signals to the left Wire.beginTransmission(PCF8574_WADDR); value1 = value; cbi(value1, TWI_LCD_DATAL); // Turn off LByte cbi(value1, TWI_LCD_RS); cbi(value1, TWI_LCD_RW); sendPulse(value1); delay(1); cbi(value, TWI_LCD_DATAH); // Turn off HByte value <<= 4; cbi(value, TWI_LCD_RS); cbi(value, TWI_LCD_RW); sendPulse(value); Wire.endTransmission(); delay(1); } void twiLCD::writeData(uint8_t value) { int value1 = 0; int control = 0; // stores RS and RW // Wait for the LCD to be ready #ifdef TWI_LCD_USE_TIMEOUT previousMillis = millis(); #endif control = value >> 8; // get the control signals RS and RW control >>= 5; // shift the control signals to the left value1 = value; cbi(value1, TWI_LCD_DATAL); // Turn off LByte sbi(value1, TWI_LCD_RS); cbi(value1, TWI_LCD_RW); while (checkLCDBusy()); Wire.beginTransmission(PCF8574_WADDR); sendPulse(value1); delay(1); cbi(value, TWI_LCD_DATAH); // Turn off HByte value <<= 4; sbi(value, TWI_LCD_RS); cbi(value, TWI_LCD_RW); sendPulse(value); Wire.endTransmission(); } void twiLCD::sendPulse(int value) { cbi(value, TWI_LCD_ENABLE); writeToPCF(value); sbi(value, TWI_LCD_ENABLE); writeToPCF(value); cbi(value, TWI_LCD_ENABLE); writeToPCF(value); } void twiLCD::writeToPCF(int value) { #if defined(TWI_LCD_CTRL) && !defined(TWI_LCD_BL_PWM) if (backlightStatus) sbi(value, TWI_LCD_BACKLIGHT); else cbi(value, TWI_LCD_BACKLIGHT); Wire.send(value); #else Wire.send(value); #endif } void twiLCD::clearScreen(void) { writeCommand(LCD_CLEAR); delay(100); #if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL) currentLine = 1; #endif #ifdef LCD_USE_CLRSCREEN_CALLBACK if (twiLCDcallbackFunc[0]) twiLCDcallbackFunc[0](); #endif } void twiLCD::printString_P(const char *data) { int ch; for (;;) { ch = pgm_read_byte( data++ ); if ( !ch ) return; writeData(ch); } } #if defined(__AVR_ATmega168__) && !defined(TWI_LCD_SMALL) #ifdef TWI_LCD_USE_TIMEOUT boolean twiLCD::checkTimeout(void) { if (displayStatus && millis() - previousMillis > TWI_LCD_TIMEOUT) { turnOff(); return true; } return false; } #endif #ifdef TWI_LCD_CTRL #ifdef TWI_LCD_BL_PWM void twiLCD::backlightOn(void) { digitalWrite(TWI_LCD_BACKLIGHT, HIGH); } void twiLCD::backlightOn(uint8_t value) { analogWrite(TWI_LCD_BACKLIGHT, value); } void twiLCD::backlightOff(void) { digitalWrite(TWI_LCD_BACKLIGHT, LOW); } #else #ifdef TWI_LCD_DPOT_CTRL void twiLCD::backlightOn(void) { DPOT.setWiper2(TWI_LCD_BL_LEVEL); } void twiLCD::backlightOn(uint8_t value) { DPOT.setWiper2(value); } void twiLCD::backlightOff(void) { DPOT.setWiper2(0); } void twiLCD::setBrightness(void) { DPOT.setWiper1(TWI_LCD_DB_LEVEL); } void twiLCD::setBrightness(uint8_t value) { DPOT.setWiper1(value); } #else void twiLCD::backlightOn(void) { int val = 0; backlightStatus = 1; sbi(val, TWI_LCD_BACKLIGHT); Wire.beginTransmission(PCF8574_WADDR); Wire.send(val); Wire.endTransmission(); } void twiLCD::backlightOff(void) { int val = 0; backlightStatus = 0; cbi(val, TWI_LCD_BACKLIGHT); Wire.beginTransmission(PCF8574_WADDR); Wire.send(val); Wire.endTransmission(); } #endif #endif #endif void twiLCD::turnOff(void) { writeCommand(LCD_TURN_OFF); #if defined(TWI_LCD_CTRL) backlightOff(); #ifdef TWI_LCD_DPOT_CTRL setBrightness(0); #endif #endif displayStatus = false; } /** * This function needs a rewrite **/ void twiLCD::setCursor(int index) { //0-79, index for one line display, 8 bit mode //0-39 and 64-103 for lines one and two of two line display, not implemented yet int cmd = 128+index; writeCommand(cmd); } /** * This function needs a rewrite **/ void twiLCD::moveToXY(uint8_t row, uint8_t column) { int position; // Determine the new position position = (row * 20) + column; // Send the correct commands to the command register of the LCD if(position < 20) writeCommand(0x80 | position); else if(position >= 20 && position < 40) writeCommand(0x80 | (position % 20 + 0x40)); else if(position >= 41 && position < 60) writeCommand(0x80 | (position % 40 + 0x14)); else if(position >= 20 && position < 40) writeCommand(0x80 | (position % 60 + 0x54)); } uint8_t twiLCD::getCurrentLine(void) { return currentLine; } void twiLCD::goToLine(uint8_t line) { if (line > LCD_ROWS) return; moveToXY(line - 1, 0); currentLine = line; } void twiLCD::goToNextLine(void) { if (currentLine+1 > LCD_ROWS) { goToLine(1); } else { goToLine(currentLine+1); } } void twiLCD::goHome(void) { writeCommand(LCD_GO_HOME); // set cursor position to zero currentLine = 1; } void twiLCD::clearLine(void) { int ii; moveToXY(currentLine-1, 0); for (ii=0;ii 0) writeData(thousands + 0x30); uint8_t hundreds = (integer - thousands*1000) / 100; if (hundreds > 0 || thousands > 0) writeData(hundreds + 0x30); uint8_t tens = (integer - thousands*1000 - hundreds*100 ) / 10; if (tens || hundreds > 0 || thousands > 0) writeData(tens + 0x30); uint8_t ones = (integer - thousands*1000 - hundreds*100 - tens*10); writeData(ones + 0x30); } #endif #ifdef LCD_USE_CLRSCREEN_CALLBACK void twiLCD::clrsSetCallback(void (*userFunc)(void)) { twiLCDcallbackFunc[0] = userFunc; } #endif