PDA

View Full Version : I2C lcd ( arduino ) with PICBASIC, help



iw2fvo
- 16th May 2014, 10:52
good day,
I have to interface the I2C LCD (arduino like) using picbasic.
Any suggestion or code example please ?
Thanks in advance.
Ambrogio
IW2FVO

andybarrett1
- 16th May 2014, 13:43
Have a look at this :-

Forgive some of the comments.... Code did help me out :-)

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

iw2fvo
- 16th May 2014, 14:24
Thanks Andy for the code,

I am not a good programmer and I would like to convert the PBP program that is normally used now to EASY control the I2C display.
At the moment I am using this piece of code:

INS CON 254 ' $FE: INSTRUCTION COMMAND MODE
CLR CON 1 ' CLEAR LCD , GOTO FIRST LINE, FIRST CHARACTER
DG CON 223 ' DEG SYMBOL °
LINE1 CON 128 ' $80: GOTO LINE 1
LINE2 CON 192 ' $C0: GOTO LINE 2
LINE3 CON 148 ' $94: GOTO LINE 3
LINE4 CON 212 ' $D4: GOTO LINE 4

And then I do the the following to write my own data on it:

LCDOUT INS, LINE2, " V=", DEC2 VLT/10, ".", DEC1 VLT

How could I translate the above in I2C enviroment for displaying ?

Thanks for the assistance
Regards,
Ambrogio
IW2FVO

EarlyBird2
- 18th May 2014, 07:05
This does not look straight forward to use. How for have you got? Have you found its address for example?

richard
- 18th May 2014, 07:26
there is a similar thread on the pbp3 forum it might be worth a look
http://support.melabs.com/threads/986-I2C-PCF8574-20x4-LCD

EarlyBird2
- 18th May 2014, 07:36
this looks very interesting if you are open to alternatives.

http://www.robot-italy.com/en/lcd05-20x4-blue-serial-i2c-display-20x4-blue-background.html

I have used similar in the past and found them very easy, this one includes keypad inputs.

EarlyBird2
- 18th May 2014, 07:47
Richard's link looks to be the solution you are looking for.

iw2fvo
- 18th May 2014, 08:34
Steve,
the address is 0x20.
Thanks
Ambrogio

EarlyBird2
- 18th May 2014, 08:37
Do you need any more help?

iw2fvo
- 18th May 2014, 09:37
Thanks Steve,
I am running the PBP 2.50B version: is the Darrel include applicable to my pbp version ?
If not, what could I do ? Any possible modification to the program ?
Regards,
ambrogio
IW2FVO

EarlyBird2
- 20th May 2014, 07:08
Thanks Steve,
I am running the PBP 2.50B version: is the Darrel include applicable to my pbp version ?
If not, what could I do ? Any possible modification to the program ?
Regards,
ambrogio
IW2FVO

I can not advise you on this. Is there a pressing reason you want to use this LCD? There are LCDs that are easier to use and this one just looks like hard work to me.

iw2fvo
- 20th May 2014, 09:19
Steve,
Thanks.
I have no more pins available on the pic and I have this LCD on my hands.
Anyway, what LCD ( 20x4) with serial interface could you suggest to me ? I could try to get one.
Regards,
Ambrogio
IW2FVO

EarlyBird2
- 20th May 2014, 09:22
See post 6 above

EarlyBird2
- 20th May 2014, 09:25
Also

http://www.crownhill.co.uk/product.php?prod=1304

EarlyBird2
- 1st June 2014, 09:05
The good news is that it can be done here is some code.




'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


from this thread


http://www.picbasic.co.uk/forum/showthread.php?t=17302 (http://www.picbasic.co.uk/forum/showthread.php?t=17302)

If you need more help just ask,

EarlyBird2
- 1st June 2014, 11:27
Does this code work?

If it does we can use it as a starting point and adapt it for your use.

iw2fvo
- 1st June 2014, 18:36
Thanks Steve for the kind assistance,
I can not test the code soon : the day before yesterday my display went off. I ordered another one and will be here in two weeks tiime.
Anyway : the dispaly is exactly the same of the one shown in the images attached to the link you have sent to me.
I really think that a smart code to control the i2c LCD will be appreciate by a lot of people that use PBP.
Thanks a lot for helping.
Regards,
Ambrogio

EarlyBird2
- 1st June 2014, 18:52
Let me know when you have a replacement. I am confident that we can get this to work between us. You do the testing and I will help with the programing.

I would do it all but I do not have the hardware anymore as I went over to touch screen PLCs. I am more interested in touch screen GLCD solutions based on a PIC (Amicus18 for example) which I need the hardware for.

iw2fvo
- 1st June 2014, 20:42
Thanks Steve,
I do appreciate your help. I will tell you as soon as I have the new dispaly in my hands.
Ambrogio

iw2fvo
- 21st June 2014, 15:35
Hi Steve,
I received the new display just now.
It is equipped with the PCF 8574T.
It is connected to the QC2004A display in the following way:

pin_4 p0 > RS
pin_5 p1 > RW
pin_6 p2 > enable
pin_7 p3 > Backlight
pin_9 p4> data4
pin_10 p5 > data5
pin_11 p6 > data6
pin_12 p7 > data7

It is different wrt the one I had before: it has a different connections between the PCF and the LCD.
I will be ready for testing tomorrow or monday: please suggest me what trials to do just to start.
Thanks for all
Ambrogio

EarlyBird2
- 22nd June 2014, 08:28
We start with Darrel's routine for PBP3 and make changes for your LCD pin setup and PBP2.x

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

iw2fvo
- 22nd June 2014, 13:48
Steve,
the point is that I do not have PBP_3.
My pbp is 2.50 B.
No arraywrite or read, no usercommand ... are available to me .
Thanks
Ambrogio

EarlyBird2
- 22nd June 2014, 22:14
Steve,
the point is that I do not have PBP_3.
My pbp is 2.50 B.
No arraywrite or read, no usercommand ... are available to me .
Thanks
Ambrogio

Yes the arraywrite command has to be handled differently in pbp2.5.

Arraywrite loads the LCD_Buff you need to replace Arraywrite with a routine that loads what you want displayed on the LCD into LCD_Buff.

For example
LCD_BuffLen = 4
LCD_Buff.0 = "T"
LCD_Buff.1 = "e"
LCD_Buff.2 = "s"
LCD_Buff.3 = "t"
LCD_WriteBuff

Just to give you an idea as I think this is how it works but obviously I have not tested it as only you have the hardware.

Also johncouture's LCD has the same pins as your's (check it) so his modified programs are the ones you need to use.

This is the first step more issues could be thrown up. I am expecting to enjoy the ride (voyage of discovery) and hopefully get it working.

