Boezelman
Posts: 40
Joined: Sun Aug 05, 2012 3:25 pm

PCF8574 + 20x4 LCD help

Tue Oct 09, 2012 7:15 pm

Hi guys,

I "upgraded" my 16x2 LCD (which I controlled with a PCF857) to this -->20x4 LCD with I2C controller

But I can't figure out how to change the pins in the python program (I really don't understand the -->PCF8574 datasheet)

My "old LCD" uses this pin-out

Code: Select all

	P0 -  - D4
	P1 -  - D5	
	P2 -  - D6
	P3 -  - D7	
	P4 -   - RS
	P5 -   - R/W	
	P6 -   - E	
My new LCD uses this pin-out

Code: Select all

	P0 -  - RS
	P1 -  - RW	
	P2 -  - E
	P4 -  - D4 	
	P5 -   - D5
	P6 -   - D6
	P7 -   - D7		
The thing I don't understand is, where and how are the pins defined and how do I change them to my needs?

Old program that worked great with the 16x2 LCD

Code: Select all

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
	'''
	pinout is as follows: PCF8574 - HD44780
	P0 - LCD11 - D4
	P1 - LCD12 - D5	
	P2 - LCD13 - D6
	P3 - LCD14 - D7	
	P4 - LCD4  - RS
	P5 - LCD5  - R/W	
	P6 - LCD6  - E	
	'''
	def __init__(self, addr, port):
		self.lcd_device = i2c_device(addr, port)
		self.lcd_device.write(0x03)
		self.lcd_strobe()
		sleep(0.0005)
		self.lcd_strobe()
		sleep(0.0005)
		self.lcd_strobe()
		sleep(0.0005)
		self.lcd_device.write(0x02)
		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)

	# clocks EN to latch command
	def lcd_strobe(self):
		self.lcd_device.write((self.lcd_device.read() | 0x40))
		self.lcd_device.write((self.lcd_device.read() & 0xbF))

	# write a command to lcd
	def lcd_write(self, cmd):
		self.lcd_device.write((cmd >> 4))
		hi= self.lcd_device.read()
		self.lcd_strobe()
		self.lcd_device.write((cmd & 0x0F))
		lo= self.lcd_device.read()
		self.lcd_strobe()
		self.lcd_device.write(0x0)
	#	print 'cmd',cmd,hi,lo

	# write a character to lcd (or character rom)
	def lcd_write_char(self, charvalue):
	#		print "char",charvalue
			self.lcd_device.write((0x10 | (charvalue >> 4)))
			self.lcd_strobe()
			self.lcd_device.write((0x10 | (charvalue & 0x0F)))
			self.lcd_strobe()
			self.lcd_device.write(0x0)

	# 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(0x10)
		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)

Serac
Posts: 124
Joined: Wed Jul 18, 2012 2:49 pm

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 12:17 am

Code: Select all

	# clocks EN to latch command
	def lcd_strobe(self):
	      self.lcd_device.write((self.lcd_device.read() | 0x04))
	      self.lcd_device.write((self.lcd_device.read() & 0xFB))

	# write a command to lcd
	def lcd_write(self, cmd):
		self.lcd_device.write((cmd & 0xF0))
		hi= self.lcd_device.read()
		self.lcd_strobe()
		self.lcd_device.write((cmd << 4))
		lo= self.lcd_device.read()
		self.lcd_strobe()
		self.lcd_device.write(0x0)
	# write a character to lcd (or character rom)
	def lcd_write_char(self, charvalue):
			self.lcd_device.write((0x01 | (charvalue & 0xF0)))
			self.lcd_strobe()
			self.lcd_device.write((0x01 | (charvalue << 4)))
			self.lcd_strobe()
			self.lcd_device.write(0x0)
...Should get you close - The main difference is the data is transmitted in the upper nibble whilst the control lines are on the lower nibble with your new module. So it is just a case of shifting the data in the other direction and swapping the hexadecimal numbers round.

Boezelman
Posts: 40
Joined: Sun Aug 05, 2012 3:25 pm

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 6:14 pm

Thanks for your replay and code! I will try it soon!

The thing that's really bugging me is:

I thought I'd only needed to change the hexadecimal adresses of the PCF8574 to match the connection on my new LCD (P0,1,2,3,4,5,6,7) But I can't figure out where the addresses are defined in the python code.
And I can't find / don't understand the datasheet to see the addresses of P0,1,2,3,4,5,6,7.

