blob: 8e1c66b7f1ffaeb6cbd7c71fda16198826c6b24a [file] [log] [blame]
cliechti88641262002-07-29 02:09:04 +00001#!/usr/bin/env python
2# character LCD example for pyparallel
3#
4#(C) 2002 Chris Liechti <cliechti@gmx.net>
5# this is distributed under a free software license, see license.txt
6
7import sys, time
cliechti85ca4ee2005-11-02 18:54:21 +00008sys.path.insert(0, '..')
cliechti88641262002-07-29 02:09:04 +00009import parallel
10
11LCDON = 0x01 #0x00000001 Switch on display
12LCDOFF = 0x08 #0x00001000 Switch off display
13LCDCLEAR = 0x01 #0x00000001
14LCDLINE1 = 0x80 #0x10000000
15LCDLINE2 = 0xc0 #0x11000000
16LCDCURSORON = 0x0f #0x00001111 turn on cursor blinking
17LCDCURSOROFF = 0x0c #0x00001100 Disable cursor blinking. The cursor is hidden.
18LCDCGADRSET = 0x40 #0b01000000
19LCDDDADRSET = 0x80 #0b10000000
20LCD2LINES = 0x28 #0b00101000 Set display mode to two lines.
21LCD8BITS = 0x30 #0b00110000 select 8 Bit interface
22LCD4BITS = 0x20 #0b00100000 select 4 Bit interface
23LCD_DATA_OFF = 0x05 #0x00000101 mask used to clear the data lines
24
25LCD_RS = 1<<1
26LCD_RW = 1<<2
27LCD_E = 1<<3
28LCD_D4 = 1<<4
29LCD_D5 = 1<<5
30LCD_D6 = 1<<6
31LCD_D7 = 1<<7
32
33
cliechti85ca4ee2005-11-02 18:54:21 +000034class FourBitIO(object):
cliechti88641262002-07-29 02:09:04 +000035 def __init__(self):
cliechti88641262002-07-29 02:09:04 +000036 self.data = 0
37
38 self.out(0) #reset pins
39 time.sleep(0.050) #wait more than 30ms
40 #send the reset sequece (3 times the same pattern)
41 self.out(LCD8BITS) #set 8 bit interface
42 self.toggleE() #toggle LCD_E, the enable pin
43 time.sleep(0.005) #wait a bit
44 self.toggleE() #toggle LCD_E, the enable pin
45 time.sleep(0.005) #wait a bit
46 self.toggleE() #toggle LCD_E, the enable pin
47 time.sleep(0.005) #wait a bit
48
49 self.out(LCD4BITS) #now set up the 4 bit interface
50 self.toggleE() #toggle LCD_E, the enable pin
51 time.sleep(0.002) #wait until instr is finished
52 self.instr(LCD2LINES) #set 2 lines display
53 self.instr(LCDCURSOROFF) #hide cursor
54 self.instr(LCDCLEAR) #clear display
55
56 #my connector has the wrong pinorder....
57 #better swap them in software than to solder ;-)
58 def reveseout(self, x):
59 r = ((x & (1<<0) and 1) << 7) |\
60 ((x & (1<<1) and 1) << 6) |\
61 ((x & (1<<2) and 1) << 5) |\
62 ((x & (1<<3) and 1) << 4) |\
63 ((x & (1<<4) and 1) << 3) |\
64 ((x & (1<<5) and 1) << 2) |\
65 ((x & (1<<6) and 1) << 1) |\
66 ((x & (1<<7) and 1) << 0)
67 #print "%02x" % r, "%02x" %x
68 self.p.setData(r)
69
70 def toggleE(self):
71 """toggle enable pin"""
72 self.data |= LCD_E; #toggle LCD_E, the enable pin
73 self.reveseout(self.data)
74 self.data &= ~LCD_E; #back to inactive position
75 self.reveseout(self.data)
76
77 def out(self, data):
78 """set data to LCD port"""
79 self.data = data
80 self.reveseout(self.data)
81
82 def instr(self, cmd):
83 """send instruction byte to LCD"""
84 self.out(cmd & 0xf0) #output upper nibble
85 self.toggleE() #toggle LCD_E, the enable pin
86 self.out((cmd << 4) & 0xf0) #and then the lower nibble
87 self.toggleE() #toggle LCD_E, the enable pin
88 time.sleep(0.001) #wait until instr is finished
89
90 def putc(self, c):
91 """send a data byte to the LCD"""
92 c = ord(c)
93 self.out((c & 0xf0) | LCD_RS) #output upper nibble
94 self.toggleE() #toggle LCD_E, the enable pin
95 self.out(((c << 4) & 0xf0) | LCD_RS) #and then the lower nibble
96 self.toggleE() #toggle LCD_E, the enable pin
97 time.sleep(0.001) #wait until instr is finished
98
cliechti85ca4ee2005-11-02 18:54:21 +000099
100class EightBitIO(object):
101 def __init__(self):
102 self.data = 0
103
104 self.setRS(0)
105 self.setRW(0)
106 self.out(0) #reset pins
107 time.sleep(0.050) #wait more than 30ms
108 #send the reset sequece (3 times the same pattern)
109 self.out(LCD8BITS) #set 8 bit interface
110 self.toggleE() #toggle LCD_E, the enable pin
111 time.sleep(0.005) #wait a bit
112 self.toggleE() #toggle LCD_E, the enable pin
113 time.sleep(0.005) #wait a bit
114 self.toggleE() #toggle LCD_E, the enable pin
115 time.sleep(0.005) #wait a bit
116
117 #~ self.instr(LCD2LINES) #set 2 lines display
118 self.instr(LCDCURSOROFF) #hide cursor
119 self.instr(LCDCLEAR) #clear display
120
121 def setRW(self, state):
122 self.p.setAutoFeed(state)
123
124 def setRS(self, state):
125 self.p.setInitOut(state)
126
127 def toggleE(self):
128 """toggle enable pin"""
129 self.p.setDataStrobe(1) #toggle LCD_E, the enable pin
130 #~ time.sleep(0.001)
131 self.p.setDataStrobe(0) #back to inactive position
132 #~ time.sleep(0.001)
133
134 def out(self, data):
135 """set data to LCD port"""
136 self.data = data
137 self.p.setData(self.data)
138
139 def instr(self, cmd):
140 """send instruction byte to LCD"""
141 self.setRS(0)
142 self.setRW(0)
143 self.out(cmd)
144 self.toggleE() #toggle LCD_E, the enable pin
145 time.sleep(0.005) #wait until instr is finished
146
147 def putc(self, c):
148 """send a data byte to the LCD"""
149 self.setRS(1)
150 self.setRW(0)
151 self.out(ord(c))
152 self.toggleE() #toggle LCD_E, the enable pin
153 time.sleep(0.001) #wait until instr is finished
154
155
156#~ class HD44780(FourBitIO):
157class HD44780(EightBitIO):
158 def __init__(self):
159 self.p = parallel.Parallel()
160 super(HD44780, self).__init__()
161
cliechti88641262002-07-29 02:09:04 +0000162 def write(self, str):
163 """write a string to the LCD"""
164 for c in str:
165 self.putc(c) #write each character
166
167 def downloadFont(self, fontdata):
168 """Set the memory pointer and download a font"""
169 self.instr(LCDCGADRSET);
170 self.write(fontdata)
171 self.instr(LCDLINE1) #just in case, set cursor to a visible pos
172
173if __name__ == '__main__':
cliechti85ca4ee2005-11-02 18:54:21 +0000174 lcd = HD44780()
cliechti88641262002-07-29 02:09:04 +0000175 lcd.write("Hello World")
176 lcd.instr(LCDLINE2)
177 lcd.write("from Python")
178## for c in map(chr,range(256)):
179## lcd.instr(LCDLINE1)
180## lcd.write(c)
181
182