AGirs
LiquidCrystal_I2C_bm.cpp
Go to the documentation of this file.
1 #include "LiquidCrystal_I2C_bm.h"
2 
3 #include "Wire.h"
4 
5 // commands (previously in the header)
6 #define LCD_CLEARDISPLAY 0x01
7 #define LCD_RETURNHOME 0x02
8 #define LCD_ENTRYMODESET 0x04
9 #define LCD_DISPLAYCONTROL 0x08
10 #define LCD_CURSORSHIFT 0x10
11 #define LCD_FUNCTIONSET 0x20
12 #define LCD_SETCGRAMADDR 0x40
13 #define LCD_SETDDRAMADDR 0x80
14 
15 // flags for display entry mode
16 #define LCD_ENTRYRIGHT 0x00
17 #define LCD_ENTRYLEFT 0x02
18 #define LCD_ENTRYSHIFTINCREMENT 0x01
19 #define LCD_ENTRYSHIFTDECREMENT 0x00
20 
21 // flags for display on/off control
22 #define LCD_DISPLAYON 0x04
23 #define LCD_DISPLAYOFF 0x00
24 #define LCD_CURSORON 0x02
25 #define LCD_CURSOROFF 0x00
26 #define LCD_BLINKON 0x01
27 #define LCD_BLINKOFF 0x00
28 
29 // flags for display/cursor shift
30 #define LCD_DISPLAYMOVE 0x08
31 #define LCD_CURSORMOVE 0x00
32 #define LCD_MOVERIGHT 0x04
33 #define LCD_MOVELEFT 0x00
34 
35 // flags for function set
36 #define LCD_8BITMODE 0x10
37 #define LCD_4BITMODE 0x00
38 #define LCD_2LINE 0x08
39 #define LCD_1LINE 0x00
40 
41 // flags for backlight control
42 #define LCD_BACKLIGHT 0x08
43 #define LCD_NOBACKLIGHT 0x00
44 
45 #define En B00000100 // Enable bit
46 #define Rw B00000010 // Read/Write bit
47 #define Rs B00000001 // Register select bit
48 
49 size_t LiquidCrystal_I2C::write(uint8_t value) {
50  send(value, Rs);
51  return 1;
52 }
53 
79 LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t i2c_Addr, uint8_t lcd_cols, uint8_t lcd_rows) {
80  _Addr = i2c_Addr;
81  _cols = lcd_cols;
82  _rows = lcd_rows;
83  _backlightval = LCD_NOBACKLIGHT;
84 }
85 
87  init_priv();
88 }
89 
90 void LiquidCrystal_I2C::init_priv() {
91  Wire.begin();
92  _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
93  begin(_cols, _rows);
94 }
95 
96 void LiquidCrystal_I2C::begin(uint8_t cols __attribute__ ((unused)), uint8_t lines, uint8_t dotsize) {
97  if (lines > 1) {
98  _displayfunction |= LCD_2LINE;
99  }
100  _numlines = lines;
101 
102  // for some 1 line displays you can select a 10 pixel high font
103  if ((dotsize != 0) && (lines == 1)) {
104  _displayfunction |= LCD_5x10DOTS;
105  }
106 
107  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
108  // according to datasheet, we need at least 40ms after power rises above 2.7V
109  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
110  delay(50);
111 
112  // Now we pull both RS and R/W low to begin commands
113  expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1)
114  delay(1000);
115 
116  //put the LCD into 4 bit mode
117  // this is according to the hitachi HD44780 datasheet
118  // figure 24, pg 46
119 
120  // we start in 8bit mode, try to set 4 bit mode
121  write4bits(0x03 << 4);
122  delayMicroseconds(4500); // wait min 4.1ms
123 
124  // second try
125  write4bits(0x03 << 4);
126  delayMicroseconds(4500); // wait min 4.1ms
127 
128  // third go!
129  write4bits(0x03 << 4);
130  delayMicroseconds(150);
131 
132  // finally, set to 4-bit interface
133  write4bits(0x02 << 4);
134 
135  // set # lines, font size, etc.
136  command(LCD_FUNCTIONSET | _displayfunction);
137 
138  // turn the display on with no cursor or blinking default
139  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
140  display();
141 
142  // clear it off
143  clear();
144 
145  // Initialize to default text direction (for roman languages)
146  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
147 
148  // set the entry mode
149  command(LCD_ENTRYMODESET | _displaymode);
150 
151  home();
152 }
153 
154 /********** high level commands, for the user! */
156  command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
157  delayMicroseconds(2000); // this command takes a long time!
158 }
159 
161  command(LCD_RETURNHOME); // set cursor position to zero
162  delayMicroseconds(2000); // this command takes a long time!
163 }
164 
165 void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row) {
166  int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
167  if (row > _numlines) {
168  row = _numlines - 1; // we count rows starting w/0
169  }
170  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
171 }
172 
177  _displaycontrol &= ~LCD_DISPLAYON;
178  command(LCD_DISPLAYCONTROL | _displaycontrol);
179 }
180 
182  _displaycontrol |= LCD_DISPLAYON;
183  command(LCD_DISPLAYCONTROL | _displaycontrol);
184 }
185 
190  _displaycontrol &= ~LCD_CURSORON;
191  command(LCD_DISPLAYCONTROL | _displaycontrol);
192 }
193 
195  _displaycontrol |= LCD_CURSORON;
196  command(LCD_DISPLAYCONTROL | _displaycontrol);
197 }
198 
203  _displaycontrol &= ~LCD_BLINKON;
204  command(LCD_DISPLAYCONTROL | _displaycontrol);
205 }
206 
208  _displaycontrol |= LCD_BLINKON;
209  command(LCD_DISPLAYCONTROL | _displaycontrol);
210 }
211 
212 // These commands scroll the display without changing the RAM
215 }
216 
219 }
220 
225  _displaymode |= LCD_ENTRYLEFT;
226  command(LCD_ENTRYMODESET | _displaymode);
227 }
228 
233  _displaymode &= ~LCD_ENTRYLEFT;
234  command(LCD_ENTRYMODESET | _displaymode);
235 }
236 
241  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
242  command(LCD_ENTRYMODESET | _displaymode);
243 }
244 
249  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
250  command(LCD_ENTRYMODESET | _displaymode);
251 }
252 
257 void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
258  location &= 0x7; // we only have 8 locations 0-7
259  command(LCD_SETCGRAMADDR | (location << 3));
260  for (int i = 0; i < 8; i++) {
261  write(charmap[i]);
262  }
263 }
264 
269  _backlightval = LCD_NOBACKLIGHT;
270  expanderWrite(0);
271 }
272 
274  _backlightval = LCD_BACKLIGHT;
275  expanderWrite(0);
276 }
277 
278 /*********** mid level commands, for sending data/cmds */
279 inline void LiquidCrystal_I2C::command(uint8_t value) {
280  send(value, 0);
281 }
282 
283 /************ low level data pushing commands **********/
284 
288 void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
289  uint8_t highnib = value & 0xf0;
290  uint8_t lownib = (value << 4)&0xf0;
291  write4bits((highnib) | mode);
292  write4bits((lownib) | mode);
293 }
294 
295 void LiquidCrystal_I2C::write4bits(uint8_t value) {
296  expanderWrite(value);
297  pulseEnable(value);
298 }
299 
300 void LiquidCrystal_I2C::expanderWrite(uint8_t _data) {
301  Wire.beginTransmission(_Addr);
302  /*printIIC*/Wire.write((int) (_data) | _backlightval);
303  Wire.endTransmission();
304 }
305 
306 void LiquidCrystal_I2C::pulseEnable(uint8_t _data) {
307  expanderWrite(_data | En); // En high
308  delayMicroseconds(1); // enable pulse must be >450ns
309 
310  expanderWrite(_data & ~En); // En low
311  delayMicroseconds(50); // commands need > 37us to settle
312 }
#define LCD_ENTRYSHIFTDECREMENT
#define LCD_SETDDRAMADDR
#define LCD_RETURNHOME
#define LCD_CURSOROFF
#define Rs
#define LCD_BLINKOFF
#define LCD_ENTRYMODESET
#define LCD_CURSORSHIFT
#define LCD_NOBACKLIGHT
#define LCD_DISPLAYON
#define LCD_2LINE
#define LCD_1LINE
#define LCD_ENTRYSHIFTINCREMENT
#define LCD_SETCGRAMADDR
#define LCD_FUNCTIONSET
#define LCD_MOVELEFT
#define LCD_DISPLAYMOVE
#define En
#define LCD_CURSORON
#define LCD_4BITMODE
#define LCD_BACKLIGHT
#define LCD_BLINKON
#define LCD_CLEARDISPLAY
#define LCD_MOVERIGHT
#define LCD_DISPLAYCONTROL
#define LCD_ENTRYLEFT
Functions for deploying I2C LCD displays.
void rightToLeft()
This is for text that flows Right to Left.
void noAutoscroll()
This will 'left justify' text from the cursor.
void noCursor()
Turns the underline cursor on/off.
void autoscroll()
This will 'right justify' text from the cursor.
LiquidCrystal_I2C(uint8_t i2c_Addr, uint8_t lcd_cols, uint8_t lcd_rows)
Constructior.
void noBacklight()
Turn the (optional) backlight off/on.
void noBlink()
Turn on and off the blinking cursor.
void leftToRight()
This is for text that flows Left to Right.
static constexpr uint8_t LCD_5x10DOTS
void createChar(uint8_t, uint8_t[])
Allows us to fill the first 8 CGRAM locations with custom characters.
void setCursor(uint8_t, uint8_t)
static constexpr uint8_t LCD_5x8DOTS
void begin(uint8_t cols, uint8_t rows, uint8_t charsize=LCD_5x8DOTS)
void noDisplay()
Turn the display on/off (quickly)