diff options
Diffstat (limited to 'libraries')
| -rwxr-xr-x | libraries/LiquidCrystal/LiquidCrystal.cpp | 297 | ||||
| -rwxr-xr-x | libraries/LiquidCrystal/LiquidCrystal.h | 95 | 
2 files changed, 324 insertions, 68 deletions
| diff --git a/libraries/LiquidCrystal/LiquidCrystal.cpp b/libraries/LiquidCrystal/LiquidCrystal.cpp index b5f2cd4..4e46318 100755 --- a/libraries/LiquidCrystal/LiquidCrystal.cpp +++ b/libraries/LiquidCrystal/LiquidCrystal.cpp @@ -25,10 +25,39 @@  // LiquidCrystal constructor is called).  LiquidCrystal::LiquidCrystal(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) : -  _four_bit_mode(0), _rs_pin(rs), _rw_pin(rw), _enable_pin(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)  { +  init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, 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) +{ +  init(0, rs, -1, enable, d0, d1, d2, d3, d4, d5, d6, d7); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, +			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ +  init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +LiquidCrystal::LiquidCrystal(uint8_t rs,  uint8_t enable, +			     uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) +{ +  init(1, rs, -1, enable, d0, d1, d2, d3, 0, 0, 0, 0); +} + +void LiquidCrystal::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) +{ +  _rs_pin = rs; +  _rw_pin = rw; +  _enable_pin = enable; +      _data_pins[0] = d0;    _data_pins[1] = d1;    _data_pins[2] = d2; @@ -37,92 +66,244 @@ LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,    _data_pins[5] = d5;    _data_pins[6] = d6;    _data_pins[7] = d7;  -   +    pinMode(_rs_pin, OUTPUT); -  pinMode(_rw_pin, OUTPUT); +  // we can save 1 pin by not using RW. Indicate by passing -1 instead of pin# +  if (_rw_pin != -1) {  +    pinMode(_rw_pin, OUTPUT); +  }    pinMode(_enable_pin, OUTPUT); -  for (int i = 0; i < 8; i++) -    pinMode(_data_pins[i], OUTPUT); -  -  command(0x38);  // function set: 8 bits, 1 line, 5x8 dots -  command(0x0C);  // display control: turn display on, cursor off, no blinking -  command(0x06);  // entry mode set: increment automatically, display shift, right shift -  clear(); +  if (fourbitmode) +    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; +  else  +    _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; +   +  begin(16, 1);    } -LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, -  uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) : -  _four_bit_mode(1), _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;  -   -  pinMode(_rs_pin, OUTPUT); -  pinMode(_rw_pin, OUTPUT); -  pinMode(_enable_pin, OUTPUT); +void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { +  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 +  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 != -1) {  +    digitalWrite(_rw_pin, LOW); +  } -  for (int i = 0; i < 4; i++) -    pinMode(_data_pins[i], OUTPUT); -  -  command(0x28);  // function set: 4 bits, 1 line, 5x8 dots -  command(0x0C);  // display control: turn display on, cursor off, no blinking -  command(0x06);  // entry mode set: increment automatically, display shift, right shift +  //put the LCD into 4 bit or 8 bit mode +  if (! (_displayfunction & LCD_8BITMODE)) { +    // 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 8-bit interface +    write4bits(0x02);  +  } else { +    // this is according to the hitachi HD44780 datasheet +    // page 45 figure 23 + +    // Send function set command sequence +    command(LCD_FUNCTIONSET | _displayfunction); +    delayMicroseconds(4500);  // wait more than 4.1ms + +    // second try +    command(LCD_FUNCTIONSET | _displayfunction); +    delayMicroseconds(150); + +    // third go +    command(LCD_FUNCTIONSET | _displayfunction); +  } + +  // finally, 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 romance languages) +  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; +  // set the entry mode +  command(LCD_ENTRYMODESET | _displaymode); +  } +/********** high level commands, for the user! */  void LiquidCrystal::clear()  { -  command(0x01);  // clear display, set cursor position to zero -  delayMicroseconds(2000); +  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero +  delayMicroseconds(2000);  // this command takes a long time!  }  void LiquidCrystal::home()  { -  command(0x02);  // set cursor position to zero -  delayMicroseconds(2000); +  command(LCD_RETURNHOME);  // set cursor position to zero +  delayMicroseconds(2000);  // this command takes a long time!  } -void LiquidCrystal::setCursor(int col, int row) +void LiquidCrystal::setCursor(uint8_t col, uint8_t row)  {    int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; -  command(0x80 | (col + row_offsets[row])); +  if ( row > _numlines ) { +    row = _numlines-1;    // we count rows starting w/0 +  } +   +  command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal::noDisplay() { +  _displaycontrol &= ~LCD_DISPLAYON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::display() { +  _displaycontrol |= LCD_DISPLAYON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal::noCursor() { +  _displaycontrol &= ~LCD_CURSORON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::cursor() { +  _displaycontrol |= LCD_CURSORON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal::noBlink() { +  _displaycontrol &= ~LCD_BLINKON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal::blink() { +  _displaycontrol |= LCD_BLINKON; +  command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal::scrollDisplayLeft(void) { +  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal::scrollDisplayRight(void) { +  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal::shiftLeft(void) { +  _displaymode |= LCD_ENTRYLEFT; +  command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal::shiftRight(void) { +  _displaymode &= ~LCD_ENTRYLEFT; +  command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal::shiftIncrement(void) { +  _displaymode |= LCD_ENTRYSHIFTINCREMENT; +  command(LCD_ENTRYMODESET | _displaymode);  } -void LiquidCrystal::command(uint8_t value) { +// This will 'left justify' text from the cursor +void LiquidCrystal::shiftDecrement(void) { +  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; +  command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) { +  location &= 0x7; // we only have 8 locations 0-7 +  command(LCD_SETCGRAMADDR | (location << 3)); +  for (int i=0; i<8; i++) { +    write(charmap[i]); +  } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal::command(uint8_t value) {    send(value, LOW);  } -void LiquidCrystal::write(uint8_t value) { +inline void LiquidCrystal::write(uint8_t value) {    send(value, HIGH);  } +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection  void LiquidCrystal::send(uint8_t value, uint8_t mode) {    digitalWrite(_rs_pin, mode); -  digitalWrite(_rw_pin, LOW); - -  if (_four_bit_mode) { -    for (int i = 0; i < 4; i++) { -      digitalWrite(_data_pins[i], (value >> (i + 4)) & 0x01); -    } -     -    digitalWrite(_enable_pin, HIGH); -    digitalWrite(_enable_pin, LOW); -     -    for (int i = 0; i < 4; i++) { -      digitalWrite(_data_pins[i], (value >> i) & 0x01); -    } -    digitalWrite(_enable_pin, HIGH); -    digitalWrite(_enable_pin, LOW); +  // if there is a RW pin indicated, set it low to Write +  if (_rw_pin != -1) {  +    digitalWrite(_rw_pin, LOW); +  } +   +  if (_displayfunction & LCD_8BITMODE) { +    write8bits(value);     } else { -    for (int i = 0; i < 8; i++) { -      digitalWrite(_data_pins[i], (value >> i) & 0x01); -    } +    write4bits(value>>4); +    write4bits(value); +  } +} + +void LiquidCrystal::pulseEnable(void) { +  digitalWrite(_enable_pin, LOW); +  delayMicroseconds(1);     +  digitalWrite(_enable_pin, HIGH); +  delayMicroseconds(1);    // enable pulse must be >450ns +  digitalWrite(_enable_pin, LOW); +  delayMicroseconds(100);   // commands need > 37us to settle +} -    digitalWrite(_enable_pin, HIGH); -    digitalWrite(_enable_pin, LOW); +void LiquidCrystal::write4bits(uint8_t value) { +  for (int i = 0; i < 4; i++) { +    pinMode(_data_pins[i], OUTPUT); +    digitalWrite(_data_pins[i], (value >> i) & 0x01);    } + +  pulseEnable(); +} + +void LiquidCrystal::write8bits(uint8_t value) { +  for (int i = 0; i < 8; i++) { +    pinMode(_data_pins[i], OUTPUT); +    digitalWrite(_data_pins[i], (value >> i) & 0x01); +  } +   +  pulseEnable();  } diff --git a/libraries/LiquidCrystal/LiquidCrystal.h b/libraries/LiquidCrystal/LiquidCrystal.h index a5edc5f..5a8d087 100755 --- a/libraries/LiquidCrystal/LiquidCrystal.h +++ b/libraries/LiquidCrystal/LiquidCrystal.h @@ -4,28 +4,103 @@  #include <inttypes.h>  #include "Print.h" +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 +  class LiquidCrystal : public Print {  public: -  LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t); -  LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, -    uint8_t, uint8_t, uint8_t, uint8_t); +  LiquidCrystal(uint8_t rs, 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); +  LiquidCrystal(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); +  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, +		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); +  LiquidCrystal(uint8_t rs, uint8_t enable, +		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); + +  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();    void home(); -  void setCursor(int, int);  -  /* -  void shiftDisplayLeft(); -  void shiftDisplayRight(); -  */ + +  void noDisplay(); +  void display(); +  void noBlink(); +  void blink(); +  void noCursor(); +  void cursor(); +  void scrollDisplayLeft(); +  void scrollDisplayRight(); +  void printLeft(); +  void printRight(); +  void shiftLeft(); +  void shiftRight(); +  void shiftIncrement(); +  void shiftDecrement(); + +  void createChar(uint8_t, uint8_t[]); +  void setCursor(uint8_t, uint8_t);     virtual void write(uint8_t);    void command(uint8_t);  private:    void send(uint8_t, uint8_t); -   -  uint8_t _four_bit_mode; +  void write4bits(uint8_t); +  void write8bits(uint8_t); +  void pulseEnable(); +    uint8_t _rs_pin; // LOW: command.  HIGH: character.    uint8_t _rw_pin; // LOW: write to LCD.  HIGH: read from LCD.    uint8_t _enable_pin; // activated by a HIGH pulse.    uint8_t _data_pins[8]; + +  uint8_t _displayfunction; +  uint8_t _displaycontrol; +  uint8_t _displaymode; + +  uint8_t _initialized; + +  uint8_t _numlines,_currline;  };  #endif | 
