PDA

View Full Version : Interfacing with Arduino I2C LCD



norohs
- 27th October 2012, 18:56
I bought one of these Arduino I2C 20x4 LCD modules (http://dx.com/p/arduino-iic-i2c-serial-blue-backlight-lcd-2004-module-display-138616?item=54).

I got the LCD module in today. It has a slightly different back board, but that's not a bad thing. They extended the A0, A1 & A2 slave address pins out to solder/short PCB pads. This will affect the advertised address from 7 bit address of 0x27 (A0:A2 all "1"s) to a 7 bit address of 0x20 (A0:A2 all "0"s). Shorting the jumper pads ties the pin(s) to +5V. At least the modules slave addresses can be easy to change and set... that's a good thing! I was expecting to get stuck with a fixed slave address.

Again, the web site is wrong about the advertised module address - it is 0x20 as shipped, not 0x27, at least for the module they sent me.

Past that, it's using a basic I2C bi-directional I/O expander IC - PCF8574T.

Addressing the module is pretty strait forward, though the data byte being sent needs to be constructed as follows:

LCD runs in 4 bit mode - DB4 : DB7 are data bits - DB0 : DB3 are not connected at all.

Data Byte sent via I2C:

bit7 = B/L LED (0=on; 1=off)
bit6 = RS (Register Select)
bit5 = R/W (Read/Write)
bit4 = E (Enable)
bit3 = DB7 data
bit2 = DB6 data
bit1 = DB5 data
bit0 = DB4 data

All the normal commands are available under HD44780 datasheet, including 2-way communication with module.

BTW, the soldering was very good when I got it. Due to my test probe use to confirm the hookup, it looks worse then when I got it.

mackrackit
- 28th October 2012, 05:19
Do you want to share your PBP code? Or is this just an advertisement?

norohs
- 28th October 2012, 15:16
Wow, really? :rolleyes:

Seems what I've shared is at least relevant considering this question (http://www.picbasic.co.uk/forum/showthread.php?t=15120&highlight=Arduino+LCD) has been asked before... in light of the answers offered.

This is the documentation section, right?

My code is embarrassing. I'm sure anyone can read what I've posted and come up with much better code then I did. Frankly I'm not up for the criticism about how I wrote it... seeing your comments, I'm glad I didn't post it.

Heckler
- 28th October 2012, 21:08
Frankly I'm not up for the criticism about how I wrote it... seeing your comments, I'm glad I didn't post it.

Norohs,
so what was the point of your post?? Seems reasonable to me to want to see your code.

I've been around here a while and have not ever noticed "criticism" regarding someone elses code. Constructive help, yes. Suggestion on how to improve, yes.

If someone posts here with a real intent to learn and ask for help... they always get it.

You, on your third post, have managed to be rude and condecending to someone here who has over 5 thousand posts to their credit.
No the sheer number of posts does not grant someone special status. But why would you assume someone is going to criticize your code??

Strange way to start a life in a fourm :confused:

dhouston
- 28th October 2012, 21:35
You, on your third post, have managed to be rude and condecending to someone here who has over 5 thousand posts to their credit.


None of which have been critical or condescending.

rmteo
- 29th October 2012, 01:13
None of which have been critical or condescending.
Agreed +1.

mackrackit
- 29th October 2012, 01:47
Norohs,

If you have seen any of my code you will see that I am the last on to criticize others code. You original post seemed like it could have been an advertisement, if it was it should be moved to another section.

Being it was to show a project working, then posting your code could help someone. Do not worry about what your code looks like or how inefficient you think it is. As long as it works. Sometimes that is all someone needs.

norohs
- 29th October 2012, 04:29
it should be moved to another section.

Feel free to move it.

norohs
- 29th October 2012, 05:52
'ARDUINO IIC LCD GY-LCD-V1
'PIC 12F629
'PRINTS " HELLO RCG!_"
Define OSC 20
DEFINE I2C_SLOW 1
CMCON = $7
OPTION_REG.7 = 0
C VAR GPIO.1
D VAR GPIO.0
ADDR VAR BYTE
ADDR = $40
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT4
RS VAR LCD_CMD.BIT6
E=0:RS=0
LCD_CMD = 0
PAUSE 1000
LCD_CMD = $2
GOSUB LCDWRITE
GOSUB LCDWRITE
LCD_CMD = $8
GOSUB LCDWRITE
LCD_CMD = $0
GOSUB LCDWRITE
LCD_CMD = $E
GOSUB LCDWRITE
LCD_CMD = $0
GOSUB LCDWRITE
LCD_CMD = $6
GOSUB LCDWRITE
RS=1
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $48
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $45
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $4C
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $4C
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $4F
GOSUB LCDWRITE
LCD_CMD = $42
GOSUB LCDWRITE
LCD_CMD = $40
GOSUB LCDWRITE
LCD_CMD = $45
GOSUB LCDWRITE
LCD_CMD = $42
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $43
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $47
GOSUB LCDWRITE
LCD_CMD = $42
GOSUB LCDWRITE
LCD_CMD = $41
GOSUB LCDWRITE
RETURN
LCDWRITE:
I2CWRITE D,C,ADDR,[LCD_CMD]
E=1
I2CWRITE D,C,ADDR,[LCD_CMD]
E=0
I2CWRITE D,C,ADDR,[LCD_CMD]
RETURN
END

EarlyBird2
- 3rd June 2014, 06:59
Has anyone done this?

I have downloaded the Aduino LCD libraries and there are differences between them and the above code.

Demon
- 4th June 2014, 02:26
Just curious where RETURN right before LCDWRITE subroutine returns to?

Don't have one to test.

Robert

EarlyBird2
- 4th June 2014, 06:08
Just curious where RETURN right before LCDWRITE subroutine returns to?

Don't have one to test.

Robert

From what I have read the code is correct in that it will print to the LCD on a one shot basis then return to nowhere.

Return to nowhere?

Does anyone have one to test?

Having used serial LCDs which were easy to use by sending ascii commands and data using serout2 these look very difficult. I just wonder why make something difficult when there is an easier way.

I have done more research and I believe that all Arduino I2C LCDs are not the same. I guess it depends on the manufacturers implementation and the chips used on the backpack.

Demon
- 4th June 2014, 11:55
So I'm not missing a label then, the code just isn't terminated "properly".

I kept going through it thinking I was missing something obvious.

Robert

EarlyBird2
- 5th June 2014, 07:41
I kept going through it thinking I was missing something obvious.
Robert

Not that I can see but then I always wonder if I am missing something whether it is obvious or not.



LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $48
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $45
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $4C
GOSUB LCDWRITE


I have been trying to work out what the $44 do because they are not printed on the screen.

Demon
- 5th June 2014, 14:47
Can't find info on $44, and can't see what's in this zip on my phone:

https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

I'd be curious to see all the stuff in version 1.2.1.

Robert

EarlyBird2
- 5th June 2014, 15:23
Can't find info on $44, and can't see what's in this zip on my phone:

https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

I'd be curious to see all the stuff in version 1.2.1.

Robert

Compare this code with Darrel's the one obvious issue is that the LCD is in 4 bit mode which requires the upper nibble and lower nibble to be sent separately. One other concern is that of setting the RS bit for data mode which is done once after initialisation. Does this not need doing every time a data nibble is sent?

EarlyBird2
- 5th June 2014, 16:00
Is it pure coincidence that all the upper nibbles are $4?

doctordhd
- 4th May 2015, 13:51
I believe this may be my first post to this forum...

Has anyone figured more of this out? I finally got my I2C serial adapter for the 1602 LCD to do something at least.

It was indeed very helpful to see the original code posted. Somehow my default address is $40.

When I use the code provided, I do get the display to light up and display "HELLO RCG! but when I try to change the initials to DHD, using the hex codes for D = $44, H=$48, and D=$44, I get THD in the display.

I am also looking for a bit more help with the control characters, and why the LCDWRITE routine needs 3 i2cwrite commands.

Thanks from noob Dave

EarlyBird2
- 5th May 2015, 07:43
There is information here.

http://www.picbasic.co.uk/forum/showthread.php?t=19222

richard
- 5th May 2015, 13:49
and here if you have pbp3
http://support.melabs.com/threads/986-I2C-PCF8574-20x4-LCD

doctordhd
- 5th May 2015, 14:47
Great, thank you. Lots of information in those posts.

doctordhd
- 23rd May 2015, 22:53
Hmm, I am still having difficulty with this even after reading the above referenced threads.

I am working with PBP 3.0.7.0 and a pic 12F629. I am able to get the code writen by norohs (above) to work but I am having difficulty figuring it all out so that I can modify it for my own use.

Basically, I'd like to send some data and or ascii from my 12F629 to my LCD1602 via the I2C "adapter".

Can someone give me a bit more guidance?

richard
- 24th May 2015, 01:18
you might get something from this
http://support.melabs.com/threads/1075-I2C-to-LCD

or tell us more on what your trying to achieve and post your code (in code tags)

EarlyBird2
- 24th May 2015, 11:31
I also found this code written by norohs difficult to work out and eventually I decided that it works more by accident than design and that there has to be a better way of doing this. This is what I worked out.

The LCD works in four bit mode which makes every byte sent a four bit control nibble plus a nibble of data. To send a byte of data two bytes have to be sent consisting of a control nibble plus high data nibble then control nibble plus low data nibble.

To send "H" which is $48

requires two LCDWRITE instructions

LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $48
GOSUB LCDWRITE

In each instruction the first 4 after the $ sets the R/W bit to write and $48 is made up from the 4 and 8 in red.

and "D" would be

LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE

and to print "DHD" would be

LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $48
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE
LCD_CMD = $44
GOSUB LCDWRITE

Looking at the LCDWRITE

LCDWRITE:
I2CWRITE D,C,ADDR,[LCD_CMD]
E=1
I2CWRITE D,C,ADDR,[LCD_CMD]
E=0
I2CWRITE D,C,ADDR,[LCD_CMD]
RETURN

each command is sent three times with E=0 then E=1 then E=0 which I think is an error, the first line is not needed.

LCDWRITE:
E=1
I2CWRITE D,C,ADDR,[LCD_CMD]
E=0
I2CWRITE D,C,ADDR,[LCD_CMD]
RETURN

but you can test this.

Why send it twice? On the LCD with the E bit set to 1 the data is loaded into a buffer and E has to change from 1 to 0 for the data to be transferred to the screen which is why the second instruction is required.

I decided to look for a better solution as I was not totally confident that the above was correct.

Darrel Taylor came to the rescue here

http://support.melabs.com/threads/986-I2C-PCF8574-20x4-LCD

As you can see from this not all Arduino LCDs are wired the same. The control and data nibbles can be either data/control or control/data.

johncouture worked this out for us in the thread above.

doctordhd
- 25th May 2015, 14:28
EarlyBird2, your reply has helped me understand this a bit more. I was able to get the norohs code to work without the initial I2CWRITE command as you suggested.

Darrel Taylor's program seems to be a work of art but I think with the INCLUDE, it's just too big for my 12F629 as I am getting, "Unable to fit variable" errors.

I have been able to use the lcdout command to write data to my LCD1602. My goal is to do the same with the i2cwrite command.

I will try to get a better understanding of how to send the control commands by studying Darrel's code.

I think what I am trying to figure out is...

Hey, you need to initialize the LCD to nibble / 4 bit mode by sending I2CWRITE commands with code $xx, ...
then to turn on the backlight you need to I2CWRITE $yy (mabe needs 2 commands for high and low nibbles)
to send data you need to I2CWRITE highNibble, then I2CWRITE lowNibble...

I will reread the thread you referenced, http://support.melabs.com/threads/98...F8574-20x4-LCD

richard
- 25th May 2015, 21:49
Darrel Taylor's program seems to be a work of art but I think with the INCLUDE, it's just too big for my 12F629 as I am getting, "Unable to fit variable" errors.


I did not realise you were using a pic12f the dt code won't work on those chips because




ARRAYWRITE is not supported on 12-bit core PIC MCUs due to RAM and stack

constraints

doctordhd
- 26th May 2015, 13:45
I believe Darrel Taylor was using a 12F1822. Doesn't that have the same "bit core" as my 12F629?

According to the Microchip datasheet on the 12F1822,

"This family of devices contains an enhanced mid-range 8-bit CPU core"

doctordhd
- 26th May 2015, 18:53
The PIC numbering system was getting me confused so I spoke to an engineer at Microchip and this is what I was told...

The 12 in the 12F629 means it is an 8 pin chip. (I didn't ask why 12 means 8 or why they just didn't just call it an 8Fxxx)

The 6 after the F means that it has a 14 bit memory core, since anything other (? # > 5) has a 14 bit memory core.

A 12F5xx chip would be an 8 pin chip with a 12 bit memory core...

So it does not seem to a 12-bit core problem but rather an overall memory problem.

The 12F629 has 1k x 14 memory (there's that 14 bit core again), where as
the 12F1822 has 2K 14 memory.

I ordered some 12F1822s to see if I can get Darrel's program working.

doctordhd
- 26th May 2015, 18:56
Here is the thread in which I believe Darrel was using a 12F1822.

Post #3

http://support.melabs.com/threads/986-I2C-PCF8574-20x4-LCD

doctordhd
- 26th May 2015, 19:47
Hmmm, unfortunately, I just figured out that my Silver version of PBP3.0 doesn't support the 12F1822...

richard
- 27th May 2015, 00:04
a pic12f1xxx is an enhanced midrange device . they have twice the stack capacity of a 12f6xx device , apart from more memory etc ....

doctordhd
- 28th May 2015, 05:33
Thanks to everyone that helped out.

I have gotten a modified version of Darrel's code to run on a 12F683 which has 2K of memory. :D

I am using an LCD 1602 and I don't see any Jumping Jacks.



; Filename : 632-I2C-LCD for 12F683.pbp
; Author : Darrel Taylor
; Created : Mon Feb 24 2014
; : May 27, 2015 adapted for the 12F683
; Processor : PIC12F683
; Compiler : PicBasic Pro 3.0.7.x or higher
; Description : Uses PCF8574 Port expander to interface with HD44780 LCD
;

;----[Oscillator Setup]---------------------------------------------------------
define OSC 20
define I2C_SLOW 1

;----[Aliases]------------------------------------------------------------------
SDA VAR GPIO.0 ; I2C Data pin
SCL VAR GPIO.1 ; I2C Clock Pin

;----[Initialize Hardware]------------------------------------------------------
ANSEL = 0 ; Make Analog inputs digital

';----[Setup LCD using PCF8574 Port Expander]------------------------------------
LCD_Addr CON $40 ; A0, A1, A2 grounded
true con 1
false con 0
INCLUDE "LCD_PCF8574.pbp" ; Init LCD using I2C and PCF8574

;----[Variables]----------------------------------------------------------------
LoopCount VAR BYTE
CustChar VAR BYTE

;----[Program Start]------------------------------------------------------------
Backlight = 0 ; Turn on LCD Backlight
LoopCount = 0
ARRAYWRITE LCD_Buff,[" LCD PCF8574"] : LCD_WriteBuff

;----[Custom Characters]-(Jumping Jacks)----------------------------------------
ARRAYWRITE LCD_Buff,[$FE,$40,$00,$04,$0A,$04,$0E,$15,$0A,$11]:LCD_WriteBuff ' #0
ARRAYWRITE LCD_Buff,[$FE,$48,$00,$04,$0A,$04,$1F,$04,$0A,$0A]:LCD_WriteBuff ' #1
ARRAYWRITE LCD_Buff,[$FE,$50,$04,$0A,$15,$0E,$04,$0A,$0A,$00]:LCD_WriteBuff ' #2

;----[Main Program Loop]--------------------------------------------------------
Main:
ARRAYWRITE LCD_Buff,[$FE,$C0,"Count = ",DEC LoopCount," "] : LCD_WriteBuff
PAUSE 200
LoopCount = LoopCount + 1

CustChar = LoopCount//3 ; Jumping Jacks Sequence
ARRAYWRITE LCD_Buff,[$FE,$9D,CustChar] : LCD_WriteBuff
GOTO Main

doctordhd
- 28th May 2015, 05:42
Commented out the lines...

ARRAYWRITE LCD_Buff,[" LCD PCF8574"] : LCD_WriteBuff

and

ARRAYWRITE LCD_Buff,[$FE,$C0,"Count = ",DEC LoopCount," "] : LCD_WriteBuff

Changed the $9D to a $C0 in

ARRAYWRITE LCD_Buff,[$FE,$C0,CustChar] : LCD_WriteBuff ' $C0 was $9D

and now the little guy is doing Jumping Jacks in the lower left hand corner.

Thanks again!

n0yox
- 26th February 2017, 20:02
I am trying to make this code work with a 16F629A and all I get is a blinking back light with the modified code below.I am probably missing something simple?

Thanks,

; Filename : Test_LCD_PCF8574.pbp
; Author : Darrel Taylor
; Created : Mon Feb 24 2014
; Processor : 16F629A
; Compiler : PicBasic Pro 3.0.6.x or higher
; Description : Uses PCF8574 Port expander to interface with HD44780 LCD
;

;----[16f629A Hardware Configuration]-------------------------------------------
#config
__config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_ON & _BODEN_OFF
#endconfig



;----[Aliases]------------------------------------------------------------------
SDA var porta.7
SCL var porta.6
;----[Initialize Hardware]------------------------------------------------------
CMCON = 7 'CHANGES PORTA TO DIGITAL
;----[Setup LCD using PCF8574 Port Expander]------------------------------------
LCD_Addr CON $7E
INCLUDE "LCD_PCF8574.pbp" ; Include LCD module for PCF8574

;----[Variables]----------------------------------------------------------------
LoopCount VAR BYTE
CustChar VAR BYTE

;----[Program Start]------------------------------------------------------------
Backlight = 0 ; Turn on LCD Backlight
ARRAYWRITE LCD_Buff,[" LCD PCF8574"] : LCD_WriteBuff
LoopCount= 0

;----[Custom Characters]-(Jumping Jacks)----------------------------------------
ARRAYWRITE LCD_Buff,[$FE,$40,$00,$04,$0A,$04,$0E,$15,$0A,$11]:LCD_WriteBuff ' #0
ARRAYWRITE LCD_Buff,[$FE,$48,$00,$04,$0A,$04,$1F,$04,$0A,$0A]:LCD_WriteBuff ' #1
ARRAYWRITE LCD_Buff,[$FE,$50,$04,$0A,$15,$0E,$04,$0A,$0A,$00]:LCD_WriteBuff ' #2

;----[Main Program Loop]--------------------------------------------------------
Main:
ARRAYWRITE LCD_Buff,[$FE,$C0,"Count = ",DEC LoopCount," "] : LCD_WriteBuff
PAUSE 200
LoopCount = LoopCount + 1

CustChar = LoopCount//3 ; Jumping Jacks Sequence
ARRAYWRITE LCD_Buff,[$FE,$C0,CustChar] : LCD_WriteBuff
GOTO Main

n0yox
- 26th February 2017, 22:15
I did delete these two lines

ARRAYWRITE LCD_Buff,[" LCD PCF8574"] : LCD_WriteBuff

ARRAYWRITE LCD_Buff,[$FE,$C0,"Count = ",DEC LoopCount," "] : LCD_WriteBuff

and Change this line

ARRAYWRITE LCD_Buff,[$FE,$C0,CustChar] : LCD_WriteBuff ' $C0 was $9D

richard
- 26th February 2017, 22:47
16F629A ?
might you mean 12f629 ?

if so you need to set the " lcd " pins to digital

n0yox
- 26th February 2017, 23:34
Sorry, I should have said 16F628A. I did set my pins as digital? I want to display data from my program but that seems far away at this point?? I cut the program down to the below lines and I get a custom character and a blinking cursor the backlight stays on. I guess that is progress ?

Thank You!

;----[16f628A Hardware Configuration]-------------------------------------------
#config
__config _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_ON & _BODEN_OFF
#endconfig


SDA var porta.7
SCL var porta.6
;----[Initialize Hardware]------------------------------------------------------
CMCON = 7 'CHANGES PORTA TO DIGITAL
;----[Setup LCD using PCF8574 Port Expander]------------------------------------
LCD_Addr CON $7E
INCLUDE "LCD_PCF8574.pbp" ; Include LCD module for PCF8574

ARRAYWRITE LCD_Buff,[$FE,$50,$04,$0A,$15,$0E,$04,$0A,$0A,$00]:LCD_WriteBuff ' #2


Main:

GOTO Main

richard
- 27th February 2017, 00:41
there is more info here . note the slightly differing versions of the include
INCLUDE "LCD_PCF8574.pbp" ; Include LCD module for PCF8574
INCLUDE "LCD_PCF8574a.pbp" ; Include LCD module for PCF8574

http://support.melabs.com/threads/1075-I2C-to-LCD?highlight=PCF8574
http://support.melabs.com/threads/1072-Using-Picbasic-with-I2C-LCD?highlight=PCF8574
ps
LCD_Addr CON $7E is way different to addr used in above threads

n0yox
- 27th February 2017, 01:31
Richard thank you for your help.

I have read most of the threads but will read them again. I will find and download both version of the include. On Arduino this is the Initialization for my display the 3F turns into 7E when you shift the bits one to the left.

"LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE)"

I have used serial lcd displays in the past with no issues. So far I am not a fan of this i2c version. I think someone is missing a market for easy to use i2c displays?

Thanks again!

richard
- 27th February 2017, 02:36
"LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE)"




interpreted as [( 7bit_addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY) ]

the PCF8574 datasheet indicates the 7bit addr range is 0x20--0x27

0x3f is not valid afaik.


default with a0:2 open = 7bit_addr of 0x27 , pbp addr would be $4e

n0yox
- 27th February 2017, 03:39
interpreted as [( 7bit_addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY) ]

the PCF8574 datasheet indicates the 7bit addr range is 0x20--0x27

0x3f is not valid afaik.


default with a0:2 open = 7bit_addr of 0x27 , pbp addr would be $4e

I see on the data sheet for the PCF8574 you are right I used the Arduino i2c address finder to get the address. I have tried it using the 4E address and get nothing however with the 7E I do get some response from the display. I am still trying to understand the Initialization string and how to use it if you can offer guidance it would be appreciated. This is a little beyond my current ability but I will continue to try to learn and get this project going.

Thank You!

richard
- 27th February 2017, 04:22
did it work with the Arduino sketch ?
if so what was the init command [I assume a0:2 are open]
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) or LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
afaik there is at least two types there may be others.
if the addr is not between 0x20 and 0x27 then its a going to be different animal and the include files may need modification

would not hurt to trace out the cct and see what bits are wired to rs,e,rd/wr etc

n0yox
- 27th February 2017, 04:36
did it work with the Arduino sketch ?
if so what was the init command [I assume a0:2 are open]
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE) or LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
afaik there is at least two types there may be others.
if the addr is not between 0x20 and 0x27 then its a going to be different animal and the include files may need modification

would not hurt to trace out the cct and see what bits are wired to rs,e,rd/wr etc


This is the init command from my working Arduino sketch "LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE)" all three jumpers are open A0:2.

Thanks!

richard
- 27th February 2017, 05:35
This is the init command from my working Arduino sketch "LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE)" all three jumpers are open A0:2.


ok must be PCF8574A [addr range 0x38-0x3f]

so $7e is sounding good for an address , one of those includes should work .

another thought
you did not specify osc speed you may need
DEFINE I2C_SLOW 1

Dave
- 27th February 2017, 12:14
Make sure of the IC Type. A PCF8574 (non A) has an upper nibble of 4 for the address and the PCF5874A version has an upper nibble of 7 for the address. NXP did this to allow upto 16 devices on the I2C bus.

n0yox
- 27th February 2017, 13:36
PCF8574AT is the number on my IC.

norohs
- 29th May 2017, 01:34
Wow... I must apologize for being a butt head. I've got no excuse... I'm a butt head. That being said, here's some of the code I originally did not want to share. It's highly commented, so I hope it's more helpful than the first post. It's not the same "Hello RCG" example, but a speed test I did. It's easy to follow (at least I think it is).



'I2C LCD SPEED TEST.BAS
'BY NoRoHS
'BASIC INTERFACING WITH AN ARDUINO I2C LCD GY-LCD-V1 20x4 LCD MODULE
'TARGET PIC 12F629
'PRINTS THE NUMBERS (0 THROUGH 65535) ON THE LCD AS FAST AS IT CAN
'RESULT IS ABOUT 800CPS COM SPEED AND DISPLAY VALUE UPDATE IS 120 TIMES A SECOND
'SET PROGRAMMER FOR POWER-UP TIMER ENABLE AND HS CLOCKING (20MHZ) AND NO WDT
'352 WORDS USED
'TESTED AND CONFIRMED ON LAST SAVE/COMPILE 11/11/12
'
'
' |<============ NO NEED FOR 4.7k PULLUP RESISTORS -
' | |<======== 10K'S ARE ON ARDUINO I2C LCD MODULE'S BACKBOARD
' | |
' GND SDA SCL N/C
' __|___|___|___|__
' | 8 7 6 5 |
' > PIC12F629 |
' |__1___2___3___4__|
' | | | |
' +5V X-TAL N/C
'
' METHOD OF OPERATION:
' USES BYTE VARIABLE (NUM_GEN) TO STEP THROUGH ALL 65536 VALUES AND PRINT
' THIS NUMBER ON THE FIRST LINE. EACH NUMBER IS CONVERTED TO A
' DIGIT VALUE AND PADDED BY ADDING 48 THE RESULTS TO CONVERT IT TO ASCII.
' SINCE THIS IS AN I2C COM, THE LCD IS IN THE 4-BIT MODE AND DATA IS MOVED
' USING THE 4-BIT FORMAT, REQUIRING THE SHIFTING AND MASKING OF DATA FOR
' EACH COMMAND/VALUE SENT.
'
' THIS IS A 'CHOPPED' PROGRAM FROM ANOTHER ONE AND MOST OF THE UN-NEEDED
' PROGRAM INFORMATION HAS BEEN REMOVED, BUT SOME MAY STILL REMAIN.
'
' THE FOLLOWING HELPS EXPLAIN THE 12C TO 4-BIT MODE DATA CONVERSION PROCESS:
'
'
' vvvvvvv (FROM FIRST DEMO PROGRAM - RELEVENT - FOR REFERENCE ONLY) vvvvvvvv
' ************************************************** *************************
' * *
' * WRITING TO LCD MODULE WITH I2C FORMAT: (I2CWRITE D,C,ADDR,[LCD_DAT]) *
' * *
' ************************************************** *************************
' * *
' * *REMEMBER, EVEN THOUGH THE LCD IS SET FOR 4-BIT MODE, IN I2C WE ARE *
' * ALWAYS SENDING 8 BITS OF DATA WITH EVERY I2CWRITE COMMAND *
' * *
' * *HIGH NIBBLE MEANS THE HIGHEST 4 BITS OF A BYTE *
' * *LOW NIBBLE MEANS THE LOWEST 4 BITS OF A BYTE *
' * *
' * *LCD_DAT Variable IS A BYTE - VALUE MAYBE CODED IN HEX ($xy) *
' * FOR EASY READING *
' * *
' * *HIGH NIBBLE OR THE x IN $xy IS THE LCD MODULE FUNCTION PINS (4 BITS) *
' * *LOW NIBBLE OR THE y IN $xy IS THE LCD DATA PINS (4 BITS) *
' * *
' * *HIGH NIBBLE (FUNCTION NIBBLE)(x IN $xy) EX:($4y OR %0100yyyy) CONTAINS*
' * LCD_DAT.Bit7 = BACKLIGHT LED ON/OFF (1 = OFF, 0 = ON)(NOT A MISPRINT)*
' * LCD_DAT.Bit6 = RS (1 = DATA, 0 = INSTRUCTION) *
' * LCD_DAT.Bit5 = R/W (1 = READ, 0 = WRITE) *
' * LCD_DAT.Bit4 = E (1 = ENABLE, 0 = INHIBIT) *
' * *
' * **NOTE THAT EVERY TRANSMISSION OF DATA WILL INCLUE INFORMATION ABOUT *
' * THESE FUNCTIONS. IN THIS EXAMPLE, SETTING THESE PINS (IF NEEDED) *
' * MUST BE DONE AFTER CONSTRUCTING THE DATA TO BE SENT. MASKING AND *
' * SHIFTING NEEDED TO CONSTRUCT THE LOWER NIBBLE MEANS THESE BITS ARE *
' * ALWAYS SET TO "0" AFTER THE DATA IS CONSTRUCTED. *
' * *
' * *LOW NIBBLE (DATA NIBBLE) (THE y IN $xy) EX:($x8 OR %xxxx1000) CONTAINS*
' * LCD_DAT.Bit3 = DATA BIT 3 (MSB) *
' * LCD_DAT.Bit2 = DATA BIT 2 *
' * LCD_DAT.Bit1 = DATA BIT 1 *
' * LCD_DAT.Bit0 = DATA BIT 0 (LSB) *
' * *
' * *LCD_DAT IS SENT OUT IN TWO WRITES USING I2CWRITE(**) *
' * SEND OUT THE HIGH NIBBLE OF THE DATA FIRST: *
' * LCD_DAT = FUNCTION + DATA(HIGH NIBBLE) > I2CWRITE *
' * LATCH DATA TO LCD MODULE (ENABLE BIT SET/RELEASE) > RETURN *
' * SEND OUT THE LOW NIBBLE OF THE DATA SECOND: *
' * LCD_DAT = FUNCTION + DATA (LOW NIBBLE) > I2CWRITE *
' * LATCH DATA TO LCD MODULE (ENABLE BIT SET/RELEASED) > RETURN *
' * *
' * **NOTE: *
' * THE FIRST TIME THE MODULE IS ADDRESSED IT IS IN THE 8-BIT MODE. *
' * THESE COMMANDS MUST BE THE FIRST SENT TO THE LCD MODULE TO PUT *
' * IT IN THE 4-BIT MODE: *
' * *
' * LCD_DAT = $02 *
' * GOSUB LCDWRITE *
' * GOSUB LCDWRITE *
' * LCD_DAT = $08 *
' * GOSUB LCDWRITE *
' * *
' * *EXAMPLE: (SENDING THE CHARACTER "H") *
' * * THE CHARACTER "H" IN HEX IS $48 *
' * * SEND THE HEX '4' FIRST, THEN THE HEX '8' SECOND *
' * * EACH TIME THEY ARE SENT, THEY ARE COMBINED WITH THE FUNCTION *
' * HIGH NIBBLE (REPRESENTED AS x IN $xy) *
' * * FOR THIS EXAMPLE: FUNCTION = $4y OR %0100yyyy OR $40 (MASKED) *
' * WHICH IS LED = ON, RS = DATA, R/W = WRITE, E = INHIBIT *
' * * SO, SENDING THE HEX DATA IN THIS EXAMPLE OF "H" IS: *
' * LCD_DAT = $44, LCDWRITE, FOLLOWED BY LCD_DAT = $48, LCDWRITE *
' * * THE SUB LCDWRITE WILL SEND LCD_DAT VIA I2C TO THE ARDUINO MODULE *
' * AND THEN TOGGLE THE 'E'(ENABLE) BIT ON AND OFF TO 'LATCH' THE DATA*
' * INTO THE LCD MODULE. THIS IS WHY LCDWRITE HAS 3 I2CWRITE'S IN IT. *
' * *
' ************************************************** *************************
'
'

Define OSC 20 'USE EXTERNAL 20MHZ CRYSTAL (PINS 2 AND 3)
'DEFINE I2C_SLOW 1 'SEEMS TO WORK FASTER AND WELL IN THE FASTER MODE

CMCON = $7 'SET COMPARITOR PORTS TO DIGITAL

MASK CON $0F 'SET MASK TO %00001111 TO CLEAR TOP NIBBLE

C VAR GPIO.1 'IC PIN 6 IS SCL
D VAR GPIO.0 'IC PIN 7 IS SDA

ADDR VAR BYTE 'HOLDER FOR I2C ADDRESS
LCD_DAT VAR BYTE 'HOLDER FOR I2C LCD MODULE DATA ***SEE ABOVE ^
FCHAR VAR BYTE 'CHARICTOR OR COMMAND TO BE SENT
FTEMP VAR BYTE 'NEEDED TO MANIPULATE FCHAR AND PRESERVE FCHAR VALUE
E VAR LCD_DAT.BIT4 'HOLDER FOR ENABLE BIT (xxxE xxxx)
RS VAR LCD_DAT.BIT6 'HOLDER FOR REGISTER SELECT BIT (xRSxx xxxx)

NUM_GEN VAR WORD 'LOOP COUNTER HOLDER FOR THE VALUE TO BE DISPLAYED
NUM_GEN = 0 'MAKE SURE VALUE STARTS AT 0 (REDUNDENT)

ADDR = $40 'SET I2C 7 BIT ADDRESS $20 + A '0' FOR PBP BYTE VALUE
LCD_DAT = $00 'PRESET LCD_DAT VALUE TO 0 TO BE SURE
E = 0 'PRESET ENABLE AND REGISTER SELECT BITS TO O
RS = 0 ' (ALSO TO BE SURE)

PAUSE 1000 'WAIT 1 SECOND FOR THE LCD MODULE TO RESET

'*************** 'LCD MODULE SETUP STARTS HERE **************************

LCD_DAT = $02 'SETUP LCD MODULE FOR 4-BIT MODE
GOSUB LCDWRITE
GOSUB LCDWRITE 'NOTE: MUST SEND $02 TWICE
LCD_DAT = $08
GOSUB LCDWRITE

LCD_DAT = $00 'DISP ON, CURS ON, NO BLINK UPPER NIBBLE
GOSUB LCDWRITE '...SEND
LCD_DAT = $0E 'DISP ON, CURS ON, NO BLINK LOWER NIBBLE
GOSUB LCDWRITE '...SEND
LCD_DAT = $00 'SETUP ENTRY MODE UPPER NIBLE
GOSUB LCDWRITE '...SEND
LCD_DAT = $06 'SETUP ENTRY MODE LOWER NIBLE
GOSUB LCDWRITE '...SEND
LCD_DAT = $00 'RETURN TO HOME UPPER NIBLE
GOSUB LCDWRITE '...SEND
LCD_DAT = $02 'RETURN TO HOME LOWER NIBLE
GOSUB LCDWRITE '...SEND

'**************** LCD MAIN DISPLAY LOOP STARTS HERE *********************

MAIN:

fOR NUM_GEN = 0 TO 65535 'MAIN LOOP COUNTER AND NUMBER TO BE DISPLAYED

FCHAR = NUM_GEN DIG 4 'THE NEXT 17 LINES ARE USED TO CALCULATE THE
FCHAR = FCHAR + 48 'ASCII VALUE TO BE SENT TO THE LCD DISPLAY...
GOSUB CONSTRUCT_CHAR

FCHAR = NUM_GEN DIG 3
FCHAR = FCHAR + 48
GOSUB CONSTRUCT_CHAR

FCHAR = "," 'NO ASCII CONVERSION NEEDED FOR " , "
GOSUB CONSTRUCT_CHAR

FCHAR = NUM_GEN DIG 2
FCHAR = FCHAR + 48
GOSUB CONSTRUCT_CHAR

FCHAR = NUM_GEN DIG 1
FCHAR = FCHAR + 48
GOSUB CONSTRUCT_CHAR

FCHAR = NUM_GEN DIG 0
FCHAR = FCHAR + 48
GOSUB CONSTRUCT_CHAR

LCD_DAT = $00 'SEND UPPER NIBBLE 'RETURN TO HOME' COMMAND
GOSUB LCDWRITE
LCD_DAT = $02 'SEND LOWER NIBBLE 'RETURN TO HOME' COMMAND
GOSUB LCDWRITE

nEXT NUM_GEN 'NEXT NUMBER TO BE DISPLAYED... UNTIL 65535

PAUSE 2000 'PAUSE 2 SECONDS WHEN NUM_GEN ROLLS OVER

GOTO MAIN 'LOOP FOREVER

'************ CONSTRUCT_CHAR SUB- CONSTRUCT CHARICTERS AND SEND OUT ************

CONSTRUCT_CHAR:

FTEMP = FCHAR 'MOVE THE UPPER NIBBLE TO THE LOWER NIBBLE
FTEMP = FTEMP >> 4 ' (UPPER NIBBLE IS SENT FIRST IN 4-BIT MODE)
LCD_DAT = FTEMP 'NOTE: UPPER NIBBLE IS GOING TO BE ALL "0" ...
RS = 1 ' SO, SET THE RS TO 'DATA'

GOSUB LCDWRITE 'SEND UPPER NIBBLE TO LCD

FTEMP = FCHAR 'MASK THE UPPER NIBBLE WITH '0'
FTEMP = FTEMP & MASK ' (LOWER NIBBLE IS SENT SECOND IN 4-BIT MODE)
LCD_DAT = FTEMP 'NOTE: UPPER NIBBLE IS GOING TO BE ALL "0" ...
RS = 1 ' SO, SET THE RS TO 'DATA'

GOSUB LCDWRITE 'SEND LOWER NIBBLE TO LCD

RETURN

'************* LCDWRITE SUB - SENDING AND LATCHING DATA TO LCD *****************

LCDWRITE:

I2CWRITE D,C,ADDR,[LCD_DAT] 'LOAD DATA ONTO LCD PORT (NOT LATCHED YET)
E = 1 'SET ENABLE BIT
I2CWRITE D,C,ADDR,[LCD_DAT] 'LATCH DATA BY SETTING ENABLE PIN ON LCD MODULE
E = 0 'CLEAR ENABLE BIT
I2CWRITE D,C,ADDR,[LCD_DAT] 'CLEAR ENABLE PIN ON LCD MODULE

RETURN

'**************** 'END ********************************************

END

n0yox
- 30th May 2017, 18:53
Thank You, I will try your code. I went another direction but I will order another display just to try this. Thanks again!