i2c LCD using chinese piggy-back convertor board.

cactusface

Senior Member
Hi All,
Sorry but I've been playing with the Arduino for a time... And find this very useful, it's a tiny PCB containing a chip to control and LCD module via i2c so only 4 wires and 2 of them are power, what a saving on I/O Pins. It just solders in place on the LCD header/strip, they vary but this one is addressed at 0x27. So what I need to know is how do I send data and or text to this? is it just like writing to an EEprom? or a DS1307?

If you have done it or still doing it! I would like to have your advice and ideas.. Here's a couple of pictures..

Regards

Mel.
 

Attachments

Rick100

Senior Member
Hello Mel,

You use the I2C commands to send data to it. Did you use it with an Arduino? If so what pins were declared for the Arduino library for the Enable, RW, RS, BL, and data lines. You need to know these to control the lcd. Not all of them are wired the same. Some have the data lines on the low nibble of the IO expander and the control lines on the high nibble. Some are opposite. The lcd address will be $4E on the Picaxe because it shifted left 1 bit. Here's a recent thread about an I2C display.
http://www.picaxeforum.co.uk/showthread.php?25964-I2C-LCD-Display

Good luck,
Rick
 

westaust55

Moderator
This appears to be the same module you started a thread about in Nov 2013:
http://www.picaxeforum.co.uk/showthread.php?24781-i2c-LCD

Did the informaiton at post 14 help?
that linked to this thread: http://www.picaxeforum.co.uk/showthread.php?23471&p=233713#post233713
From the photos above it is the Philips IO Expander chip.
Similar to but not exactly the same as the photo I provided at post 3 in the past thread.

Without advising us exactly which IO Expander pin is used for which LCD function and what the 3 i2c slave address pins are set to (pulled high or low)
we can only point you in a direction but no-one can give guaraneteed working code as there are several variants of these i2c interface boards.
 

Rick100

Senior Member
Hello Mel,

If this is the same display you had in the thread westaust55 referred to, then this code should drive it.

Code:
'drive 8574 based I2C lcd display in 4 bit mode
'D7- D4 of display mapped to P7-P4 of 8574
'changed pules enable line to single  hi2cout command
'removed edelay constant
'removed other 'pause 10'delays between hi2cout commands
'works up to 32 MHz / remember to use I2CSLOW_32 
'put BL = 1 after InitLcd so it won't be reset


#picaxe 08m2

'***************************************************************
'---------MAKE SURE LCD_ADR IS CORRECT--------------------------
'***************************************************************
'Symbol LCD_ADR = $40		'I2C address of lcd
Symbol LCD_ADR = $4E		'I2C address of lcd

Symbol RSCMD = 0	' Select Command register
Symbol RSDAT = 1	' Select Data register

Symbol shadow = b0	'used for hi2cout shadow port
'change the following 4 symbols to match display
Symbol RS = bit0     ' bit0 of shadow register (0 = Command   1 = Data bit)
Symbol RD = bit1     ' bit1 of shadow register (0 = Write     1 = Read)
Symbol E = bit2   	' bit2 of shadow register (0 = Idle      1 = Active)
Symbol BL = bit3     ' bit3 of shadow register (backlight)

Symbol fetch = b4
Symbol char = b5
Symbol nibReg = b6
Symbol temp = b7

Symbol hunsDig = b8
Symbol tensDig = b9
Symbol onesDig = b10
Symbol counter = b11

'-------------------------------------------
	setfreq M32

	Gosub InitLcd
	
main:

	BL = 1						'backlight on

	char = 1 					'clear screen
	gosub SendCmdByte
	pause 20 					'pause after clear screen

	For fetch = 6 TO 10  	'read "Hello" from eeprom
   	Read fetch,char
      Gosub SendDataByte
	Next

'Move to line 2
	char = 192
	Gosub SendCmdByte

   For fetch = 11 To 16 	'read "World!" from eeprom
   	Read fetch,char
      Gosub SendDataByte
   Next
   
	pause 3000

	char = 1 					'clear screen
	gosub SendCmdByte
	pause 20 					'pause after clear screen

	for counter = 0 to 255
	   char = 192		  	'start of 2nd line
	   Gosub SendCmdByte
	   bintoascii counter,hunsDig,tensDig,onesDig
	   char = hunsDig
	   Gosub SendDataByte
	   char = tensDig
	   Gosub SendDataByte
	   char = onesDig
	   Gosub SendDataByte
	   'pause 500
	next

	goto main

   End

InitLcd:
	'make sure I2CSLOW_X matches clock speed
	HI2cSetup I2CMASTER, LCD_ADR, I2CSLOW_32, I2CBYTE

	shadow = %00110000 	  ' 8-bit mode
	RS  = RSCMD 				' Send to Command register
	RD = 0

	temp = shadow
	E = 1
	HI2cOut(temp,shadow,temp )  ' Pulse E 1X
	Pause 100
	HI2cOut(temp,shadow,temp )  ' Pulse E 2X
	Pause 100
	HI2cOut(temp,shadow,temp )  ' Pulse E 3X
	pause 100

	shadow = %00100000          ' 4-bit mode
	RS  = RSCMD             ' Send to Command register
	RD = 0

	temp = shadow
	E = 1
	HI2cOut(temp,shadow,temp )  ' Pulse E
	E = 0
	pause 100

	'now we can use 4 bit interface for rest of initialization
	char = $28  			' %00101000 %001LNF00   Display Format
	Gosub SendInitCmdByte

	char = $0C  			' %00001100 %00001DCB   Display On
	Gosub SendInitCmdByte

	char = $06  			' %00000110 %000001IS   Cursor Move
	Gosub SendInitCmdByte

	char = 1 	 			'Clear Screen
	Gosub SendInitCmdByte

	pause 20 					'important beacuse last command was clear screen

	Return	'InitialiseLcd

