Quote Originally Posted by EarlyBird2 View Post
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


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
Code:
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
Code:
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.