Skip to content

Commit f2b3401

Browse files
committed
Initial commit.
0 parents  commit f2b3401

File tree

7 files changed

+556
-0
lines changed

7 files changed

+556
-0
lines changed

LiquidCrystal_I2C.cpp

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
#include "LiquidCrystal_I2C.h"
2+
#include <inttypes.h>
3+
#include <Arduino.h>
4+
#include <Wire.h>
5+
6+
// When the display powers up, it is configured as follows:
7+
//
8+
// 1. Display clear
9+
// 2. Function set:
10+
// DL = 1; 8-bit interface data
11+
// N = 0; 1-line display
12+
// F = 0; 5x8 dot character font
13+
// 3. Display on/off control:
14+
// D = 0; Display off
15+
// C = 0; Cursor off
16+
// B = 0; Blinking off
17+
// 4. Entry mode set:
18+
// I/D = 1; Increment by 1
19+
// S = 0; No shift
20+
//
21+
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
22+
// can't assume that its in that state when a sketch starts (and the
23+
// LiquidCrystal constructor is called).
24+
25+
LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows)
26+
{
27+
_Addr = lcd_Addr;
28+
_cols = lcd_cols;
29+
_rows = lcd_rows;
30+
_backlightval = LCD_NOBACKLIGHT;
31+
}
32+
33+
void LiquidCrystal_I2C::init(){
34+
init_priv();
35+
}
36+
37+
void LiquidCrystal_I2C::init_priv()
38+
{
39+
Wire.begin();
40+
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
41+
begin(_cols, _rows);
42+
}
43+
44+
void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
45+
if (lines > 1) {
46+
_displayfunction |= LCD_2LINE;
47+
}
48+
_numlines = lines;
49+
50+
// for some 1 line displays you can select a 10 pixel high font
51+
if ((dotsize != 0) && (lines == 1)) {
52+
_displayfunction |= LCD_5x10DOTS;
53+
}
54+
55+
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
56+
// according to datasheet, we need at least 40ms after power rises above 2.7V
57+
// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
58+
delay(50);
59+
60+
// Now we pull both RS and R/W low to begin commands
61+
expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1)
62+
delay(1000);
63+
64+
//put the LCD into 4 bit mode
65+
// this is according to the hitachi HD44780 datasheet
66+
// figure 24, pg 46
67+
68+
// we start in 8bit mode, try to set 4 bit mode
69+
write4bits(0x03 << 4);
70+
delayMicroseconds(4500); // wait min 4.1ms
71+
72+
// second try
73+
write4bits(0x03 << 4);
74+
delayMicroseconds(4500); // wait min 4.1ms
75+
76+
// third go!
77+
write4bits(0x03 << 4);
78+
delayMicroseconds(150);
79+
80+
// finally, set to 4-bit interface
81+
write4bits(0x02 << 4);
82+
83+
84+
// set # lines, font size, etc.
85+
command(LCD_FUNCTIONSET | _displayfunction);
86+
87+
// turn the display on with no cursor or blinking default
88+
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
89+
display();
90+
91+
// clear it off
92+
clear();
93+
94+
// Initialize to default text direction (for roman languages)
95+
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
96+
97+
// set the entry mode
98+
command(LCD_ENTRYMODESET | _displaymode);
99+
100+
home();
101+
102+
}
103+
104+
105+
106+
/********** high level commands, for the user! */
107+
void LiquidCrystal_I2C::clear(){
108+
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
109+
delayMicroseconds(2000); // this command takes a long time!
110+
}
111+
112+
void LiquidCrystal_I2C::home(){
113+
command(LCD_RETURNHOME); // set cursor position to zero
114+
delayMicroseconds(2000); // this command takes a long time!
115+
}
116+
117+
void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){
118+
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
119+
if ( row > _numlines ) {
120+
row = _numlines-1; // we count rows starting w/0
121+
}
122+
command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
123+
}
124+
125+
// Turn the display on/off (quickly)
126+
void LiquidCrystal_I2C::noDisplay() {
127+
_displaycontrol &= ~LCD_DISPLAYON;
128+
command(LCD_DISPLAYCONTROL | _displaycontrol);
129+
}
130+
void LiquidCrystal_I2C::display() {
131+
_displaycontrol |= LCD_DISPLAYON;
132+
command(LCD_DISPLAYCONTROL | _displaycontrol);
133+
}
134+
135+
// Turns the underline cursor on/off
136+
void LiquidCrystal_I2C::noCursor() {
137+
_displaycontrol &= ~LCD_CURSORON;
138+
command(LCD_DISPLAYCONTROL | _displaycontrol);
139+
}
140+
void LiquidCrystal_I2C::cursor() {
141+
_displaycontrol |= LCD_CURSORON;
142+
command(LCD_DISPLAYCONTROL | _displaycontrol);
143+
}
144+
145+
// Turn on and off the blinking cursor
146+
void LiquidCrystal_I2C::noBlink() {
147+
_displaycontrol &= ~LCD_BLINKON;
148+
command(LCD_DISPLAYCONTROL | _displaycontrol);
149+
}
150+
void LiquidCrystal_I2C::blink() {
151+
_displaycontrol |= LCD_BLINKON;
152+
command(LCD_DISPLAYCONTROL | _displaycontrol);
153+
}
154+
155+
// These commands scroll the display without changing the RAM
156+
void LiquidCrystal_I2C::scrollDisplayLeft(void) {
157+
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
158+
}
159+
void LiquidCrystal_I2C::scrollDisplayRight(void) {
160+
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
161+
}
162+
163+
// This is for text that flows Left to Right
164+
void LiquidCrystal_I2C::leftToRight(void) {
165+
_displaymode |= LCD_ENTRYLEFT;
166+
command(LCD_ENTRYMODESET | _displaymode);
167+
}
168+
169+
// This is for text that flows Right to Left
170+
void LiquidCrystal_I2C::rightToLeft(void) {
171+
_displaymode &= ~LCD_ENTRYLEFT;
172+
command(LCD_ENTRYMODESET | _displaymode);
173+
}
174+
175+
// This will 'right justify' text from the cursor
176+
void LiquidCrystal_I2C::autoscroll(void) {
177+
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
178+
command(LCD_ENTRYMODESET | _displaymode);
179+
}
180+
181+
// This will 'left justify' text from the cursor
182+
void LiquidCrystal_I2C::noAutoscroll(void) {
183+
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
184+
command(LCD_ENTRYMODESET | _displaymode);
185+
}
186+
187+
// Allows us to fill the first 8 CGRAM locations
188+
// with custom characters
189+
void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
190+
location &= 0x7; // we only have 8 locations 0-7
191+
command(LCD_SETCGRAMADDR | (location << 3));
192+
for (int i=0; i<8; i++) {
193+
write(charmap[i]);
194+
}
195+
}
196+
197+
// Turn the (optional) backlight off/on
198+
void LiquidCrystal_I2C::noBacklight(void) {
199+
_backlightval=LCD_NOBACKLIGHT;
200+
expanderWrite(0);
201+
}
202+
203+
void LiquidCrystal_I2C::backlight(void) {
204+
_backlightval=LCD_BACKLIGHT;
205+
expanderWrite(0);
206+
}
207+
208+
209+
210+
/*********** mid level commands, for sending data/cmds */
211+
212+
inline void LiquidCrystal_I2C::command(uint8_t value) {
213+
send(value, 0);
214+
}
215+
216+
inline size_t LiquidCrystal_I2C::write(uint8_t value) {
217+
send(value, Rs);
218+
}
219+
220+
221+
222+
/************ low level data pushing commands **********/
223+
224+
// write either command or data
225+
void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
226+
uint8_t highnib=value&0xf0;
227+
uint8_t lownib=(value<<4)&0xf0;
228+
write4bits((highnib)|mode);
229+
write4bits((lownib)|mode);
230+
}
231+
232+
void LiquidCrystal_I2C::write4bits(uint8_t value) {
233+
expanderWrite(value);
234+
pulseEnable(value);
235+
}
236+
237+
void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
238+
Wire.beginTransmission(_Addr);
239+
Wire.write((int)(_data) | _backlightval);
240+
Wire.endTransmission();
241+
}
242+
243+
void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
244+
expanderWrite(_data | En); // En high
245+
delayMicroseconds(1); // enable pulse must be >450ns
246+
247+
expanderWrite(_data & ~En); // En low
248+
delayMicroseconds(50); // commands need > 37us to settle
249+
}
250+
251+
void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){
252+
createChar(char_num, rows);
253+
}
254+
255+
void LiquidCrystal_I2C::setBacklight(uint8_t new_val){
256+
if(new_val){
257+
backlight(); // turn backlight on
258+
}else{
259+
noBacklight(); // turn backlight off
260+
}
261+
}
262+
263+
void LiquidCrystal_I2C::printstr(const char c[]){
264+
//This function is not identical to the function used for "real" I2C displays
265+
//it's here so the user sketch doesn't have to be changed
266+
print(c);
267+
}
268+
269+
// unsupported API functions
270+
void LiquidCrystal_I2C::off() {}
271+
void LiquidCrystal_I2C::on() {}
272+
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
273+
uint8_t LiquidCrystal_I2C::status(){return 0;}
274+
uint8_t LiquidCrystal_I2C::keypad (){return 0;}
275+
uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
276+
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
277+
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
278+
void LiquidCrystal_I2C::setContrast(uint8_t new_val){}

0 commit comments

Comments
 (0)