Skip to content

Instantly share code, notes, and snippets.

@gnawux
Last active December 25, 2015 05:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gnawux/4f68b8e301b203489336 to your computer and use it in GitHub Desktop.
Save gnawux/4f68b8e301b203489336 to your computer and use it in GitHub Desktop.
I2C LCD 1602 driver for raspberry pi
#!/usr/bin/env python
"""
original from http://www.rpiblog.com/2012/07/interfacing-16x2-lcd-with-raspberry-pi.html
I modified it, thus you can set customized pin defines, such as
lcd(0x27,1, Rs=0, Rw=1, En=2, Backlight=3, D4=4, D5=5, D6=6, D7=7)
address 0x27
port 1
P0 - Rs
P1 - RW
P2 - En
P3 - Backlight
P4-P7 - D4-D7
"""
import smbus
from time import *
# General i2c device class so that other devices can be added easily
class i2c_device:
def __init__(self, addr, port):
self.addr = addr
self.bus = smbus.SMBus(port)
def write(self, byte):
self.bus.write_byte(self.addr, byte)
def read(self):
return self.bus.read_byte(self.addr)
def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
return self.bus.read_i2c_block_data(self.addr, data, n)
class lcd:
#initializes objects and lcd
def __init__(self, addr, port, **kwarg):
self.pin = {}
self.lcd_device = i2c_device(addr, port)
self.config(**kwarg)
self.Backlight = True
self.low_level_write(En=False, Rs=False, Rw=False, data=3)
self.lcd_strobe()
sleep(0.0005)
self.lcd_strobe()
sleep(0.0005)
self.lcd_strobe()
sleep(0.0005)
self.low_level_write(En=False, Rs=False, Rw=False, data=2)
self.lcd_strobe()
sleep(0.0005)
self.lcd_write(0x28)
self.lcd_write(0x08)
self.lcd_write(0x01)
self.lcd_write(0x06)
self.lcd_write(0x0C)
self.lcd_write(0x0F)
def config(self, **kwarg):
self.pin['Rs'] = kwarg.get('Rs', 4)
self.pin['Rw'] = kwarg.get('Rw', 5)
self.pin['En'] = kwarg.get('En', 6)
self.pin['Backlight'] = kwarg.get('Backlight', 7)
self.pin['D4'] = kwarg.get('D4', 0)
self.pin['D5'] = kwarg.get('D5', 1)
self.pin['D6'] = kwarg.get('D6', 2)
self.pin['D7'] = kwarg.get('D7', 3)
def backlight(self, on=True):
self.backlight = on
def low_level_write(self, En, Rs, Rw, data):
byte = 0
if En:
byte = byte | 1 << self.pin['En']
if Rs:
byte = byte | 1 << self.pin['Rs']
if Rw:
byte = byte | 1 << self.pin['Rw']
if self.backlight:
byte = byte | 1 << self.pin['Backlight']
if data & 0x01 :
byte = byte | 1 << self.pin['D4']
if data & 0x02 :
byte = byte | 1 << self.pin['D5']
if data & 0x04 :
byte = byte | 1 << self.pin['D6']
if data & 0x08 :
byte = byte | 1 << self.pin['D7']
self.lcd_device.write(byte)
# clocks EN to latch command
def lcd_strobe(self):
self.lcd_device.write(self.lcd_device.read() | 1 << self.pin['En'] )
self.lcd_device.write(self.lcd_device.read() & (0xFF - (1<< self.pin['En'])) )
# write a command to lcd
def lcd_write(self, cmd):
self.low_level_write(En=False, Rs=False, Rw=False, data=(cmd>>4))
self.lcd_strobe()
self.low_level_write(En=False, Rs=False, Rw=False, data=(cmd&0x0F))
self.lcd_strobe()
self.low_level_write(En=False, Rs=False, Rw=False, data=0)
# write a character to lcd (or character rom)
def lcd_write_char(self, charvalue):
self.low_level_write(En=False, Rs=True, Rw=False, data=(charvalue>>4))
self.lcd_strobe()
self.low_level_write(En=False, Rs=True, Rw=False, data=(charvalue&0x0F))
self.lcd_strobe()
self.low_level_write(En=False, Rs=False, Rw=False, data=0)
# put char function
def lcd_putc(self, char):
self.lcd_write_char(ord(char))
# put string function
def lcd_puts(self, string, line):
if line == 1:
self.lcd_write(0x80)
if line == 2:
self.lcd_write(0xC0)
if line == 3:
self.lcd_write(0x94)
if line == 4:
self.lcd_write(0xD4)
for char in string:
self.lcd_putc(char)
# clear lcd and set to home
def lcd_clear(self):
self.lcd_write(0x1)
self.lcd_write(0x2)
# add custom characters (0 - 7)
def lcd_load_custon_chars(self, fontdata):
self.lcd_device.bus.write(0x40);
for char in fontdata:
for line in char:
self.lcd_write_char(line)
if __name__ == '__main__':
# define bus address, port, and pins
display = lcd(0x27,1, Rs=0, Rw=1, En=2, Backlight=3, D4=4, D5=5, D6=6, D7=7)
display.lcd_clear()
# line 1 and line 2
display.lcd_puts("I2C LCD on R-Pi",1)
display.lcd_puts(" by gnawux",2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment