Switch through custom data with 16×2 LCD screen and Raspberry Pi

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).

 Switch through custom data with 16×2 LCD screen and Raspberry Pi

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:

LCDswitch1

LCDswitch2

LCDswitch3 (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.

LCDswitch4

LCDswitch5

LCDswitch6

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()
  Switch through custom data with 16×2 LCD screen and Raspberry Pidef 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


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top