iw2fvo
- 25th June 2014, 22:24
Steve,
sorry for not having reply soon because of " family duty ".
I wrote this small program and I am able to control Backlight :

DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
C VAR portd.3 ' S_CLOCK
D VAR portd.2 ' S_DATA
ADDR VAR BYTE
ADDR = %01001110 ' dec 78 , hex 4E
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT2
RS VAR LCD_CMD.BIT0
E=0:RS=0
LCD_CMD = 0
PAUSE 1000

MAIN:

I2CWRITE D, C, ADDR, [%00000000] ' bck_lt= off
PAUSE 200
I2CWRITE D, C, ADDR, [%00001000] ' bck_lt=on
PAUSE 200

GOTO MAIN

The I2C address is new.
Now, my LCD has 20 chrs X 4 lines.
The PCF controls the LCD using the upper four bits of its output port.
I have to initialize the LCD in four bit mode , four lines at the required PCF port pins.
How could I do that ?
Thanks
Ambrogio

EarlyBird2
- 25th June 2014, 22:54
Initialise is at the end of the second code which you need to include using this code



INCLUDE "LCD_PCF8574A.pbp" ; Init LCD using I2C and PCF8574




; File Name : LCD_PCF8574A.pbp
; Author : Darrel Taylor
; Created : Mon Feb 24 2014
; Sun Mar 03 2014
; Updated bit shift. Data is on Lower side, Cmd lines on Upper
; Compiler : PicBasic Pro 3.0.6.x or higher
; Description : Uses PCF8574 Port expander to interface with HD44780 LCD
;
;-------------------------------------------------------------------------------
LCD_BuffSize CON 30
LCD_Buff VAR BYTE[LCD_BuffSize]
LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte

GOTO Over_LCDPCF8574

;----[Write 1-byte to LCD]--(Input is LCD_Data)---------------------------------
USERCOMMAND "LCD_WRITE"
LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return

ASM
LCD_WRITE? macro
L?CALL _LCD_WRITE_
endm
ENDASM

;----[Write contents of buffer to LCD]------------------------------------------
USERCOMMAND "LCD_WRITEBUFF"
LCD_WRITEBUFF_:
' The purpose of this routine is to increment through LCD_Buff and
' pass each character to LCD_Data so that it can be written.
' This will loop for LCD_BuffLen which is calculated by
' subtracting the starting address of the buffer from the
' ending address of the buffer.

LCD_BuffLen = R5 - LCD_BuffAddr -1
LCD_WriteMode = 3 ; Both Nibbles
LCD_CommandMode = 0
FOR LCD_Idx = 0 TO LCD_BuffLen
IF LCD_Buff(LCD_Idx) = $FE THEN LCD_CommandMode = 1 : GOTO LCD_ByteDone
IF LCD_CommandMode THEN
LCD_RS = 0 ' this is a command
LCD_CommandMode = 0 ' false, next byte will be data
ELSE
LCD_RS = 1 ' this is data
ENDIF
LCD_Data = LCD_Buff(LCD_Idx)
LCD_Write
IF LCD_CommandMode THEN
PAUSE 2
ELSE
PAUSEUS 50
ENDIF

LCD_ByteDone:
NEXT LCD_Idx

LCD_CommandMode = 0
RETURN

ASM
LCD_WRITEBUFF? macro
L?CALL _LCD_WRITEBUFF_
endm
ENDASM

USERCOMMAND "LED_WRITE"
LED_Write_:
; Write to the LEDs (this is a test routine)
LCD_E = 1
IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
i2cwrite SDA,SCL, LCD_Addr2,[LCD_Byte]
pause 500
i2cwrite SDA,SCL, LCD_Addr2,[LCD_Byte2]
pause 500
endif
IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
i2cwrite SDA,SCL, LCD_Addr2,[LCD_Byte]
pause 500
i2cwrite SDA,SCL, LCD_Addr2,[LCD_Byte2]
pause 500
endif
RETURN

ASM
LED_WRITE? macro
L?CALL _LED_WRITE_
endm
ENDASM

Over_LCDPCF8574:

;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish


The files you need are here
http://support.melabs.com/threads/98...F8574-20x4-LCD

EarlyBird2
- 27th June 2014, 10:25
Ambrogio are you making any progress?

iw2fvo
- 27th June 2014, 13:31
Steve,

I am not able to go on. I am not a software guy...
I do need something very simple just to start from the beginning...
It is hard to me .
I understand that I will never have the I2C lcd as simple as the LCDOUT that I usually use.
Thanks to be patient !
Ambrogio

EarlyBird2
- 27th June 2014, 21:23
Steve,

I am not able to go on. I am not a software guy...
I do need something very simple just to start from the beginning...
It is hard to me .
I understand that I will never have the I2C lcd as simple as the LCDOUT that I usually use.
Thanks to be patient !
Ambrogio

I will work on something very simple like print "Test" on the LCD as a start.

Unfortunately my problem is everything looks easy to me and I assume everyone sees what I see and understands what I understand and obviously they do not. I can take the lead if you want me to. I just assumed you wanted the fun of solving the problem. Give me a bit of time to write a test program.

iw2fvo
- 28th June 2014, 09:22
Thanks Steve.
your assistance is great.
Ambrogio

EarlyBird2
- 28th June 2014, 10:01
This is the code to initialise the LCD and send Test. It does not use the LCD_Buff features. Obviously you need to check the OSC and DEFINEs as usual. I do expect this not to work first time!



DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return



Main:
LCD_Data = "T"
gosub LCD_Write_
LCD_Data = "e"
gosub LCD_Write_
LCD_Data = "s"
gosub LCD_Write_
LCD_Data = "t"
gosub LCD_Write_

goto main

iw2fvo
- 28th June 2014, 15:04
Steve,
Thanks a lot for the intersest.
It does not work. I added the bck_lt flashing in the main loop just to see if the communication is good > the bck_lt comes ond goes correctly.
I am attaching the whole program
Ambrogio
'************************************************* ***************
'* Name : RKPK40 board pic18F452 40 MHz *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 23/06/2014 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

';Program Configuration Register 1H
@ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H

';Program Configuration Register 2L
@ __CONFIG _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L

';Program Configuration Register 2H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H

';Program Configuration Register 3H
@ __CONFIG _CONFIG3H, _CCP2MX_OFF_3H

';Program Configuration Register 4L
@ __CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L

';Program Configuration Register 5L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L

';Program Configuration Register 5H
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H

';Program Configuration Register 6L
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L

';Program Configuration Register 6H
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H

';Program Configuration Register 7L
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L

';Program Configuration Register 7H
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return



