Introduction
After starting my circuit testing with some LEDs and switches I moved up to a small 16×2 LCD screen (HD44780 controller) with the Raspberry Pi. The configuration of the LCD pins and base code for output to the 16×2 LCD screen is taken from the excellent Raspberry Pi Spy website. I’ve made a few modifications:
- Added some python code to obtain hostname, IP address, CPU load and memory usage.
- Introduce a switch that cycles through the data above (read in through a voltage divider and GPIO input).
Circuit Diagram
Using the excellent Fritzing tool my circuit diagram is shown below (again, very similar to the Raspberry Pi Spy website with a couple of additions)
There is a 10K potentiometer in the middle (attached to the contrast pin of the LCD screen) to control screen contrast. In addition there is a voltage divider with the switch feeding into GPIO 22. This switch will be used to cycle through the data output to screen. The voltage divider is required because the LCD screen is using the 5V rail but the GPIO pins should never receive an input above 3.3V. In addition R2 in the voltage divider is acting as a pull down resistor.
The calculations below were used to obtain the voltage out using some simple resistor values:
(this is sufficient to provide a HIGH on the GPIO pin)
If you want a voltage closer to 3.3V then a 6.8K resistor will provide ~3.0V.
In addition to the voltage input above, the current dropped across R1 when the switch is pressed is ~0.5mA. Both voltage and current readings were confirmed with a multimeter.
Code
Here is the python code for the switch cycling:
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
2021
|
#!/usr/bin/python # # HD44780 LCD Script for # Raspberry Pi # Reads switch input and shuffles through # Hostname, IP address, CPU load # and memory usage. # The wiring for the LCD is as follows: # 1 : GND # 2 : 5V # 3 : Contrast (0-5V)* # 4 : RS (Register Select) # 5 : R/W (Read Write) - GROUND THIS PIN # 6 : Enable or Strobe # 7 : Data Bit 0 - NOT USED # 8 : Data Bit 1 - NOT USED # 9 : Data Bit 2 - NOT USED # 10: Data Bit 3 - NOT USED # 11: Data Bit 4 # 12: Data Bit 5 # 13: Data Bit 6 # 14: Data Bit 7 # 15: LCD Backlight +5V** # 16: LCD Backlight GND #import import RPi.GPIO as GPIO import time import subprocess # Define GPIO to LCD mapping LCD_RS = 7 LCD_E = 8 LCD_D4 = 25 LCD_D5 = 24 LCD_D6 = 23 LCD_D7 = 18 SWITCH_IN = 22 # Define some device constants LCD_WIDTH = 16 # Maximum characters per line LCD_CHR = True LCD_CMD = False LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line # Timing constants E_PULSE = 0.000005 E_DELAY = 0.000005 def main(): # Main program block GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers GPIO.setup(LCD_E, GPIO.OUT) # E GPIO.setup(LCD_RS, GPIO.OUT) # RS GPIO.setup(LCD_D4, GPIO.OUT) # DB4 GPIO.setup(LCD_D5, GPIO.OUT) # DB5 GPIO.setup(LCD_D6, GPIO.OUT) # DB6 GPIO.setup(LCD_D7, GPIO.OUT) # DB7 GPIO.setup(SWITCH_IN, GPIO.IN) # Switch Input cmd = "ip addr show wlan0 | grep inet | awk '{print $2}' | cut -d/ -f1" cmd2 = "hostname" cmd3 = "free | grep cache: | awk '{print $4}'" cmd4 = "uptime | tail -c 17" i = 1 # Initialise display lcd_init() while True : time.sleep( 0.05 ) if GPIO. input (SWITCH_IN) = = True : if i = = 1 : hostname = run_cmd2(cmd2) fhostname(hostname) i = 2 time.sleep( 0.1 ) elif i = = 2 : ipaddr = run_cmd(cmd) fipaddress(ipaddr) i = 3 time.sleep( 0.1 ) elif i = = 3 : cpuload = run_cmd4(cmd4) fcpuload(cpuload) i = 4 time.sleep( 0.1 ) elif i = = 4 : memory = run_cmd3(cmd3) ffreememory(memory) i = 1 time.sleep( 0.1 ) else : print ( "no function found" ) def fhostname(hostname): # Send hostname information lcd_byte(LCD_LINE_1, LCD_CMD) lcd_string( "Hostname" , 2 ) lcd_byte(LCD_LINE_2, LCD_CMD) lcd_string(hostname, 2 ) while GPIO.inputSWITCH_IN = = True : pass def fipaddress(ipaddr): # Send IP info lcd_byte(LCD_LINE_1, LCD_CMD) lcd_string( "IP Address" , 2 ) lcd_byte(LCD_LINE_2, LCD_CMD) lcd_string(ipaddr, 2 ) while GPIO.inputSWITCH_IN = = True : pass def ffreememory(memory): # Send some text lcd_byte(LCD_LINE_1, LCD_CMD) lcd_string( "Free Memory" , 2 ) lcd_byte(LCD_LINE_2, LCD_CMD) lcd_string(memory + " MB" , 2 ) while GPIO.inputSWITCH_IN = = True : pass def fcpuload(cpuload): # Send some text lcd_byte(LCD_LINE_1, LCD_CMD) lcd_string( "CPU Load" , 2 ) lcd_byte(LCD_LINE_2, LCD_CMD) lcd_string(cpuload, 2 ) while GPIO.inputSWITCH_IN = = True : pass #Capture IP Address def run_cmd(cmd): p = subprocess.Popen(cmd, shell = True , stdout = subprocess.PIPE) output = p.communicate()[ 0 ] return output.rstrip() #Capture Hostname def run_cmd2(cmd2): p = subprocess.Popen(cmd2, shell = True , stdout = subprocess.PIPE) output = p.communicate()[ 0 ] return output.rstrip() #Capture Hostname def run_cmd3(cmd3): p = subprocess.Popen(cmd3, shell = True , stdout = subprocess.PIPE) output = p.communicate()[ 0 ] output = str ( int (output) / 1024 ) return output.rstrip() #Capture CPU Load def run_cmd4(cmd4): p = subprocess.Popen(cmd4, shell = True , stdout = subprocess.PIPE) output = p.communicate()[ 0 ] return (output.rstrip()).lstrip() def lcd_init(): # Initialise display lcd_byte( 0x33 ,LCD_CMD) lcd_byte( 0x32 ,LCD_CMD) lcd_byte( 0x28 ,LCD_CMD) lcd_byte( 0x0C ,LCD_CMD) lcd_byte( 0x06 ,LCD_CMD) lcd_byte( 0x01 ,LCD_CMD) def lcd_string(message,style): # Send string to display # style=1 Left justified # style=2 Centred # style=3 Right justified if style = = 1 : message = message.ljust(LCD_WIDTH, " " ) elif style = = 2 : message = message.center(LCD_WIDTH, " " ) elif style = = 3 : message = message.rjust(LCD_WIDTH, " " ) for i in range (LCD_WIDTH): lcd_byte( ord (message[i]),LCD_CHR) def lcd_byte(bits, mode): # Send byte to data pins # bits = data # mode = True for character # False for command |
For more detail: Switch through custom data with 16×2 LCD screen and Raspberry Pi