Skip to content
This repository was archived by the owner on May 12, 2022. It is now read-only.

Commit ede037d

Browse files
authored
Merge pull request #22 from malwareslayer/master
Adding Liquid Crystal Display I2C Example
2 parents 69809da + 734390f commit ede037d

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
from time import sleep
2+
from pymata4 import pymata4
3+
from typing import (
4+
AnyStr
5+
)
6+
7+
8+
class LiquidCrystal_I2C:
9+
LCD_CLEARDISPLAY = 0x01
10+
LCD_RETURNHOME = 0x02
11+
LCD_ENTRYMODESET = 0x04
12+
LCD_DISPLAYCONTROL = 0x08
13+
LCD_CURSORSHIFT = 0x10
14+
LCD_FUNCTIONSET = 0x20
15+
LCD_SETCGRAMADDR = 0x40
16+
LCD_SETDDRAMADDR = 0x80
17+
18+
LCD_ENTRYRIGHT = 0x00
19+
LCD_ENTRYLEFT = 0x02
20+
LCD_ENTRYSHIFTINCREMENT = 0x01
21+
LCD_ENTRYSHIFTDECREMENT = 0x00
22+
23+
LCD_DISPLAYON = 0x04
24+
LCD_DISPLAYOFF = 0x00
25+
LCD_CURSORON = 0x02
26+
LCD_CURSOROFF = 0x00
27+
LCD_BLINKON = 0x01
28+
LCD_BLINKOFF = 0x00
29+
30+
LCD_DISPLAYMOVE = 0x08
31+
LCD_CURSORMOVE = 0x00
32+
LCD_MOVERIGHT = 0x04
33+
LCD_MOVELEFT = 0x00
34+
35+
LCD_8BITMODE = 0x10
36+
LCD_4BITMODE = 0x00
37+
LCD_2LINE = 0x08
38+
LCD_1LINE = 0x00
39+
LCD_5x10DOTS = 0x04
40+
LCD_5x8DOTS = 0x00
41+
42+
LCD_BACKLIGHT = 0x08
43+
LCD_NOBACKLIGHT = 0x00
44+
45+
ENABLE_BIT = 0B00000100 # Enable bit
46+
READ_WRITE_BIT = 0B00000010 # Read/Write bit
47+
REGISTER_SELECT_BIT = 0B00000001 # Register select bit
48+
49+
_backlight_value: int = LCD_NOBACKLIGHT
50+
_display_function: int = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS
51+
_numlines: int = None
52+
_display_control: int = None
53+
_display_mode: int = None
54+
_oled: bool = True
55+
56+
def write(self, value: int):
57+
self.send(value, self.REGISTER_SELECT_BIT)
58+
59+
def __init__(self, address: int, column: int, row: int, board: pymata4.Pymata4, dotsize: int = 1) -> None:
60+
self.address: int = address
61+
self.column: int = column
62+
self.row: int = row
63+
if not isinstance(board, pymata4.Pymata4):
64+
raise AttributeError("argument board not from pymata4.Pymata4")
65+
else:
66+
self.board: pymata4.Pymata4 = board
67+
68+
self.begin(self.column, self.row, dotsize=dotsize)
69+
70+
def begin(self, column: int, lines: int, dotsize: int = LCD_5x8DOTS) -> None:
71+
self.board.set_pin_mode_i2c()
72+
73+
if lines >= 1:
74+
self._display_function = self._display_function | self.LCD_2LINE
75+
76+
self._numlines = lines
77+
78+
if dotsize != 0 and lines == 1:
79+
self._display_function = self._display_function | self.LCD_5x10DOTS
80+
81+
sleep(0.05)
82+
83+
self.expander_write(self._backlight_value)
84+
sleep(1)
85+
86+
self.write_4_bits(0x03 << 0x4)
87+
sleep(0.0045)
88+
89+
self.write_4_bits(0x03 << 0x4)
90+
sleep(0.0045)
91+
92+
self.write_4_bits(0x03 << 0x4)
93+
sleep(0.00015)
94+
95+
self.write_4_bits(0x02 << 0x4)
96+
97+
self.command(self.LCD_FUNCTIONSET | self._display_function)
98+
99+
self._display_control = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
100+
self.enable_display()
101+
102+
self.clear()
103+
104+
self._display_mode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
105+
self.command(self.LCD_ENTRYMODESET | self._display_mode)
106+
107+
self.home()
108+
109+
def clear(self):
110+
self.command(self.LCD_CLEARDISPLAY)
111+
sleep(0.002)
112+
if self._oled:
113+
self.set_cursor(0, 0)
114+
115+
def home(self) -> None:
116+
self.command(self.LCD_RETURNHOME)
117+
sleep(0.002)
118+
119+
def set_cursor(self, column: int, row: int) -> None:
120+
row_offsets = [0x00, 0x40, 0x14, 0x54]
121+
if row > self._numlines:
122+
row = self._numlines - 1
123+
self.command(self.LCD_SETDDRAMADDR | (column + row_offsets[row]))
124+
125+
def disable_display(self) -> None:
126+
self._display_control = self._display_control & ~self.LCD_DISPLAYON
127+
self.command(self.LCD_DISPLAYON | self._display_control)
128+
129+
def enable_display(self) -> None:
130+
self._display_control = self._display_control | self.LCD_DISPLAYON
131+
self.command(self.LCD_DISPLAYCONTROL | self._display_control)
132+
133+
def disable_cursor(self) -> None:
134+
self._display_control = self._display_control & ~self.LCD_CURSORON
135+
self.command(self.LCD_DISPLAYCONTROL | self._display_control)
136+
137+
def enable_cursor(self) -> None:
138+
self._display_control = self._display_control | self.LCD_CURSORON
139+
self.command(self.LCD_DISPLAYCONTROL | self._display_control)
140+
141+
def disable_blink(self) -> None:
142+
self._display_control = self._display_control & ~self.LCD_BLINKON
143+
self.command(self.LCD_DISPLAYCONTROL | self._display_control)
144+
145+
def enable_blink(self) -> None:
146+
self._display_control = self._display_control | self.LCD_BLINKON
147+
self.command(self.LCD_DISPLAYCONTROL | self._display_control)
148+
149+
def scroll_display_left(self) -> None:
150+
self.command(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
151+
152+
def scroll_display_right(self) -> None:
153+
self.command(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT)
154+
155+
def left_to_right(self) -> None:
156+
self._display_mode = self._display_mode | self.LCD_ENTRYLEFT
157+
self.command(self.LCD_ENTRYMODESET | self._display_mode)
158+
159+
def right_to_left(self) -> None:
160+
self._display_mode = self._display_mode & ~self.LCD_ENTRYLEFT
161+
self.command(self.LCD_ENTRYMODESET | self._display_mode)
162+
163+
def enable_auto_scroll(self) -> None:
164+
self._display_mode = self._display_mode | self.LCD_ENTRYSHIFTINCREMENT
165+
self.command(self.LCD_ENTRYMODESET | self._display_mode)
166+
167+
def disable_auto_scroll(self) -> None:
168+
self._display_mode = self._display_mode & ~self.LCD_ENTRYSHIFTINCREMENT
169+
self.command(self.LCD_ENTRYMODESET | self._display_mode)
170+
171+
def disable_backlight(self) -> None:
172+
self._backlight_value = self.LCD_NOBACKLIGHT
173+
self.expander_write(0)
174+
175+
def enable_backlight(self) -> None:
176+
self._backlight_value = self.LCD_BACKLIGHT
177+
self.expander_write(0)
178+
179+
def command(self, value) -> None:
180+
self.send(value, 0)
181+
182+
def send(self, value: int, mode: int) -> None:
183+
high_nibble: int = value & 0xf0
184+
low_nibble: int = (value << 4) & 0xf0
185+
self.write_4_bits(high_nibble | mode)
186+
self.write_4_bits(low_nibble | mode)
187+
188+
def write_4_bits(self, value: int) -> None:
189+
self.expander_write(value)
190+
self.pulse_enable(value)
191+
192+
def expander_write(self, data: int) -> None:
193+
self.board.i2c_write(self.address, [data, self._backlight_value])
194+
195+
def pulse_enable(self, data: int) -> None:
196+
self.expander_write(data | self.ENABLE_BIT)
197+
sleep(0.000001)
198+
199+
self.expander_write(data & ~self.ENABLE_BIT)
200+
sleep(0.00005)
201+
202+
def print(self, string: AnyStr) -> None:
203+
for character in string:
204+
self.write(ord(character))
205+
sleep(0.000001)
206+
else:
207+
sleep(0.00005)
208+
209+
210+
Board = pymata4.Pymata4("/dev/ttyACM0")
211+
LCD = LiquidCrystal_I2C(0x27, 0, 1, Board)
212+
LCD.enable_backlight()
213+
LCD.print("Hello, Worlds!")

0 commit comments

Comments
 (0)