What i'm trying to figure out is:

for example:

Code: Select all

Pin       Input        Output
P0        0x3F         0x33
P1        0x8E         0x12
etc.
etc.

Boezelman
Posts: 40
Joined: Sun Aug 05, 2012 3:25 pm

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 6:56 pm

Boezelman wrote:Thanks for your replay and code! I will try it soon!
Your code work great, thanks.
only problem is that the backlight LED goes out when I run the code!?!
So maybe it's connected to 1 of the PCF8574 pins?

* well almost great, the lcd stay blank sometime and also showing some strange characters..

But hey, better then nothing right?! :)
Last edited by Boezelman on Wed Oct 10, 2012 7:13 pm, edited 1 time in total.

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

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 7:11 pm

Boezelman wrote:Thanks for your replay and code! I will try it soon!

The thing that's really bugging me is:

I thought I'd only needed to change the hexadecimal adresses of the PCF8574 to match the connection on my new LCD (P0,1,2,3,4,5,6,7) But I can't figure out where the addresses are defined in the python code.
And I can't find / don't understand the datasheet to see the addresses of P0,1,2,3,4,5,6,7.
Firstly you are giving things the wrong names so it will be confusing to match anyuthing in datasheet or code.

PCF89574 has an I2C address to slect it on the I2C bus of which 3 bits match the A0-A2 pins on the PCF8574.

The data I/O pins on the PCF8574 have names P0 to P7 matching data bit 0 to data bit 7 in a data byte sent on I2C to the PCF8574, when it is addressed.
Boezelman wrote:]What i'm trying to figure out is:

for example:

Code: Select all

Pin       Input        Output
P0        0x3F         0x33
P1        0x8E         0x12
etc.
P0 is bit 0 has value of 1 (almost any number base)
P1 is bit 1 has value of 2
through to
P6 is bit 6 has value of 64 (hex 0x40)
P7 is bit 7 has value of 128 (hex 0x80)

What each data bit represents to the outside world is down to how the PCF8574 is wired up.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

Boezelman
Posts: 40
Joined: Sun Aug 05, 2012 3:25 pm

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 7:31 pm

Thanks for you explanation!

So if i get it right:

Code: Select all

            7 - 128 - 0x80
            6 - 64   - 0x40
            5 - 32   - 0x20
            4 - 16   - 0x10
            3 - 8     - 0x08
            2 - 4     - 0x04
            1 - 2     - 0x02
            0 - 1     - 0x01
Would complete the list?!

One step closer in "understanding" the code rather than just "copy/past" and go: Whow it works! :)

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

Re: PCF8574 + 20x4 LCD help

Wed Oct 10, 2012 8:12 pm

Yes standard bit weightings for binary to deciaml and hexadecimal.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

ufux
Posts: 2
Joined: Sun Jul 28, 2013 12:57 pm

Re: PCF8574 + 20x4 LCD help

Sun Jul 28, 2013 1:01 pm

Even this post is a little bit old ... I started with the code and the hints here, but I thought there is space for improvement. So I double checked the documentation of the HD44780U controller and modified the code. It works with and without backlight and it also allows to not double initialize after the display had been powered once. Check it out here: https://gist.github.com/ufux/6094977

Hope this is helpful.

Ufux

User avatar
dentex
Posts: 180
Joined: Sun May 20, 2012 7:58 am
Location: Italy
Contact: Website

Re: PCF8574 + 20x4 LCD help

Sun Oct 02, 2016 8:05 pm

ufux wrote:Even this post is a little bit old ... I started with the code and the hints here, but I thought there is space for improvement. So I double checked the documentation of the HD44780U controller and modified the code. It works with and without backlight and it also allows to not double initialize after the display had been powered once. Check it out here: https://gist.github.com/ufux/6094977

Hope this is helpful.

Ufux
Thank you very much.
It works really good. :D
One of my projects with the Raspberry Pi:
--------------------------------------------------------
(Raspberry) Pi Aquarium Controller: https://github.com/dentex/piac
...and its dashboard: https://freeboard.io/board/O17ACD

Return to “Python”

Who is online

Users browsing this forum: elParaguayo and 18 guests