Main:
LCD_Data = "T"
gosub LCD_Write_
LCD_Data = "e"
gosub LCD_Write_
LCD_Data = "s"
gosub LCD_Write_
LCD_Data = "t"
gosub LCD_Write_
pause 5000
i2cwrite sda, scl, LCD_addr, [0] ' back_lt blinking
pause 1000
i2cwrite sda, scl, LCD_Addr,[%00010000]
pause 1000
goto main

iw2fvo
- 28th June 2014, 15:08
Steve,
I have checked the PCF to LCD connection :

bit0 = RS
bit1 =RW
bit2 =EN
bit3 =bck_lt
bit4 =D4
bit5 =D5
bit6 =D6
bit7 =D7

D0 to D3 of the LCD : there is no connection at all.

Regards,
Ambrogio

iw2fvo
- 28th June 2014, 16:20
Steve,
the display has 20 chrs X 4 lines.
Thanks,
Ambrogio

EarlyBird2
- 28th June 2014, 22:05
Steve,
Thanks a lot for the intersest.
It does not work. I added the bck_lt flashing in the main loop just to see if the communication is good > the bck_lt comes ond goes correctly.
I am attaching the whole program
Ambrogio


'************************************************* ***************
'* Name : RKPK40 board pic18F452 40 MHz *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 23/06/2014 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

';Program Configuration Register 1H
@ __CONFIG _CONFIG1H, _OSCS_OFF_1H & _HSPLL_OSC_1H

';Program Configuration Register 2L
@ __CONFIG _CONFIG2L, _BOR_OFF_2L & _BORV_20_2L & _PWRT_ON_2L

';Program Configuration Register 2H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H

';Program Configuration Register 3H
@ __CONFIG _CONFIG3H, _CCP2MX_OFF_3H

';Program Configuration Register 4L
@ __CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L

';Program Configuration Register 5L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L

';Program Configuration Register 5H
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H

';Program Configuration Register 6L
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L

';Program Configuration Register 6H
@ __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H

';Program Configuration Register 7L
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L

';Program Configuration Register 7H
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return



Main:
LCD_Data = "T"
gosub LCD_Write_
LCD_Data = "e"
gosub LCD_Write_
LCD_Data = "s"
gosub LCD_Write_
LCD_Data = "t"
gosub LCD_Write_
goto main

I over simplified the program!
need to add this line

LCD_RS = 1 ' this is data highlighted in red above. This switches from command mode to data. It was in command mode that is why your back_lt instructions worked. An excellent clue for me.

I am not sure about these lines

LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7

and what the location addresses are to position the cursor at the beginning of each line.

Have you a datasheet for this LCD?

When this simple example is working we can add Command/Data switching which we will obviously need to have. I will follow Darrel's method as close as possible, he uses $FE to indicate the next byte is a command and switches to command mode for one byte then back to data.

Plenty for me to think about.

EarlyBird2
- 29th June 2014, 09:56
INS CON 254 ' $FE: INSTRUCTION COMMAND MODE
CLR CON 1 ' CLEAR LCD , GOTO FIRST LINE, FIRST CHARACTER
DG CON 223 ' DEG SYMBOL °
LINE1 CON 128 ' $80: GOTO LINE 1
LINE2 CON 192 ' $C0: GOTO LINE 2
LINE3 CON 148 ' $94: GOTO LINE 3
LINE4 CON 212 ' $D4: GOTO LINE 4

Assuming $80 is line 1/0 then we can add

PAUSE 2 ; Let command finish
LCD_Data = $80
gosub LCD_Write_

to position the cursor. As this is a command it goes before we switch to data mode like this

PAUSE 2 ; Let command finish
LCD_Data = $80
gosub LCD_Write_
PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

iw2fvo
- 29th June 2014, 14:50
Dear Steve,

I am not able to findout the detailed spec for the QC2004A display. I can tell it is working well using the standard PBP connection diagram.
I am posting a general spec for LCD addressing ( attached ).

I did a very bad experience with the PCF expander board that was attached to the LCD: the trim pot that should adjust the contrast of the display has the cursor connected to ground and one side connected to 5VDC. I did turn it just to be sure of the contrast setting and I got a short circuit of the 5Vdc to ground when turned fully clockwise. The result is that my ICD2 programmer smoked and it is no longer working. I have attached the photo of the PCF expander to warn about this item: there is a very very gross design error on it.
I am looking to find a new pic programmer to buy: what do you recommand to me ? Is the pickit3 really good ?
I have a pic16f877 to replace on the ICD2 programmer but I do not have any possibiliity to program it with the required bootloader... I will ask someone tomorrow !
I really hope to test your programs soon. I will let you know.
I want to thank you once again for the help you are giving to me .
Regards,
Ambrogio

EarlyBird2
- 30th June 2014, 08:02
Ambrogio


I am looking to find a new pic programmer to buy: what do you recommend to me ? Is the pickit3 really good ?

I have no experience of programmers as I inherited all of my hardware from my son, he took an electronics course before going to university. I have a Picstart Plus that I have never used.


I really hope to test your programs soon. I will let you know.

Please do as you have sparked my interest now and all sorts of bright ideas are formulating in my mind to the point that I am loosing sleep.

richard
- 30th June 2014, 08:44
I have a pickit3 and a pickit2 programmer the pk3 only ever gets used if its the only choice (and it very seldom is) . the gui for the pk2 is just so much better to use . serial debugging is just so easy with the pk2 and its built in comms package . by far the pk2 is my tool of choice for icsp.
I have never bothered to use either of them in command line mode for programming directly from micro code studio although it is fairly easy to do .
I must admit that I have not looked to see if microchip have made a better/upgraded gui for the pk3 for at least a year now , my info may be out of date .
I also wonder if any body has tried the cheap pk2 clones that are on ebay , are they compatible with the microchip pk2 gui ? are they any good?

iw2fvo
- 1st July 2014, 08:16
Is there a lista of PICs programmable by PICKIT2 ?
Thanks
Ambrogio

richard
- 1st July 2014, 10:27
Is there a lista of PICs programmable by PICKIT2 ?
not that I can find ,but there is not many that aren't on the supported device list.
you can download the pickit2 program(its free) from microchip site and check out the supported device list if you have specific devices to check
http://www.microchip.com/DevelopmentTools/ProductDetails.aspx?PartNO=pg164120#dtDocumentatio n

iw2fvo
- 9th July 2014, 15:04
Hi Steve,
I am back again on this LCD ...
I have repaired the programmer and so I had the occasion to test the program.
> Back light does not come on at all .
> nothing is displayed on the LCD
If you have something more to suggest, I am ready to go on .
Thanks
Regards,
Ambrogio

