bobleichhardt
Posts: 5
Joined: Tue Oct 01, 2013 8:08 am

lcd custom characters

Wed Oct 23, 2013 1:30 pm

I am using i2c_lcd from i2clibraries (http://think-bowl.com/raspberry-pi/i2c- ... pberry-pi/) to drive a 4x20 LCD and it is working fine for writing strings and characters etc.

I would like to be able to write custom characters to the LCD though and I am struggling with how to do this. There is a command method in the library but I have tried various combinations of instructions and I can't get it to work.

eg
from i2clibraries import i2c_lcd

lcd = i2c_lcd.i2c_lcd(0x27,1, 2, 1, 0, 4, 5, 6, 7, 3)
lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)

lcd.setPosition(1,1)
lcd.writeChar('>') # write a character to show LCD works

lcd.command(0x40) # try to access CGRAM which is at address 0x40, character 0

lcd.command(0x1f)
lcd.command(0x11)
lcd.command(0x11)
lcd.command(0x11) #send a character pattern (hollow rectangle)
lcd.command(0x11)
lcd.command(0x11)
lcd.command(0x1f)

lcd.command(0x00) #try to write the character -> doesn't work.

obviously I have no idea what I am doing. Can anyone help?

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: lcd custom characters

Wed Oct 23, 2013 1:34 pm

bobleichhardt wrote:
....
lcd.setPosition(1,1)
lcd.writeChar('>') # write a character to show LCD works
.....
lcd.command(0x00) #try to write the character -> doesn't work.
If you want to display a character at a position then surely you dont send a command of 0 you send the position, then Write a Char with code 0 as the parameter.

Commands are how the display operates, writing Chars is what to display.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

bobleichhardt
Posts: 5
Joined: Tue Oct 01, 2013 8:08 am

Re: lcd custom characters

Wed Oct 23, 2013 1:55 pm

That helps - if I put lcd.writeChar(chr(0x00)) it does write a char but not the one I tried to put in. I get a character with 4 horizontal lines instead of an empty box. There is something wrong with how I am entering the custom character.

fixitsan
Posts: 58
Joined: Sun Sep 29, 2013 4:28 pm

Re: lcd custom characters

Wed Oct 23, 2013 6:48 pm

I made this a while ago (the fish character is made of custom chars) http://www.youtube.com/watch?v=zvhqimcQFVE

I can't tell you the exact 'trick' to doing it, but I can tell you the answer is in the datasheet for the lcd display usually.

The standard 16 x 2 lcd datasheet describes it on page 15 onwards https://www.sparkfun.com/datasheets/LCD/HD44780.pdf

Page 24 shows that to write to the CGRAM you need to set bit DB6 (adding '64' to your character shoudl work)

Your display likely uses very similar drivers, or at least the similar command set

rickseiden
Posts: 411
Joined: Thu Aug 02, 2012 12:21 pm
Location: Buffalo, NY, USA

Re: lcd custom characters

Wed Oct 23, 2013 10:14 pm

I can't find my code that did a custom character, but here's the we resource I used to get started.

http://www.geocities.com/dinceraydin/lcd/custom.htm

Make sure to really look through that site. It's got a ton of information on this stuff, and there is even an emulator you can manually put your numbers into and see the results.

Good luck
Rick
There are 10 types of people in this world. Those that understand binary, and those that don't.

toxibunny
Posts: 1382
Joined: Thu Aug 18, 2011 9:21 pm

Re: lcd custom characters

Thu Oct 24, 2013 12:25 am

http://www.youtube.com/watch?v=8qd3EqZ15Jg

...I can understand rapidly updating the 8 custom characters to show a large animation, but it seems like this guy's also doing some trick with the flashing backlight to do the impossible and double that! O.o
note: I may or may not know what I'm talking about...

bobleichhardt
Posts: 5
Joined: Tue Oct 01, 2013 8:08 am

Re: lcd custom characters

Thu Oct 24, 2013 2:40 pm

Thanks all for your help, the information was great - I think I have it sorted.

What I have done is added a new method to the 12clibraries i2c_lcd module:

