|# requires RPi_I2C_driver.py|
|from time import *|
|mylcd = RPi_I2C_driver.lcd()|
|# test 2|
|mylcd.lcd_display_string("RPi I2C test", 1)|
|mylcd.lcd_display_string(" Custom chars", 2)|
|sleep(2) # 2 sec delay|
|# let's define a custom icon, consisting of 6 individual characters|
|# 3 chars in the first row and 3 chars in the second row|
|fontdata1 = [|
|# Char 0 - Upper-left|
|[ 0x00, 0x00, 0x03, 0x04, 0x08, 0x19, 0x11, 0x10 ],|
|# Char 1 - Upper-middle|
|[ 0x00, 0x1F, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00 ],|
|# Char 2 - Upper-right|
|[ 0x00, 0x00, 0x18, 0x04, 0x02, 0x13, 0x11, 0x01 ],|
|# Char 3 - Lower-left|
|[ 0x12, 0x13, 0x1b, 0x09, 0x04, 0x03, 0x00, 0x00 ],|
|# Char 4 - Lower-middle|
|[ 0x00, 0x11, 0x1f, 0x1f, 0x0e, 0x00, 0x1F, 0x00 ],|
|# Char 5 - Lower-right|
|[ 0x09, 0x19, 0x1b, 0x12, 0x04, 0x18, 0x00, 0x00 ],|
|# Char 6 - my test|
|# Load logo chars (fontdata1)|
|# Write first three chars to row 1 directly|
|# Write next three chars to row 2 directly|
|mylcd.lcd_display_string_pos("Testing",1,1) # row 1, column 1|
|mylcd.lcd_display_string_pos("Testing",2,3) # row 2, column 3|
|# Now let's define some more custom characters|
|fontdata2 = [|
|# Char 0 - left arrow|
|[ 0x1,0x3,0x7,0xf,0xf,0x7,0x3,0x1 ],|
|# Char 1 - left one bar|
|[ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 ],|
|# Char 2 - left two bars|
|[ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 ],|
|# Char 3 - left 3 bars|
|[ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c ],|
|# Char 4 - left 4 bars|
|[ 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e ],|
|# Char 5 - left start|
|[ 0x0,0x1,0x3,0x7,0xf,0x1f,0x1f,0x1f ],|
|# Char 6 -|
|# [ ],|
|# Load logo chars from the second set|
|block = chr(255) # block character, built-in|
|# display two blocks in columns 5 and 6 (i.e. AFTER pos. 4) in row 1|
|# first draw two blocks on 5th column (cols 5 and 6), starts from 0|
|mylcd.lcd_display_string_pos(block * 2,1,4)|
|pauza = 0.2 # define duration of sleep(x)|
|# now draw cust. chars starting from col. 7 (pos. 6)|
|pos = 6|
|# and another one, same as above, 1 char-space to the right|
|pos = pos +1 # increase column by one|
|# now again load first set of custom chars - smiley|
|# -*- coding: utf-8 -*-|
|Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic|
|Made available under GNU GENERAL PUBLIC LICENSE|
|# Modified Python I2C library for Raspberry Pi|
|# as found on http://www.recantha.co.uk/blog/?p=4849|
|# Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library|
|# added bits and pieces from various sources|
|# By DenisFromHR (Denis Pleic)|
|# 2015-02-10, ver 0.1|
|from time import *|
|def __init__(self, addr, port=1):|
|self.addr = addr|
|self.bus = smbus.SMBus(port)|
|# Write a single command|
|def write_cmd(self, cmd):|
|# Write a command and argument|
|def write_cmd_arg(self, cmd, data):|
|self.bus.write_byte_data(self.addr, cmd, data)|
|# Write a block of data|
|def write_block_data(self, cmd, data):|
|self.bus.write_block_data(self.addr, cmd, data)|
|# Read a single byte|
|def read_data(self, cmd):|
|return self.bus.read_byte_data(self.addr, cmd)|
|# Read a block of data|
|def read_block_data(self, cmd):|
|return self.bus.read_block_data(self.addr, cmd)|
|# LCD Address|
|ADDRESS = 0x27|
|LCD_CLEARDISPLAY = 0x01|
|LCD_RETURNHOME = 0x02|
|LCD_ENTRYMODESET = 0x04|
|LCD_DISPLAYCONTROL = 0x08|
|LCD_CURSORSHIFT = 0x10|
|LCD_FUNCTIONSET = 0x20|
|LCD_SETCGRAMADDR = 0x40|
|LCD_SETDDRAMADDR = 0x80|
|# flags for display entry mode|
|LCD_ENTRYRIGHT = 0x00|
|LCD_ENTRYLEFT = 0x02|
|LCD_ENTRYSHIFTINCREMENT = 0x01|
|LCD_ENTRYSHIFTDECREMENT = 0x00|
|# flags for display on/off control|
|LCD_DISPLAYON = 0x04|
|LCD_DISPLAYOFF = 0x00|
|LCD_CURSORON = 0x02|
|LCD_CURSOROFF = 0x00|
|LCD_BLINKON = 0x01|
|LCD_BLINKOFF = 0x00|
|# flags for display/cursor shift|
|LCD_DISPLAYMOVE = 0x08|
|LCD_CURSORMOVE = 0x00|
|LCD_MOVERIGHT = 0x04|
|LCD_MOVELEFT = 0x00|
|# flags for function set|
|LCD_8BITMODE = 0x10|
|LCD_4BITMODE = 0x00|
|LCD_2LINE = 0x08|
|LCD_1LINE = 0x00|
|LCD_5x10DOTS = 0x04|
|LCD_5x8DOTS = 0x00|
|# flags for backlight control|
|LCD_BACKLIGHT = 0x08|
|LCD_NOBACKLIGHT = 0x00|
|En = 0b00000100 # Enable bit|
|Rw = 0b00000010 # Read/Write bit|
|Rs = 0b00000001 # Register select bit|
|#initializes objects and lcd|
|self.lcd_device = i2c_device(ADDRESS)|
|self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)|
|self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)|
|self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)|
|# clocks EN to latch command|
|def lcd_strobe(self, data):|
|self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)|
|self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))|
|def lcd_write_four_bits(self, data):|
|self.lcd_device.write_cmd(data | LCD_BACKLIGHT)|
|# write a command to lcd|
|def lcd_write(self, cmd, mode=0):|
|self.lcd_write_four_bits(mode | (cmd & 0xF0))|
|self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))|
|# write a character to lcd (or character rom) 0x09: backlight | RS=DR<|
|def lcd_write_char(self, charvalue, mode=1):|
|self.lcd_write_four_bits(mode | (charvalue & 0xF0))|
|self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0))|
|# put string function|
|def lcd_display_string(self, string, line):|
|if line == 1:|
|if line == 2:|
|if line == 3:|
|if line == 4:|
|for char in string:|
|# clear lcd and set to home|
|# define backlight on/off (lcd.backlight(1); off= lcd.backlight(0)|
|def backlight(self, state): # for state, 1 = on, 0 = off|
|if state == 1:|
|elif state == 0:|
|# add custom characters (0 - 7)|
|def lcd_load_custom_chars(self, fontdata):|
|for char in fontdata:|
|for line in char:|
|# define precise positioning (addition from the forum)|
|def lcd_display_string_pos(self, string, line, pos):|
|if line == 1:|
|pos_new = pos|
|elif line == 2:|
|pos_new = 0x40 + pos|
|elif line == 3:|
|pos_new = 0x14 + pos|
|elif line == 4:|
|pos_new = 0x54 + pos|
|self.lcd_write(0x80 + pos_new)|
|for char in string:|
Perhaps someone might find this useful: I took an existing Python I2C LCD library from
Never occured to me, to be honest....
Another thing which I encountered in Arch Linux on RasPi: you might get the following error message when running the above examples:
Hi Denis, are you able to describe how to add a degree symbol? I've tried chr(176) chr(223) and unichr(176) unichr(223) and can't get it to work.
Here's a snippet of my code:
Hi Denis, i have a weired issue when printing a row as above with temperature as %currenttemp, i get the upper right part of the pumpkin character you've made right after the value...
i've already try the recantha library before and had the same issue with a different character
any idea on how to get ride of it?
this works fine for me, and you can just append the position if needed (and you can even ommit the line which then defaults to 1).
Here are your modified files:
Hi, thanks for this it looks promising but I can't get it to work... I'm using a 16x2 HD44780 LCD connected to a PCF8574N chip, wired to the RPi 2 via I2C (stand alone chip, not a back pack) wired following this tutorial: http://www.rpiblog.com/2012/07/interfacing-16x2-lcd-with-raspberry-pi.html. My problem is when I run examples.py, the program runs without errors, but nothing displays on the LCD. I have changed the address in the library. Is there anything else I need to change in the library or example program for my specific set up? Any help would really be appreciated!
Hello, first of all, thanks Denis for your job... I'm very sorry for this silly question but I'm not able to install your library in my Raspi. Downloaded the library in my RPi and tried to install using "pip install RPi_I2C_driver.py".... I obtain a bunch of errors and library wont install.
Never mind - I found the answer http://mil.ufl.edu/4744/docs/lcdmanual/characterset.html
I have following problem:
Does anyone know what is wrong? I copy pasted code. Running i2cdetect 0 says that my i2c is under 0x27 address (so I did not change anything in the script). Do you have any ideas what is wrong? I connected i2c to hd44780 pin by pin (1--1, 2--2, 3--3, 4--4, etc.)
EDIT: Internet conection seems to be affecting somehow. With either ethernet cable or wifi dongle, it displays the characters of doom after about 30min. Without any conection it will last for about 6 hours.
Looking for help or advice on this.
What I am trying to do is have 4 independent scripts, each write to one single line.
Script 1 - python - real time date and time with seconds displayed on line 1 - script is always running and updates line one once a second. No lcd_clear() used.
So, each one works perfectly on their own.
When I have two or more running, it will soon start writing random characters to the screen, mostly on the wrong lines (can be above or below). It can happen nearly instantly or start happening 20 minutes later.
I have tried adding the screen clear to one or more of the scripts, but due to other issues (data not being present on the script run), lines won't update again until the next cron run or command. Not ideal, plus I hate the way the lcd_clear() looks when it happens.
I am sure it has to do something with two or more scripts trying to access the lcd at nearly the same time.
So, any ideas or suggestions to get 4 scripts each writing their own line, to play nice and not corrupt the display?
Any thoughts are welcomed.
Hey all! I came across this looking for info on how to get my own LCD/I2C combo to work with my rpi 3, and thought it would be beneficial for enough people to make it into a pypi package. Any ideas/contributions/complaints are welcome!
@DenisFromHR any idea what these are for?
I live in Norway, but apparently I have the LCD ROM with the Japanese font set, which makes displaying the nordic characters (æ, ø, å) a real headache, at least when you're dealing with inconsistent ascii-tables and unicode (UTF8) conversions on top of that.
However, I made a custom font set with the "missing" norwegian characters, if anyone's interested.
Just out of curiousity:
it would be GREAT if I somehow managed to automatically map the character "æ" to (for instance) chr(1), "ø" to chr(2) and so on.
And if everything else fails, shouldn't it be possible to do a "char.replace('ø', chr(1))", or something similar in Python? It would make the programming flow SO much easier.
Anyway, here's my (very basic) example code (updated):
Here's how I managed to add the extra Norwegian characters to the font set. I know there are more efficient ways to do this, but I'm still learning Python, and for this purpose it kind of works:
Good job, Denis!
In case anyone is interested, here it is:
I'm trying to use this driver with PCF8574's younger sibling - PCA9554P with a 16x2 lcd display, but it does not work at all. I'm constantly getting a same error:
I'm using Raspbian stretch full, downloaded on 9.11.2018.