EarlyBird2
- 10th July 2014, 06:47
Hi Steve,
I am back again on this LCD ...
I have repaired the programmer and so I had the occasion to test the program.
> Back light does not come on at all .
> nothing is displayed on the LCD
If you have something more to suggest, I am ready to go on .
Thanks
Regards,
Ambrogio
Not good news then!

I need to refresh my memory. Post the full code you are using please.

iw2fvo
- 10th July 2014, 08:09
here it is:

DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return



Main:
LCD_Data = "T"
gosub LCD_Write_
LCD_Data = "e"
gosub LCD_Write_
LCD_Data = "s"
gosub LCD_Write_
LCD_Data = "t"
gosub LCD_Write_
goto main

EarlyBird2
- 10th July 2014, 08:43
Please use code tags as it is easier for me to read.

EarlyBird2
- 10th July 2014, 09:02
here it is:


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return



Main:
LCD_Data = "T"
gosub LCD_Write_
LCD_Data = "e"
gosub LCD_Write_
LCD_Data = "s"
gosub LCD_Write_
LCD_Data = "t"
gosub LCD_Write_
goto main

Need to add pauseus!



Main:
LCD_Data = "T"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write_: PAUSEUS 50
goto main

EarlyBird2
- 10th July 2014, 10:40
And to test backlight is working try



Main:
LCD_Backlight = 0
LCD_Data = "T"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write_: PAUSEUS 50
pause 500
LCD_Backlight = 1
LCD_Data = "-"
gosub LCD_Write_: PAUSEUS 50
pause 500
goto main

iw2fvo
- 10th July 2014, 17:02
Steve,
I uploaded the two codes you have sent to me and checked them one at the time :
> backlight is still not working
> lcd show nothing
Thanks
Ambrogio

EarlyBird2
- 10th July 2014, 22:03
Is the address correct? It is 78 in the code.

Try your code from post #24 as this did control the backlight.

iw2fvo
- 11th July 2014, 07:55
Steve,
this code still works well:
Thanks ,Ambrogio

DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
C VAR portd.3 ' S_CLOCK
D VAR portd.2 ' S_DATA
ADDR VAR BYTE
ADDR = %01001110 ' dec 78 , hex 4E
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT2
RS VAR LCD_CMD.BIT0
E=0:RS=0
LCD_CMD = 0
PAUSE 1000

MAIN:

I2CWRITE D, C, ADDR, [%00000000] ' bck_lt= off
PAUSE 200
I2CWRITE D, C, ADDR, [%00001000] ' bck_lt=on
PAUSE 200

GOTO MAIN

EarlyBird2
- 11th July 2014, 08:49
Steve,
this code still works well:
Thanks ,Ambrogio


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
C VAR portd.3 ' S_CLOCK
D VAR portd.2 ' S_DATA
ADDR VAR BYTE
ADDR = %01001110 ' dec 78 , hex 4E
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT2
RS VAR LCD_CMD.BIT0
E=0:RS=0
LCD_CMD = 0
PAUSE 1000

MAIN:

I2CWRITE D, C, ADDR, [%00000000] ' bck_lt= off
PAUSE 200
I2CWRITE D, C, ADDR, [%00001000] ' bck_lt=on
PAUSE 200

GOTO MAIN

This works because you can see the backlight turn on and off. This tells me the LCD is working and the address is correct. Unfortunately that has eliminated the obvious. I will dig deeper into Darrel's code as I can not see anything that would stop it working.

EarlyBird2
- 12th July 2014, 09:50
This works because you can see the backlight turn on and off. This tells me the LCD is working and the address is correct. Unfortunately that has eliminated the obvious. I will dig deeper into Darrel's code as I can not see anything that would stop it working.
I have studied the HD44780 and PCF8574 datasheets and compared them to Darell's code and found as expected that his code follows the datasheets precisely. I compared the code




DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
C VAR portd.3 ' S_CLOCK
D VAR portd.2 ' S_DATA
ADDR VAR BYTE
ADDR = %01001110 ' dec 78 , hex 4E
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT2
RS VAR LCD_CMD.BIT0
E=0:RS=0
LCD_CMD = 0
PAUSE 1000

MAIN:

I2CWRITE D, C, ADDR, [%00000000] ' bck_lt= off
PAUSE 200
I2CWRITE D, C, ADDR, [%00001000] ' bck_lt=on
PAUSE 200

GOTO MAIN


with Darrel's and noticed the I2C_SLOW definition is not included in his code. I then looked at I2CWRITE in the manual and noticed that PAUSE 10 is used to allow time for the transfer to complete again this is not included in Darrel's code.

What does this indicate is the question?

I compared PBP2.5 and pbp3 manuals and the I2CWRITE instruction is the same. I wondered if the pause in PBP3 is not needed as the compiler takes care of the I2C being busy.

One step at a time.
First remove the I2C_SLOW and test


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return

Main:
LCD_Backlight = 0
LCD_Data = "T"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write_: PAUSEUS 50
pause 500
LCD_Backlight = 1
LCD_Data = "-"
gosub LCD_Write_: PAUSEUS 50
pause 500
goto main

Then add pause 10 delays


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte]
PAUSE 10
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte2]
PAUSE 10
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte]
PAUSE 10
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte2]
PAUSE 10
ENDIF
return

Main:
LCD_Backlight = 0
LCD_Data = "T"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write_: PAUSEUS 50
pause 500
LCD_Backlight = 1
LCD_Data = "-"
gosub LCD_Write_: PAUSEUS 50
pause 500
goto main

and let me know the outcome.

I will continue looking for answers.

iw2fvo
- 12th July 2014, 20:58
Hi Steve,
no change using both codes.
I still have no backlight and no text.
I appreciate your assistance on this matter: thanks a lot.
I am not skilled enough to go deeper in those kind of codes ...
Regards,
Ambrogio

pedja089
- 12th July 2014, 21:33
Can I make one suggestion?
First connect few led on output of PCF8574, and control them. So you are sure that I2C communication woks.
Second connect LCD to PIC directly, get timing and control right.
Then just combine that two.

EarlyBird2
- 12th July 2014, 22:18
Try again


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 1000 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write
PAUSEUS 6000
gosub LCD_Write
PAUSEUS 1000
gosub LCD_Write
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write ; Display ON
LCD_Data = $01
gosub LCD_Write ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return

Main:

I2CWRITE SDA,SCL, LCD_Addr, [%00000000] ' bck_lt= off
PAUSE 200
I2CWRITE SDA,SCL, LCD_Addr, [%00001000] ' bck_lt=on
PAUSE 200