SendInitCmdByte:
	Pause 60 					' Delay 15mS

SendCmdByte:
	RS  = RSCMD 				' Send to Command register
	RD = 0						' Write to the display
       
SendDataByte:
	'high nibble of char or instruction first
	nibReg= char & %11110000	'high nibble of char
	shadow = shadow & %00001111	  	'low nibble contains control signals
	shadow = shadow | nibReg

	temp = shadow
	E = 1
	HI2cOut(temp,shadow,temp )  ' Pulse E
	E = 0

	'lo nibble
	nibReg = char * 16		'low nibble of char into high nibble of nibReg
	shadow = shadow & %00001111	  'low nibble contains control signals
	shadow = shadow | nibReg

	temp = shadow
	E = 1
	HI2cOut(temp,shadow,temp )  ' Pulse E
	E = 0
	RS  = RSDAT 				' Send default to Data register

	Return	'SendDataByte , SendCmdByte , SendInitCmdByte

	Eeprom 6,("Hello")
        Eeprom 11,("World!")

It uses the following connections:
LCD---8574
D7----P7
D6----P6
D5----P5
D4----P4

BL----P3
EN----P2
RW----P1
RS----P0

I2C address $4E

It should work on any of these displays that have the 8574 chip and use P7-P4 to drive the data lines. If the control lines are mapped differently, it would require setting the address symbol and control bit symbols at the top of the program. At 32 MHz it will print the numbers 000 - 255(768 characters) plus the cursor control commands in under 3 seconds(measured with stopwatch). That includes the bintoascii conversion.
I tested Hippy's code in post 9 of this thread. It also works if you set the address and bit symbols.
http://www.picaxeforum.co.uk/showthread.php?23471&p=233713#post233713

Good luck,
Rick
 

cactusface

Senior Member
@Rick, Thanks for the link, useful. Yes I do in fact have 2 of these while different in pcb layput, they both work at 0x27, but they do vary as you say! They also seem to use 2 very simular Philips chip as the I/O expanders.

@Westaust The Arduino library deals with it like this LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); // Set the LCD I2C address They have a bit of code, an i2c address finder, that once found the display, then displays details as per picture attached. Did'ent even remember posting that other thread, must be my age!!

@erco, yes the Arduino has a library for driving this and in general this is a lot easier then with a picaxe with simple comands to control the LCD (regardless of being i2c, 4 or 8 bit, etc) like lcd.setCursor(x,y), lcd.clear and lcd.print.

Regards

Mel.

LCD-1_2.jpg
 

AlbrechtMe

New Member
Nice, Rick100: this solution is working with
http://www.ebay.de/itm/Iic-I2c-Twi-Sp-I-Serial-Interface-Blue-Lcd-Module-1602-16X2-Character-Display-/401269171490
I first detected the I2C address by a litte self made I2C scanner:
#terminal 4800
main: ; waiting for terminal
for b0=10 to 1 step -1
sertxd("Noch ",#b0,"s...",cr,lf)
pause 1000
next

; scanning
b0=%00010000; start search with address = 16
sertxd("Start bei ",#b0,cr,lf)
for b0=b0 to %11101111 step 2
hi2csetup i2cmaster,b0,i2cslow,i2cbyte
hi2cin 0,(b1)
if b1<>$FF then
sertxd(#b0," ok",cr,lf)​
endif
next
dec b0
sertxd("Ende bei ",#b0,cr,lf)
This resulted in
Start bei 16
126 ok
Ende bei 239
So I set at the beginng of your code:
Symbol LCD_ADR = 126
I tried several other programs/demos with this address 126, but (out of some flashing, blinking or empty full black line) they could not talk with my cheap chinese ebay display.

 

Rick100

Senior Member
Hello AlbrechtMe,

Glad to hear it was useful. The address seems correct for an PC8574A with all the address lines tied high. These Ebay displays come wired to the PC8574 in different ways so the Arduino people have a program to help find the configuration. Most people run away from these when they see the code overhead. I prefer the 1 wire serial displays for simplicity or a parallel interface for speed, although the i2c interface is not as slow as it would seem. I hope your enjoying Picaxe adventures.

Good luck,
Rick
 

AlbrechtMe

New Member
Well, I don't fear complicated subroutines, as long as they do their work...
Here another display, now 20x4, working too:
http://www.ebay.de/itm/BLAU-IIC-I2C-TWI-SP-I-Serial-Interface2004-5V-2004-Character-LCD-Modul-LCD2004-/201802907432

Line 3 of this display starts at $94 and line 4 at $D4.

Self made characters are created as usual, but are called different on these displays: Just send 0, 1, 2, .. as DATA, not as Command.
I have not tested, how much custom characters can be stored in the display.
So it is much easier to combine Text with custom symbols (they are just 'special' characters with low asci values).
 

AllyCat

Senior Member
Hi,

I have not tested, how much custom characters can be stored in the display.
Those displays normally have only 8 "User-Defined" characters, but still quite useful for some simple graphics. Rows 3 and 4 of these displays are normally arranged as a "continuation" of rows 1 and 2 respectively. There are other relevant threads on the forum, perhaps easiest found with the search terms 1602 or 2004.

The 4-bit parallel mode using I2C is quite fast (probably not much slower than sending characters serially at 2400 baud to a separate PICaxe) so is a very satisfactory solution if the display is sold with an I2C expander "backpack" already attached. Not directly related, but I have been discussing some similar issues in this thread.

Cheers, Alan.
 
Top