Raspberry Pi Hacking - Controlling a LCD with Buttons and Python
By: magikh0e
magikh0e _aT_ ihtb d0t org
'\v/`
(o 0) m0o.
(_) /
Last Edit: Mar 23 2013
TOC
Introduction
HD44780 Schematic
Raspberry Pi Pins/GPIO
Connecting the LCD to Power
Powering Buttons and Connecting to GPIO
Button Function to GPIO Pin mapping
Driving the LCD and Buttons with Python
Final Outcome
This guide assumes you already have some prior/intermediate knowledge of developing on Raspberry Pi's and utilizing GPIO. It also assumes you will be using a breadboard
for wiring things up.
If this is your first time, I suggest you start here first: Raspberry.Pi.Hacking.pdf
HD44780 Schematic
|
Raspberry Pi Pinout
|
Connecting up the LCD (Power)
1. Connect VSS from the LCD into -/Ground on the breadboard.
2. Connect VCC from the LCD into +/Positive on the breadboard.
3. Connect VO from the LCD into -/Ground on the breadboard.
4. Connect LEDA from the LCD to +/Positive on the breadboard.
** Note: By connecting the middle pin of a 10k potentiometer to VO, you will be able to adjust the brightness of the LCD.
Though this has not been used in this guide..
Powering LCD from Raspberry Pi (5V)
1. Connect Pin 6/Ground from the Raspberry Pi into -/Ground on the breadboard.
2. Connect Pin 2/5V from the Raspberry Pi into +/Positive on the breadboard.
NOTE: Make sure you are using 5V, not 3.3V for the LCD!
Powering the Buttons from Raspberry Pi (3.3V)
1. Connect Pin 1/3.3V from the Raspberry Pi into +/Positive on the opposite side of the 5V pins on the breadboard.
NOTE: Make sure you are using 3.3V, not 5V for the buttons!
Also verify the 3.3V and 5V source are not connected to the same pins...
Wiring the Buttons to the Raspberry Pi
You have to be careful on this part of building the circit, there is a chance of causing damage to the pins if they are accidentally setup as an output when using
buttons. If you drive the pin LOW, the output is connected directly to Ground. Pushing the button after will create a short circuit between 3.3v and Ground.
Your Pi will NOT like this... =)
NOTE: To keep the Pi happy, you can put a 1k limiting resistor between the pin and the GPIO pin on the Raspberry Pi.
This resistor will ensure the pi can handle the current being drawn from it in case of accidents and/or user errors...
Button to Function Mapping
BUTTON NAME | GPIO / NAME | WiringPI |
Return | 1 / SCL | 9 |
OK | 4 / GPIO 7 | 7 |
Down | 10 / MOSI | 12 |
Right | 17 / GPIO 0 | 0 |
Left | 22 / GPIO 3 | 3 |
UP | 21 / GPIO 2 | 2 |
Before connecting up any wires, make sure you have double checked the datahseets for the buttons you will be using for proper pin configuration.
1. Pin 1 from the button connects to 3.3V on the breadboard with a 10k resistor
2. Pin 1 from the button connects to GPIO # corelating to the buttons function.
3. Pin 2 from the button connects to -/Ground on the breadboard.
4. Repeat steps 1-3 for each button using the mappings above.
You will need 6 Buttons total.
Button Schematic Example
When a GPIO pin is set to be an IN/input, it is put into a "floating" state and has no defined voltage level.
So when wiring the buttons, they need to be wired so they will have a HIGH or LOW change of state when pressed.
This is done by using a 10k pull down resistor into -/Ground. By using a 10k resistor will create a path to -/Ground and the pin
will read LOW when the button is not pressed. When the button is pressed and you have the other side connected to 3.3V, there will
be a lower resistance path to -/Ground and the pin will then read HIGH.
Using a large 10k resistor will make sure only small amounts of current are pulled from the Raspberry Pi when the button is pressed.
Driving the LCD and Buttons with Python
#!/usr/bin/python
from time import *
import time
import sys
import collections
import datetime
from subprocess import *
import RPi.GPIO as GPIO
# MODE
E_PULSE = 0.00005
E_DELAY = 0.00005
wait = 0.1
# LCD
LCD_WIDTH = 16
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
LCD_RS = 7
LCD_E = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18
LED_ON = 15
# MAPPING OF BUTTONS
RT = 1
OK = 4
DN = 10
RI = 17
LE = 22
UP = 21
tag = 0
val = 0
p = 0
try:
def main():
print "Loaded..."
tag = 0
val = 0
p = 0
GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_E, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
GPIO.setup(LED_ON, GPIO.OUT)
GPIO.setup(RT, GPIO.IN)
GPIO.setup(OK, GPIO.IN)
GPIO.setup(DN, GPIO.IN)
GPIO.setup(RI, GPIO.IN)
GPIO.setup(LE, GPIO.IN)
GPIO.setup(UP, GPIO.IN)
rt = GPIO.input(RT)
ok = GPIO.input(OK)
dn = GPIO.input(DN)
ri = GPIO.input(RI)
le = GPIO.input(LE)
up = GPIO.input(UP)
lcd_init()
GPIO.output(LED_ON, False)
time.sleep(1)
GPIO.output(LED_ON, True)
time.sleep(1)
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string("magikh0e")
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string("ihtb.org")
p = 0
tag = 0
val = 0
while True:
#lcd_byte(LCD_LINE_2, LCD_CMD)
#Return
rt = GPIO.input(RT)
#Ok
ok = GPIO.input(OK)
#Down
dn = GPIO.input(DN)
#Right
ri = GPIO.input(RI)
#Left
le = GPIO.input(LE)
#Up
up = GPIO.input(UP)
if rt == False:
p = "rt"
if ok == False:
p = "ok"
if dn == False:
p = "dn"
if ri == False:
p = "ri"
if le == False:
p = "le"
if up == False:
p = "up"
if p != 0:
result = message(tag, val, p)
val = result['val']
tag = result['tag']
p = 0
sleep(wait)
def message(tag, val, button):
lcd_byte(LCD_LINE_1, LCD_CMD)
lcd_string("you have pressed " + button)
if button == "ok":
tag = tag + 10
if button == "rt":
if tag >= 10:
tag = tag -10
else:
tag = 0
if button == "dn":
val = val - 1
if button == "up":
val = val + 1
if button == "le":
tag = tag - 1
if button == "ri":
tag = tag + 1
lcd_byte(LCD_LINE_2, LCD_CMD)
lcd_string("val " + str(val) + " tag " + str(tag))
return{'tag':tag, 'val':val}
def lcd_init():
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):
message = message.center(LCD_WIDTH, " ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]), LCD_CHR)
def lcd_byte(bits, mode):
GPIO.output(LCD_RS, mode) #RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
if __name__ == '__main__':
main()
except Exception,e:
print str(e)