LCD_Data = "T"
gosub LCD_Write: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write: PAUSEUS 50
LCD_Data = "-"
gosub LCD_Write: PAUSEUS 50
pause 500
goto Main

EarlyBird2
- 13th July 2014, 10:13
The problem could be with the delay on power up not being long enough for the LCD to initialise before the PIC starts.

Adjust this line and test

;----[Initialize the LCD]-------------------------------------------------------
PAUSE 1000 ; LCD Power-on delay

and please let me know the result.

iw2fvo
- 13th July 2014, 18:11
Dear Steve:

Your suggested test gave me the response on the lack of operation. ( see the attached).
The pcf has P0, P5 and P6 not working. This is the reason of the trouble.
I will no longer buy components on Ebay expecially if chinese. That is very bad.
I have no words to express my state. I want to apologize .
Thanks for the help given to me since the beginning.
Will try to buy another expander board: do you know some reliable seller in Europe ?
Regards,
Ambrogio

EarlyBird2
- 14th July 2014, 06:03
Dear Steve:

Your suggested test gave me the response on the lack of operation. ( see the attached).
The pcf has P0, P5 and P6 not working. This is the reason of the trouble.
I will no longer buy components on Ebay expecially if chinese. That is very bad.
I have no words to express my state. I want to apologize .
Thanks for the help given to me since the beginning.
Will try to buy another expander board: do you know some reliable seller in Europe ?
Regards,
Ambrogio

No problem and no need to apologise. Could you do some more testing on this board?
Check the voltages on the P0 to P7 pins when this program is running.


DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
DEFINE I2C_SLOW 1
C VAR portd.3 ' S_CLOCK
D VAR portd.2 ' S_DATA
ADDR VAR BYTE
ADDR = %01001110 ' dec 78 , hex 4E
CMD VAR BYTE
LCD_CMD VAR BYTE
E VAR LCD_CMD.BIT2
RS VAR LCD_CMD.BIT0
E=0:RS=0
LCD_CMD = 0
PAUSE 1000

MAIN:

I2CWRITE D, C, ADDR, [%00000000] ' port off
PAUSE 200
I2CWRITE D, C, ADDR, [%11111111] ' port on
PAUSE 200

GOTO MAIN

If all pins change then the PCF8574 chip is good indicating that the fault is either bad soldering or bad PCB track. It is possible to solder jumper wire direct to pins for a temporary repair.

richard
- 14th July 2014, 08:54
are you sure the new board has 8574t on it not a 8574A ?
that might make a world of difference

EarlyBird2
- 14th July 2014, 09:04
=richard;127791]are you sure the new board has 8574t on it not a 8574A ?
that might make a world of difference

