diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp index 0653487d70c..b76944e0393 100644 --- a/libraries/LiquidCrystal/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/LiquidCrystal.cpp @@ -8,17 +8,17 @@ // 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 +// 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 @@ -57,29 +57,29 @@ void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t en _rs_pin = rs; _rw_pin = rw; _enable_pin = enable; - + _data_pins[0] = d0; _data_pins[1] = d1; _data_pins[2] = d2; - _data_pins[3] = d3; + _data_pins[3] = d3; _data_pins[4] = d4; _data_pins[5] = d5; _data_pins[6] = d6; - _data_pins[7] = d7; + _data_pins[7] = d7; pinMode(_rs_pin, OUTPUT); // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin# - if (_rw_pin != 255) { + if (_rw_pin != 255) { pinMode(_rw_pin, OUTPUT); } pinMode(_enable_pin, OUTPUT); - + if (fourbitmode) _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; - else + else _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; - - begin(16, 1); + + begin(16, 1); } void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { @@ -97,14 +97,14 @@ void LiquidCrystal::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 - delayMicroseconds(50000); + delayMicroseconds(50000); // Now we pull both RS and R/W low to begin commands digitalWrite(_rs_pin, LOW); digitalWrite(_enable_pin, LOW); - if (_rw_pin != 255) { + if (_rw_pin != 255) { digitalWrite(_rw_pin, LOW); } - + //put the LCD into 4 bit or 8 bit mode if (! (_displayfunction & LCD_8BITMODE)) { // this is according to the hitachi HD44780 datasheet @@ -117,13 +117,13 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { // second try write4bits(0x03); delayMicroseconds(4500); // wait min 4.1ms - + // third go! - write4bits(0x03); + write4bits(0x03); delayMicroseconds(150); // finally, set to 4-bit interface - write4bits(0x02); + write4bits(0x02); } else { // this is according to the hitachi HD44780 datasheet // page 45 figure 23 @@ -141,10 +141,10 @@ void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { } // finally, set # lines, font size, etc. - command(LCD_FUNCTIONSET | _displayfunction); + command(LCD_FUNCTIONSET | _displayfunction); // turn the display on with no cursor or blinking default - _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; display(); // clear it off @@ -176,7 +176,7 @@ void LiquidCrystal::setCursor(uint8_t col, uint8_t row) if ( row >= _numlines ) { row = _numlines-1; // we count rows starting w/0 } - + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); } @@ -252,6 +252,126 @@ void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { } } +// Get the current cursor position and put the information in the passed values +void LiquidCrystal::getCursorPos(int &col, int &row) { + uint8_t value = readBusyFlagAndAddress(); + value &= 0x7f; //get rid of the busy flag if it is set + + row=0; + if(_numlines > 1) + { + //if there are 2 rows + if(value >= 64 )//it means it is on line 2 + { + value-=64; + row=1; + } + } + col = value; +} + +// Retrieves a number of characters starting from the specified position +// and puts them into the buffer, the buffer is NOT null terminated. +// Returns 0 if it could not read or returns the length if it was successful. +// Much faster with more characters than calling getCharAt for each character. +uint8_t LiquidCrystal::getChars(uint8_t col, uint8_t row, char* buffer, uint8_t length) +{ + + if (_rw_pin == 255) + {//if there is no rw pin just return 0 + return 0; + } + + //save the last position to return to it when the function is finished + int prev_col, prev_row; + getCursorPos(prev_col, prev_row); + + setCursor(col, row); + + for(int i=0; i>4); write4bits(value); } } +// reads busy flag and address if rs_pin_mode is LOW or reads characters if rs_pin_mode is HIGH, +// it is analogous to the send function +uint8_t LiquidCrystal::receive(int rs_pin_mode){ + digitalWrite(_rs_pin, rs_pin_mode); + digitalWrite(_rw_pin, HIGH); //it is up to the higher function to check if there is a rw pin, + // this is done to avoid using a code for error returning + + delayMicroseconds(1); // tAS time + + uint8_t value; + if (_displayfunction & LCD_8BITMODE) //is it 4/8 bit mode? + { + value = read8bits(); + } + else + { + value = read4bits(); + value = value << 4; + value |= read4bits(); + } + + return value; +} + void LiquidCrystal::pulseEnable(void) { digitalWrite(_enable_pin, LOW); - delayMicroseconds(1); + delayMicroseconds(1); digitalWrite(_enable_pin, HIGH); delayMicroseconds(1); // enable pulse must be >450ns digitalWrite(_enable_pin, LOW); @@ -305,6 +463,54 @@ void LiquidCrystal::write8bits(uint8_t value) { pinMode(_data_pins[i], OUTPUT); digitalWrite(_data_pins[i], (value >> i) & 0x01); } - + pulseEnable(); } + +// Reads data from the LCD in 4Bit Mode +uint8_t LiquidCrystal::read4bits() +{ + + digitalWrite(_enable_pin, HIGH); + delayMicroseconds(1); // tDDR time + + uint8_t value =0; + for(int i=3; i>=0; i--) + { + value= value<< 1; + + pinMode(_data_pins[i], INPUT); + if(digitalRead(_data_pins[i]) == HIGH) + { + value+=1; + } + + } + digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); //tDHR time + + return value; +} + +// Reads data from the LCD in 8Bit Mode +uint8_t LiquidCrystal::read8bits() +{ + digitalWrite(_enable_pin, HIGH); + delayMicroseconds(1); // tDDR time + uint8_t value =0; + for(int i=7; i>=0; i--) + { + value= value<< 1; + + pinMode(_data_pins[i], INPUT); + if(digitalRead(_data_pins[i]) == HIGH) + { + value+=1; + } + + } + digitalWrite(_enable_pin, LOW); + delayMicroseconds(1); //tDHR time + return value; +} + diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h index 24ec5afdf5b..a9e40a8941e 100755 --- a/libraries/LiquidCrystal/LiquidCrystal.h +++ b/libraries/LiquidCrystal/LiquidCrystal.h @@ -58,7 +58,7 @@ class LiquidCrystal : public Print { void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); - + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); void clear(); @@ -78,15 +78,25 @@ class LiquidCrystal : public Print { void noAutoscroll(); void createChar(uint8_t, uint8_t[]); - void setCursor(uint8_t, uint8_t); + void setCursor(uint8_t, uint8_t); virtual size_t write(uint8_t); void command(uint8_t); - + void getCursorPos(int &col, int &row); + char getCharAt(uint8_t col, uint8_t row); + char getCharAt(uint8_t col, uint8_t row, uint8_t ret); + uint8_t getChars(uint8_t col, uint8_t row, char* buffer, uint8_t length); + void deleteLast(); + void deleteAt(uint8_t col, uint8_t row); + using Print::write; private: + uint8_t readBusyFlagAndAddress(); void send(uint8_t, uint8_t); + uint8_t receive(int rs_pin_mode); void write4bits(uint8_t); void write8bits(uint8_t); + uint8_t read4bits(); + uint8_t read8bits(); void pulseEnable(); uint8_t _rs_pin; // LOW: command. HIGH: character. diff --git a/libraries/LiquidCrystal/keywords.txt b/libraries/LiquidCrystal/keywords.txt index 132845cb651..aeb3eccfb7d 100755 --- a/libraries/LiquidCrystal/keywords.txt +++ b/libraries/LiquidCrystal/keywords.txt @@ -30,6 +30,11 @@ rightToLeft KEYWORD2 scrollDisplayLeft KEYWORD2 scrollDisplayRight KEYWORD2 createChar KEYWORD2 +getCursorPos KEYWORD2 +getCharAt KEYWORD2 +getChars KEYWORD2 +deleteLast KEYWORD2 +deleteAt KEYWORD2 ####################################### # Constants (LITERAL1)