Code: Select all

        def customChar(self, charNo, pixels):  #charNo is the character number 0-7 and pixels is a list of 8 character data
                self._write(((charNo*8)+64), True)         #change charNo to the CGRAM address and send as a command
                for p in pixels:
                        self._write(int(p), False)                 #send each element of the pixels list as data
                self.home()         #send the home command because otherwise the next character misses the screen!
(the file I added this to on my Raspian pi was /usr/bin/i2clibraries/i2c_lcd.py and it needed root to edit - I mucked around for ages editing the one in my home directory to no avail... doh!)

It can then be used like this in my script:

from i2clibraries import i2c_lcd

lcd = i2c_lcd.i2c_lcd(0x27,1, 2, 1, 0, 4, 5, 6, 7, 3) #configure and enable display
lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)

lcd.customChar(0, [0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x04]) # I find it easier to picture where the pixels are with hex
lcd.customChar(1, [0x00, 0x0e, 0x0a, 0x0a, 0x0a, 0x0e, 0x00, 0x00]) # Only the right 5 bits are used.
lcd.customChar(2, [0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00]) # These characters are a bit random :)
lcd.customChar(3, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f])
lcd.customChar(4, [0x04, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x00, 0x00])
lcd.customChar(5, [0x04, 0x04, 0x04, 0x1f, 0x10, 0x10, 0x10, 0x10])
lcd.customChar(6, [0x1f, 0x01, 0x1f, 0x10, 0x1f, 0x01, 0x1f, 0x10])
lcd.customChar(7, [1, 2, 3, 4, 5, 6, 7, 8]) #Integers work too. The order is from top row to bottom row of the character pixels

lcd.setPosition(2,5) #set the cursor position (the customChar method sets it to home position)

lcd.writeChar(chr(0)) #write custom characters
lcd.writeChar(chr(1))
lcd.writeChar(chr(2))
lcd.writeChar(chr(3))
lcd.writeChar(chr(4))
lcd.writeChar(chr(5))
lcd.writeChar(chr(6))
lcd.writeChar(chr(7))

Thanks again
Bob

bobleichhardt
Posts: 5
Joined: Tue Oct 01, 2013 8:08 am

Re: lcd custom characters

Thu Oct 24, 2013 9:36 pm

One more thing.

Instead of editing the i2clibraries i2c_lcd file it works just as well with the method for generating new characters in the script, using the i2c_lcd command method to send the command to set the address to the CGRAM address and then using the i2c_lcd writeChar method to send the data, eg

Code: Select all

from i2clibraries import i2c_lcd

def newChar(charNo, pixels):         #Method for writing custom characters.  charNo is custom character address (0-7)
    lcd.command((charNo)*8+64)
    for n in pixels:                             #pixels is a list of data strings for the new character (8)
        lcd.writeChar(chr(n))
    lcd.home()
    
lcd = i2c_lcd.i2c_lcd(0x27,1, 2, 1, 0, 4, 5, 6, 7, 3)
lcd.command(lcd.CMD_Display_Control | lcd.OPT_Enable_Display)

newChar(0, [0x1f, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x04])
newChar(1, [0x00, 0x0e, 0x0a, 0x0a, 0x0a, 0x0e, 0x00, 0x00])
newChar(2, [0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00])
newChar(3, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f])
newChar(4, [0x04, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x00, 0x00])
newChar(5, [0x04, 0x04, 0x04, 0x1f, 0x10, 0x10, 0x10, 0x10])
newChar(6, [0x1f, 0x01, 0x1f, 0x10, 0x1f, 0x01, 0x1f, 0x10])
newChar(7, [1, 2, 3, 4, 5, 6, 7, 8])

lcd.setPosition(1,0)
lcd.writeString('Custom: ')

lcd.writeChar(chr(0x00))
lcd.writeChar(chr(0x01))
lcd.writeChar(chr(0x02))
lcd.writeChar(chr(0x03))
lcd.writeChar(chr(0x04))
lcd.writeChar(chr(0x05))
lcd.writeChar(chr(0x06))
lcd.writeChar(chr(0x07))

Return to “Python”