It is definitely a 8574T as shown in #36 and copied below.

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=7371&stc=1&d=1404048736[

richard
- 14th July 2014, 10:19
is that the current device or the one that got zapped ?
I found a 8574a in my junk box and fed your code into it (no lcd) and it seems ok (address is $78 for a version)
the attached pcf8574a.txt file is really a salea logic data/setting file and should be renamed to pcf8574a.logicdata , if you don't have a salea logic analyser you can download the software from salea logic and view the complete data

iw2fvo
- 14th July 2014, 10:25
Steve,
I did run the program:
P0, P5 and P6 do not toggle: they are always at 0vdc as seen by the scope.
I did check the tracks : there is good continuity between each pin of the PCF and the display pins.
I assume the pcf is gone or the module has been sent with a broken pcf.
As you have seen in the photos, I have changed the contrast pot because it was shorting the 5 vdc to ground , I fit a new one with a "crossed" pins.
Will order a new board from a reliable seller ... I am searching for it here.
Thanks for all.
Ambrogio

EarlyBird2
- 14th July 2014, 10:43
is that the current device or the one that got zapped ?
I found a 8574a in my junk box and fed your code into it (no lcd) and it seems ok (address is $78 for a version)
the attached pcf8574a.txt file is really a salea logic data/setting file and should be renamed to pcf8574a.logicdata , if you don't have a salea logic analyser you can download the software from salea logic and view the complete data

It is the current device.

The PCF8574 and PCF8574A are identical, except for the different fixed portion of the slave address. The address used is 78 which fits with it being a PCF8574T and you use $78 which again fits with yours being a PCF8574AT.

iw2fvo
- 14th July 2014, 10:46
Thanks Richard,
I confirm that the address is OK since I can get some pins toggling correctly.
the PCF has definitively some "broken" port pins.
I still have the suspect that this is a fake board: It has the contrast pot error ... and now it has this issue !
Thanks a lot
Ambrogio
iw2fvo

EarlyBird2
- 14th July 2014, 10:50
Steve,
I did run the program:
P0, P5 and P6 do not toggle: they are always at 0vdc as seen by the scope.
I did check the tracks : there is good continuity between each pin of the PCF and the display pins.
I assume the pcf is gone or the module has been sent with a broken pcf.
As you have seen in the photos, I have changed the contrast pot because it was shorting the 5 vdc to ground , I fit a new one with a "crossed" pins.
Will order a new board from a reliable seller ... I am searching for it here.
Thanks for all.
Ambrogio

Well done it is the PCF!
I am surprised I thought the PCF was the least likely cause the PCB track or soldering fault was the most likely cause.

richard
- 14th July 2014, 11:10
this looks cheap
http://www.dx.com/p/raspberry-pi-pcf8574-io-expansion-board-pcf8574t-io-expansion-board-i2c-blue-281775?tc=AUD&gclid=Cj0KEQjw_42eBRDHqcG1psmtneEBEiQAWPL8WFON5a9f 8f5z8aYBfe-68w0PknBLQ2jkbJQPihK1IZkaAuf28P8HAQ#.U8OsSWflp_Q

EarlyBird2
- 16th July 2014, 08:32
I have bought this

7392

from

http://4tronix.co.uk/store/index.php?rt=product/product&path=36&product_id=158

EarlyBird2
- 17th July 2014, 07:46
I have tested this code and it works!



DEFINE OSC 40 ' 10 MHz XTAL AND X 4 INTERNAL PLL
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78
'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 0=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
testmode var byte



;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight OFF
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Reset 3 times
gosub LCD_Write_
PAUSEUS 6000
gosub LCD_Write_
PAUSEUS 1000
gosub LCD_Write_
PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write_
PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28
gosub LCD_Write_ ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C
gosub LCD_Write_ ; Display ON
LCD_Data = $01
gosub LCD_Write_ ; Clear Screen
PAUSE 2
LCD_Data = $06
gosub LCD_Write_ ; Entry Mode

PAUSE 2 ; Let command finish
LCD_RS = 1 ' this is data
goto main

LCD_WRITE_:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return

Main:
LCD_Backlight = 0
LCD_Data = "T"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "e"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "s"
gosub LCD_Write_: PAUSEUS 50
LCD_Data = "t"
gosub LCD_Write_: PAUSEUS 50
pause 500
LCD_Backlight = 1
LCD_Data = "-"
gosub LCD_Write_: PAUSEUS 50
pause 500
goto main

EarlyBird2
- 17th July 2014, 08:15
I am not a good programmer and I would like to convert the PBP program that is normally used now to EASY control the I2C display.
At the moment I am using this piece of code:

INS CON 254 ' $FE: INSTRUCTION COMMAND MODE
CLR CON 1 ' CLEAR LCD , GOTO FIRST LINE, FIRST CHARACTER
DG CON 223 ' DEG SYMBOL °
LINE1 CON 128 ' $80: GOTO LINE 1
LINE2 CON 192 ' $C0: GOTO LINE 2
LINE3 CON 148 ' $94: GOTO LINE 3
LINE4 CON 212 ' $D4: GOTO LINE 4

And then I do the the following to write my own data on it:

LCDOUT INS, LINE2, " V=", DEC2 VLT/10, ".", DEC1 VLT

How could I translate the above in I2C enviroment for displaying ?

Thanks for the assistance
Regards,
Ambrogio
IW2FVO

How to do this as neatly as possible are the next steps.

richard
- 17th July 2014, 08:42
the ext modifier should help
lcdb VAR BYTE[22]

ASM
lcd_cmd = _lcdb
lcd_buff = _lcdb+2

ENDASM
these must be after the asm code

lcd_cmd var byte EXT
lcd_buff var byte EXT



lcdb[0]=$fe
lcdb[1]= your lcd command eg 1 $80 $c0

use arraywrite to load lcd_buff (max 20 chrs)

then you can pass
lcd_cmd to your lcd write code if you need to send a cmd with your lcd string
or pass lcd_buff if no cmd required

ps don't forget to add a dely after a cmd to give the lcd time to act

ps ps
the asm names are case sensitive


left a bit out

lcd_cmd var byte EXT
lcd_buff var byte EXT

not sure if it needs to be try it and see

lcd_cmd var byte[2] EXT
lcd_buff var byte[20] EXT

EarlyBird2
- 17th July 2014, 08:54
the ext modifier should help
lcdb VAR BYTE[22]

ASM
lcd_cmd = _lcdb
lcd_buff = _lcdb+2

ENDASM

lcdb[0]=$fe
lcdb[1]= your lcd command eg 1 $80 $c0

use arraywrite to load lcd_buff (max 20 chrs)

then you can pass
lcd_cmd to your lcd write code if you need to send a cmd with your lcd string
or pass lcd_buff if no cmd required

ps don't forget to add a dely after a cmd to give the lcd time to act

ps ps
the asm names are case sensitive


left a bit out

lcd_cmd var byte EXT
lcd_buff var byte EXT

not sure if it needs to be try it and see

lcd_cmd var byte[2] EXT
lcd_buff var byte[20] EXT



Steve,
the point is that I do not have PBP_3.
My pbp is 2.50 B.
No arraywrite or read, no usercommand ... are available to me .
Thanks
Ambrogio

Ambrogio is using pbp2.5 and I am even older on 2.46.

richard
- 17th July 2014, 08:57
without arraywrite that's a lot of code

EarlyBird2
- 17th July 2014, 08:58
without arraywrite that's a lot of code

and a lot more fun!

I am only along for the ride and to keep my brain ticking over. :smile:

richard
- 17th July 2014, 09:11
does 2.5 have the dig command

Dave
- 17th July 2014, 12:09
The DIG modifier has been there forever....

iw2fvo
- 17th July 2014, 17:05
Steve,
it is a very good new !
I am looking to place an order for a couple of new extender boards. The point is the lead time .
I will let you know.
I appreciate your assistance.
Regards,
Ambrogio

iw2fvo
- 17th July 2014, 17:13
Thanks to all of you for the assistance.
What is the dig modifier please ?
Thnaks
Ambrogio

pedja089
- 17th July 2014, 18:20
From manual:
DIG returns the value of a decimal digit. Input the digit number (0 – 9, with 0 being the rightmost digit). DIG returns the value of the decimal digit that you specified. DIG is commonly used to distill BCD digits from numeric values and to isolate single digits for display on seven-segment LCD.
B0 = 123 ' Set B0 to 123
B1 = B0 DIG 2 ' Sets B1 to 1 (digit 2 of 123)

EarlyBird2
- 18th July 2014, 08:43
Steve,
it is a very good new !
I am looking to place an order for a couple of new extender boards. The point is the lead time .
I will let you know.
I appreciate your assistance.
Regards,
Ambrogio

No next day delivery in Italy?

I ordered my LCD and backpack for £9.30 including next day delivery, details in #66.

The test program is not very useful as it only tests the LCD is working. I will add commands so that the screen can be cleared and the cursor can be positioned anywhere on the screen.

iw2fvo
- 18th July 2014, 08:57
That is clear to me now.
Thanks
Ambrogio

EarlyBird2
- 19th July 2014, 10:29
Ambrogio

I am working on the program by adding commands as you can see in the picture.

7394

Let me know when you are ready.

iw2fvo
- 19th July 2014, 11:11
Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio

EarlyBird2
- 20th July 2014, 10:19
Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio

Here it is. This is a simple test program for PBP2.5 or lower. Anything you do not understand please ask. The next step is to include the command selection inside the LCD_WRITE subroutine.


'************************************************* ***************
'* Name : I2CLCD.BAS
'* Author : Steve Earl
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 17/07/2014
'* Version : 1.0
'* Notes : Serial I2C LCD using PBP 2.5
'* : PCF8574T I2C port expander 20x4 LCD
'************************************************* ***************

define OSC 40 ' set the correct speed here!!
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78 ; PCF8574T address

'LCD_BuffSize CON 30
'LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
'LCD_BuffLen VAR WORD ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 1=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
'LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
'LCD_Idx VAR BYTE
seconds var byte
minutes var byte
hours var byte

Init:
;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight On
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register

LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Software Reset 3 times
gosub LCD_Write : PAUSEUS 6000
gosub LCD_Write : PAUSEUS 1000
gosub LCD_Write : PAUSEUS 1000

LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write : PAUSEUS 1000

LCD_WriteMode = 3 ;-- Both Nibbles
LCD_Data = $28 : gosub LCD_Write ; Function Set, 4-bit, 2-line, 5x7
LCD_Data = $0C : gosub LCD_Write ; Display ON
LCD_Data = $01 : gosub LCD_Write ; Clear Screen
PAUSE 50
LCD_Data = $06 : gosub LCD_Write ; Entry Mode
PAUSE 2 ; Let command finish
LCD_RS = 1 ;Switch to Data
;Print Static Background to LCD
LCD_Data = " " : gosub LCD_Write ;Line 1
LCD_Data = " " : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = "S" : gosub LCD_Write
LCD_Data = "t" : gosub LCD_Write
LCD_Data = "e" : gosub LCD_Write
LCD_Data = "v" : gosub LCD_Write
LCD_Data = "e" : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = "E" : gosub LCD_Write
LCD_Data = "a" : gosub LCD_Write
LCD_Data = "r" : gosub LCD_Write
LCD_Data = "l" : gosub LCD_Write

lcd_rs = 0 ;Command is next
lcd_data=$a8 : gosub lcd_write ;Move to start of line 2
pause 2
lcd_rs = 1 ;Switch back to Data

LCD_Data = " " : gosub LCD_Write ;Line 2
LCD_Data = " " : gosub LCD_Write
LCD_Data = "D" : gosub LCD_Write
LCD_Data = "a" : gosub LCD_Write
LCD_Data = "t" : gosub LCD_Write
LCD_Data = "a" : gosub LCD_Write
LCD_Data = "g" : gosub LCD_Write
LCD_Data = "e" : gosub LCD_Write
LCD_Data = "o" : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = "L" : gosub LCD_Write
LCD_Data = "i" : gosub LCD_Write
LCD_Data = "m" : gosub LCD_Write
LCD_Data = "i" : gosub LCD_Write
LCD_Data = "t" : gosub LCD_Write
LCD_Data = "e" : gosub LCD_Write
LCD_Data = "d" : gosub LCD_Write

lcd_rs = 0 ;Command is next
lcd_data=$99 : gosub lcd_write ;Move to line 3 col 6
pause 2
lcd_rs = 1 ;Switch back to Data

LCD_Data = "*" : gosub LCD_Write ;Line 3
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write
LCD_Data = "*" : gosub LCD_Write


lcd_rs = 0 ;Command is next
lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5
pause 2
lcd_rs = 1 ;Switch back to Data

LCD_Data = "T" : gosub LCD_Write ;Line 4
LCD_Data = "e" : gosub LCD_Write
LCD_Data = "s" : gosub LCD_Write
LCD_Data = "t" : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = "P" : gosub LCD_Write
LCD_Data = "r" : gosub LCD_Write
LCD_Data = "o" : gosub LCD_Write
LCD_Data = "g" : gosub LCD_Write
LCD_Data = "r" : gosub LCD_Write
LCD_Data = "a" : gosub LCD_Write
LCD_Data = "m" : gosub LCD_Write

pause 5000
lcd_rs = 0 ;Command is next
lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5
pause 2
lcd_rs = 1 ;Switch back to Data

LCD_Data = " " : gosub LCD_Write ;Clear line 4 and set clock
LCD_Data = " " : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = ":" : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = ":" : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = "0" : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write
LCD_Data = " " : gosub LCD_Write

main: ;Count seconds and refresh the clock
for hours = 0 to 23
for minutes = 0 to 59
for seconds = 0 to 59
lcd_rs = 0 ;Command is next
lcd_data=$DA : gosub lcd_write ;Move to line 4 col 7
pause 2
lcd_rs = 1 ;Switch back to Data

LCD_Data = (hours dig 1)+48 : gosub LCD_Write
LCD_Data = (hours dig 0)+48 : gosub LCD_Write
LCD_Data = ":" : gosub LCD_Write
LCD_Data = (minutes dig 1)+48 : gosub LCD_Write
LCD_Data = (minutes dig 0)+48 : gosub LCD_Write
LCD_Data = ":" : gosub LCD_Write
LCD_Data = (seconds dig 1)+48 : gosub LCD_Write
LCD_Data = (seconds dig 0)+48 : gosub LCD_Write
pause 1000
next ;second
next ;minute
next ;hour
goto main


LCD_WRITE:
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
return

EarlyBird2
- 22nd July 2014, 06:41
Ambrogio,

Any feedback?

If you have no questions then I will post the next improvement which includes the command in the LCD_Write subroutine. I am now looking at using arrays as the next step.

EarlyBird2
- 23rd July 2014, 09:03
Ambrogio,

Any feedback?

If you have no questions then I will post the next improvement which includes the command in the LCD_Write subroutine. I am now looking at using arrays as the next step.

Here it is! including LOOKUP and ARRAYs.



'************************************************* ***************
'* Name : I2CLCD.BAS *
'* Author : Steve Earl *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 17/07/2014 *
'* Version : 1.0 *
'* Notes : Serial I2C LCD using PBP 2.5 *
'* : PCF8574T I2C port expander 20x4 LCD *
'************************************************* ***************

define OSC 40 ' set the correct speed here!!
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78 ; PCF8574T address
LCD_Line_1 con $80
LCD_Line_2 con $A8
LCD_Line_3 con $94
LCD_Line_4 con $D4
LCD_BuffSize CON 22

LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
LCD_BuffLen VAR byte ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 1=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE


seconds var byte
minutes var byte
hours var byte

Init:
;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight On
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register
LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Software Reset 3 times
gosub LCD_Write : PAUSEUS 6000
gosub LCD_Write : PAUSEUS 1000
gosub LCD_Write : PAUSEUS 1000
LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write : PAUSEUS 1000
LCD_WriteMode = 3 ;-- Both Nibbles
LCD_buff[0] = $28 ; Function Set, 4-bit, 2-line
LCD_buff[1] = $0C ; Display ON
LCD_buff[2] = $FE
LCD_buff[3] = $06 ; Entry Mode
LCD_buff[4] = $FE
LCD_buff[5] = $01 ; Clear Screen
lcd_bufflen = 6
gosub LCD_Buff_Write

;Print Static Background to LCD
for lcd_idx = 0 to 85
;| | 20 characters
lookup lcd_idx,[" Steve Earl ",_ ;20
$FE,lcd_line_2," Datageo Limited ",_ ;+22 = 42
$FE,lcd_line_3," ********** ",_ ;+22 = 64
$FE,lcd_line_4," 00:00:00 "],lcd_data ;+22 = 86 (0-85)
gosub lcd_write
next

;Set up fixed buffer characters
lcd_bufflen = 10 ;8 characters in clock + $FE + LCD_Line
LCD_buff[0] = $FE ;Command is next
LCD_buff[1] = lcd_line_4 + 6 ;Move to line 4 col 7
LCD_buff[4] = ":" ;Fixed characters
LCD_buff[7] = ":" ; "
main: ;Count seconds and refresh the clock
for hours = 0 to 23
for minutes = 0 to 59
for seconds = 0 to 59
LCD_buff[2] = (hours dig 1)+48
LCD_buff[3] = (hours dig 0)+48
LCD_buff[5] = (minutes dig 1)+48
LCD_buff[6] = (minutes dig 0)+48
LCD_buff[8] = (seconds dig 1)+48
LCD_buff[9]= (seconds dig 0)+48
gosub lcd_buff_write
pause 1000
next ;second
next ;minute
next ;hour
goto main

LCD_WRITE:
if lcd_data = $FE then
lcd_commandMode = 1 ;Next byte Command
lcd_rs = 0 ;Switch to Command Register
else
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF

IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
if lcd_commandmode then
lcd_commandmode = 0 ;Reset to data
lcd_rs = 1 ;Switch to Data Register
pause 2
endif
endif
return

Lcd_Buff_Write:
for lcd_idx = 0 to lcd_bufflen - 1
lcd_data=lcd_buff[LCD_idx]
gosub LCD_Write
next
return

iw2fvo
- 23rd July 2014, 21:30
Steve,
I am sorry for the delayed reply : I am not at home on those days.
I had a look to your code : it is a good work and I am waiting to check it soon when the hardware is arrived .
Thanks a lot for the assistance.
I think your work will help a lot of people .
Regards,
Ambrogio

EarlyBird2
- 24th July 2014, 08:18
Steve,
I am sorry for the delayed reply : I am not at home on those days.
I had a look to your code : it is a good work and I am waiting to check it soon when the hardware is arrived .
Thanks a lot for the assistance.
I think your work will help a lot of people .
Regards,
Ambrogio
You are welcome. More is on the way as I am now investigating embedded strings.

EarlyBird2
- 24th July 2014, 08:54
I tried using the on board EEPROM by using DATA and READ.

DATA "This is a string",0

but it stores only alternate characters. I was surprised it worked at all but the alternate characters? There has to be a reason for it to work this way.

EarlyBird2
- 24th July 2014, 21:36
I tried using the on board EEPROM by using DATA and READ.

DATA "This is a string",0

but it stores only alternate characters. I was surprised it worked at all but the alternate characters? There has to be a reason for it to work this way.

It looks like this was fixed back in 2010.

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

My PBP2.46 is from 2005.

EarlyBird2
- 25th July 2014, 05:47
It looks like this was fixed back in 2010.

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

My PBP2.46 is from 2005.

The plot thickens! Here is an extract from this thread http://www.picbasic.co.uk/forum/showthread.php?t=6963&p=97143#post97143 using DATA with strings and it works.


EUREKA!
Thanks guys! You have been a huge help. I have finally figured it out.
My problem was more like 3 problems...

1. I have never done EEPROM stuff before so I was lost to begin with.
2. As Bruce pointed out, the mathematical order of operations in one line was not correct. I guess the BS2 thinks a little differently from PBP in that respect.
3. My PicBasic Pro compiler was Version 2.30 form 2000. It seems that v2.30 supports the PIC 16F628 but the PIC 16F628A was implemented in a later version. I have upgraded my PBP to version 2.47 and now the EEPROM features work correctly on the 16F628A. When I successfully tested a 16F84A using the same code, that lead me to question the compiler.

So for future generations and the benefit of other people like me, here's my WORKING code that is tested successfully on a PIC 16F628A with a 20MHz resonator compiled using PBP v2.47. It reads data from the Parallax RFID Reader Module, compares it against known values stored in EEPROM and allows or denies access accordingly. Enjoy.



CMCON = 7
DEFINE OSC 20 'Set oscillator in MHz

' -----[ Variables ]-------------------------------------------------------

buf VAR Byte(10) ' RFID bytes buffer
tagNum VAR Byte ' from EEPROM table
idx VAR Byte ' tag byte index
char VAR Byte ' character from table

' -----[ EEPROM Data ]-----------------------------------------------------

Tag1 DATA "100050A4B7"
Tag2 DATA "1000508E0A"
Tag3 DATA "10005091DC"
Tag4 DATA "100050203A"
Tag5 DATA "100050DA36"

' -----[ Initialization ]--------------------------------------------------

HIGH portb.3 ' turn off RFID reader
LOW portb.6 ' lock the door!
Low portb.4 'Turn off LED

' -----[ Program Code ]----------------------------------------------------

Main:

LOW portb.3 ' activate the reader
SERIN2 portb.2, 396, [WAIT($0A), STR buf\10] ' wait for hdr + ID
HIGH portb.3 ' deactivate reader

Check_List:
FOR tagNum = 1 to 5 ' scan through known tags
FOR idx = 0 TO 9 ' scan bytes in tag
READ (((tagNum-1) * 10) + idx), char ' get tag data from table
IF (char <> buf(idx)) THEN Bad_Char ' compare tag to table
NEXT
GOTO Tag_Found ' all bytes match!
Bad_Char: ' try next tag
NEXT

Bad_Tag:
tagNum = 0
FREQOUT portb.5, 1000 */ $100, 115 */ $100 ' groan
PAUSE 1000
GOTO Main

Tag_Found:
HIGH portb.6 ' remove latch
High portb.4 ' Light LED
FREQOUT portb.5, 2000 */ $100, 880 */$100 ' beep
LOW portb.6 ' restore latch
Low portb.4 ' LED OFF
GOTO Main

EarlyBird2
- 28th July 2014, 08:36
Ambrogio

After more testing of the DATA command I have come to the conclusion that my very old setup is the cause. I have PBP2.46 and MCSP from ten years ago. Looking at my old code, ten years old, I used WRITE not DATA and I now believe that was because DATA never worked. I wrote a routine just to write to the EEPROM followed by the program fortunately my set up did not overwrite the EEPROM when the PIC was reprogramed, Bruce's FlashLab boards continue to perform flawlessly.

There are three options for the screen setup

1 LOOKUP
2 Embedded string
3 EEPROM

They all work but LOOKUP uses most code space and EEPROM the least.

iw2fvo
- 29th July 2014, 09:55
Steve,
I am very interested in test the programs but I am still waiting to receive the PCF expander.
It will arrive here after my summer holidays. I will let you know.
Thanks for all.
Regards,
Ambrogio

Wirecut
- 9th September 2014, 01:01
Ciao Ambrogio,

take a look here ... could help!

http://www.protonbasic.co.uk/showthread.php/70173-Replace-the-PRINT-command-to-use-I2C-backpack-on-1602-LCD

Leo

iw2fvo
- 10th September 2014, 18:00
Thanks to all of you in this forum for the assistance.
I am having problem with my healt in this last period of time. I had an important surgery.
I hope to be active again.
Ambrogio
IW2FVO