summaryrefslogtreecommitdiff
path: root/pyparallel/examples/lcd.py
blob: 8e1c66b7f1ffaeb6cbd7c71fda16198826c6b24a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python
# character LCD example for pyparallel
#
#(C) 2002 Chris Liechti <cliechti@gmx.net>
# this is distributed under a free software license, see license.txt

import sys, time
sys.path.insert(0, '..')
import parallel

LCDON           = 0x01 #0x00000001 Switch on  display
LCDOFF          = 0x08 #0x00001000 Switch off display
LCDCLEAR        = 0x01 #0x00000001
LCDLINE1        = 0x80 #0x10000000
LCDLINE2        = 0xc0 #0x11000000
LCDCURSORON     = 0x0f #0x00001111 turn on cursor blinking
LCDCURSOROFF    = 0x0c #0x00001100 Disable cursor blinking. The cursor is hidden.
LCDCGADRSET     = 0x40 #0b01000000
LCDDDADRSET     = 0x80 #0b10000000
LCD2LINES       = 0x28 #0b00101000 Set display mode to two lines.
LCD8BITS        = 0x30 #0b00110000 select 8 Bit interface
LCD4BITS        = 0x20 #0b00100000 select 4 Bit interface
LCD_DATA_OFF    = 0x05 #0x00000101 mask used to clear the data lines

LCD_RS          = 1<<1
LCD_RW          = 1<<2
LCD_E           = 1<<3
LCD_D4          = 1<<4
LCD_D5          = 1<<5
LCD_D6          = 1<<6
LCD_D7          = 1<<7


class FourBitIO(object):
    def __init__(self):
        self.data = 0
        
        self.out(0)                 #reset pins
        time.sleep(0.050)           #wait more than 30ms
        #send the reset sequece (3 times the same pattern)
        self.out(LCD8BITS)          #set 8 bit interface
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        
        self.out(LCD4BITS)          #now set up the 4 bit interface
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.002)           #wait until instr is finished
        self.instr(LCD2LINES)    #set 2 lines display
        self.instr(LCDCURSOROFF) #hide cursor
        self.instr(LCDCLEAR)     #clear display

    #my connector has the wrong pinorder....
    #better swap them in software than to solder ;-)
    def reveseout(self, x):
        r = ((x & (1<<0) and 1) << 7) |\
            ((x & (1<<1) and 1) << 6) |\
            ((x & (1<<2) and 1) << 5) |\
            ((x & (1<<3) and 1) << 4) |\
            ((x & (1<<4) and 1) << 3) |\
            ((x & (1<<5) and 1) << 2) |\
            ((x & (1<<6) and 1) << 1) |\
            ((x & (1<<7) and 1) << 0)
        #print "%02x" % r, "%02x" %x
        self.p.setData(r)
        
    def toggleE(self):
        """toggle enable pin"""
        self.data |= LCD_E;         #toggle LCD_E, the enable pin
        self.reveseout(self.data)
        self.data &= ~LCD_E;        #back to inactive position
        self.reveseout(self.data)

    def out(self, data):
        """set data to LCD port"""
        self.data = data
        self.reveseout(self.data)

    def instr(self, cmd):
        """send instruction byte to LCD"""
        self.out(cmd & 0xf0)        #output upper nibble
        self.toggleE()              #toggle LCD_E, the enable pin
        self.out((cmd << 4) & 0xf0) #and then the lower nibble
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.001)           #wait until instr is finished

    def putc(self, c):
        """send a data byte to the LCD"""
        c = ord(c)
        self.out((c & 0xf0) | LCD_RS) #output upper nibble
        self.toggleE()              #toggle LCD_E, the enable pin
        self.out(((c << 4) & 0xf0) | LCD_RS) #and then the lower nibble
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.001)           #wait until instr is finished


class EightBitIO(object):
    def __init__(self):
        self.data = 0
        
        self.setRS(0)
        self.setRW(0)
        self.out(0)                 #reset pins
        time.sleep(0.050)           #wait more than 30ms
        #send the reset sequece (3 times the same pattern)
        self.out(LCD8BITS)          #set 8 bit interface
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait a bit
        
        #~ self.instr(LCD2LINES)       #set 2 lines display
        self.instr(LCDCURSOROFF)    #hide cursor
        self.instr(LCDCLEAR)        #clear display

    def setRW(self, state):
        self.p.setAutoFeed(state)
    
    def setRS(self, state):
        self.p.setInitOut(state)
        
    def toggleE(self):
        """toggle enable pin"""
        self.p.setDataStrobe(1)     #toggle LCD_E, the enable pin
        #~ time.sleep(0.001)
        self.p.setDataStrobe(0)     #back to inactive position
        #~ time.sleep(0.001)

    def out(self, data):
        """set data to LCD port"""
        self.data = data
        self.p.setData(self.data)

    def instr(self, cmd):
        """send instruction byte to LCD"""
        self.setRS(0)
        self.setRW(0)
        self.out(cmd)
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.005)           #wait until instr is finished

    def putc(self, c):
        """send a data byte to the LCD"""
        self.setRS(1)
        self.setRW(0)
        self.out(ord(c))
        self.toggleE()              #toggle LCD_E, the enable pin
        time.sleep(0.001)           #wait until instr is finished


#~ class HD44780(FourBitIO):
class HD44780(EightBitIO):
    def __init__(self):
        self.p = parallel.Parallel()
        super(HD44780, self).__init__()
        
    def write(self, str):
        """write a string to the LCD"""
        for c in str:
            self.putc(c)            #write each character

    def downloadFont(self, fontdata):
        """Set the memory pointer and download a font"""
        self.instr(LCDCGADRSET);
        self.write(fontdata)
        self.instr(LCDLINE1)        #just in case, set cursor to a visible pos

if __name__ == '__main__':
    lcd = HD44780()
    lcd.write("Hello World")
    lcd.instr(LCDLINE2)
    lcd.write("from Python")
##    for c in map(chr,range(256)):
##        lcd.instr(LCDLINE1)
##        lcd.write(c)