Eagle Tree Systems I2C LCD Display

nfk

Senior Member
I was looking for a really thin, ready-made LCD display for use in a PICAXE 28X1 project that I am working on and I found the Eagle Tree 'PowerPanel LCD Display"

(See http://www.rc-log.co.uk/index.php?target=products&product_id=30)

It looks great for my purposes because it's only about 5mm at its thickest point. Furthermore its an I2C driven display so I assumed it would be easy to use with the PICAXE. In case you're interested the pinouts for the screen's cable are as follows:

Red = +5V
White = Gnd
Yellow = SDA
Brown = SCL

Although I have successfully made the connection to the display from a 28X1 using "hi2csetup i2cmaster,118,i2cslow,i2cword" (I can get very random digits and effects to come up) the problem I have is actually communicating properly with this little gadget.

I believe that the controller for the LCD is the PCF2119X for which the datasheet can be found here...

http://www.nxp.com/acrobat_download/datasheets/PCF2119X_4.pdf

...but I'll admit that it all seems like pretty heavy, technical stuff to me. I know it's probably asking too much but there doesn't seem to be anything to make it as simple as the Rev Ed LCD panel which is relatively straightforward to programme.

Is this normal for I2C devices? I just can't see why an LCD display needs to be complicated. If I could only find out how to clear the screen and display a few characters I'm sure I could work out the rest.

Any guidance/pointers much appreciated.

Cheers,
Nigel
 

hippy

Ex-Staff (retired)
The controller seems to be an industry standard HD7780 clone but with an I2C wrapping and a few extra features. The I2C protocol description ( pages 54-56 ) seems straight forward enough and defines the various sequences which can be used to send data to the displays.

With a fair wind, the following conversion of my 'standard LCD driver' should work but no promises ...

Code:
        SYMBOL  RSCMDmask = %00000000 ; Select Command register
        SYMBOL  RSDATmask = %01000000 ; Select Data register

        SYMBOL  get       = b11
        SYMBOL  bite      = b12
        SYMBOL  rsbit     = b13

    PowerOnReset:

        GOSUB InitialiseLcd

    DisplayTopLine:

        EEPROM 6,("Hello")

        FOR get = 6 TO 10
          READ get,bite
          GOSUB SendDataByte
        NEXT

    MoveCursorToStartOfSecondLine:

        bite = $C0
        GOSUB SendCmdByte

    DisplayBottomLine:

        EEPROM 11,("World!")

        FOR get = 11 TO 16
          READ get,bite
          GOSUB SendDataByte
        NEXT

        END

    InitialiseLcd:

        I2CSLAVE $74, I2CSLOW, I2CBYTE
	  
        FOR get = 0 TO 3
          READ get,bite
          GOSUB SendCmdByte
        NEXT

        ' Byte commands - To configure the LCD

        EEPROM 0,( $28 )    ; %00101000 %0010NF00   Display Format
        EEPROM 1,( $0C )    ; %00001100 %00001DCB   Display On
        EEPROM 2,( $06 )    ; %00000110 %000001IS   Cursor Move

                            ; N : 0 = 1 Line        1 = 2 Lines
                            ; F : 0 = 5x7 Pixels    1 = N/A
                            ; D : 0 = Display Off   1 = Display On
                            ; C : 0 = Cursor Off    1 = Cursor On
                            ; B : 0 = Cursor Steady 1 = Cursor Flash
                            ; I : 0 = Dec Cursor    1 = Inc Cursor
                            ; S : 0 = Cursor Move   1 = Display Shift

        EEPROM 3,( $01 )    ; Clear Screen

        RETURN

    SendCmdByte:

        rsbit = RSCMDmask               ; Send to Command register

    SendDataByte:

        I2CWRITE rsbit,( bite )         ; Send to LCD
	  
        rsbit = RSDATmask               ; Send to Data register next

        RETURN
You might have to tweak the initialisation bytes and I may have entirely misunderstood something, but fingers crssed :)
 

nfk

Senior Member
Hippy,

I am very grateful indeed for your help. It's late now but I'll go through this in the morning and see if I can get it to work.

Once again, many thanks!

Regards,
Nigel
 

nfk

Senior Member
Hippy,

So nearly there!!!



Okay, I have tried your code. I made one small change where you used 'get' which I think is a reserved word so I changed it for 'gett' and the address of the LCD which is 76 rather than 74.

The result (shown in the photograph) is that I get a musical note instead of the "H" in "Hello" and the rest of the screen fills up with arrow characters. As an experiment I then tried writing "Hello Hippy!" and again the "H" was changed for a musical note. This led me to take a look at the character sets on pages 11 to 15 of the datasheet and sure enough character sets 'F' and 'R' are different (non-ASCII) and have a musical note symbol instead of the "H"! I guess I could work out a routine for converting the characters before sending them to the LCD but this seems rather a rather round-about way of doing the job. And anyway, I also notice that in character set 'R' the blank space symbol, i.e. " " is replaced with an arrow character (the one that is filling up the rest of the screen) so this leads me to believe that character set 'R' is being used. [Edit - I have now confirmed this].

The question is therefore, have you any idea how I can switch character sets?

Oh, nearly forgot...the second line didn't work - not sure why that was. However, I've tried lengthening the first line out to 32 characters and it seems to wrap so it's not such a problem.

Regards,
Nigel

Code:
        SYMBOL  RSCMDmask = %00000000 ; Select Command register
        SYMBOL  RSDATmask = %01000000 ; Select Data register

        SYMBOL gett=b11
        SYMBOL bite=b12
        SYMBOL rsbit=b13

    PowerOnReset:

        GOSUB InitialiseLcd

    DisplayTopLine:

        EEPROM 6,("Hello")

        FOR gett = 6 TO 10
          READ gett,bite
          GOSUB SendDataByte
        NEXT

    MoveCursorToStartOfSecondLine:

        bite = $C0
        GOSUB SendCmdByte

    DisplayBottomLine:

        EEPROM 11,("World!")

        FOR gett = 11 TO 16
          READ gett,bite
          GOSUB SendDataByte
        NEXT

        END

    InitialiseLcd:

        I2CSLAVE $76, I2CSLOW, I2CBYTE
	  
        FOR gett = 0 TO 3
          READ gett,bite
          GOSUB SendCmdByte
        NEXT

        ' Byte commands - To configure the LCD

        EEPROM 0,( $28 )    ; %00101000 %0010NF00   Display Format
        EEPROM 1,( $0C )    ; %00001100 %00001DCB   Display On
        EEPROM 2,( $06 )    ; %00000110 %000001IS   Cursor Move

                            ; N : 0 = 1 Line        1 = 2 Lines
                            ; F : 0 = 5x7 Pixels    1 = N/A
                            ; D : 0 = Display Off   1 = Display On
                            ; C : 0 = Cursor Off    1 = Cursor On
                            ; B : 0 = Cursor Steady 1 = Cursor Flash
                            ; I : 0 = Dec Cursor    1 = Inc Cursor
                            ; S : 0 = Cursor Move   1 = Display Shift

        EEPROM 3,( $01 )    ; Clear Screen

        RETURN

    SendCmdByte:

        rsbit = RSCMDmask               ; Send to Command register

    SendDataByte:

        I2CWRITE rsbit,( bite )         ; Send to LCD
	  
        rsbit = RSDATmask               ; Send to Data register next

        RETURN
 
Last edited:

hippy

Ex-Staff (retired)
Whoot ! Looks like we're getting there. This is usually the way driver design goes; get something half working, re-read the manual, try again. Thanks for sorting out the mistakes and doing the testing. With something displayed, half the battle is won.

1) Char Set : Probably an initialisation setting error ( or missing initialisation )
2) Missing first letter : Probably timing ( no delay after clear screen )
3) Missing second line : Either of (1), (2) or wrong DDRAM address

I'll look into it and get back to you.
 

hippy

Ex-Staff (retired)
Some things to try, first edit the code ...

EEPROM 0,( $24 ) ' Was $28

I2CWRITE rsbit,( bite )
PAUSE 50 ' Add a delay

Try that and hopefully you might get the first character and have a second line ( maybe not on the second line ). If not it means having to play with the advanced modes, which is a bit more complex but doable. Check the above first, see if it does work :)
 

nfk

Senior Member
Hippy,

Many thanks, we're definitely getting somewhere...



The character set problem still seems to be an issue with the arrows in place of spaces. The "W" of "World" only works correctly in this example because the "W" happens to be in the same place in both character sets. I've looked all over the data sheet but just can't see what controls the character set selection. It seems very odd that they wouldn't use ASCII as the default.

Any ideas?

FYI, below is the current state of the code.

Regards,
Nigel

Code:
        SYMBOL  RSCMDmask = %00000000 ; Select Command register
        SYMBOL  RSDATmask = %01000000 ; Select Data register

        SYMBOL gett=b11
        SYMBOL bite=b12
        SYMBOL rsbit=b13

    PowerOnReset:

        GOSUB InitialiseLcd

    DisplayTopLine:

        EEPROM 6,("Hello")

        FOR gett = 6 TO 10
          READ gett,bite
          GOSUB SendDataByte
        NEXT

    MoveCursorToStartOfSecondLine:

        bite = $C0
        GOSUB SendCmdByte

    DisplayBottomLine:

        EEPROM 11,("World!")

        FOR gett = 11 TO 15
          READ gett,bite
          GOSUB SendDataByte
        NEXT

        END

    InitialiseLcd:

        I2CSLAVE $76, I2CSLOW, I2CBYTE
	  
        FOR gett = 0 TO 3
          READ gett,bite
          GOSUB SendCmdByte
        NEXT

        ' Byte commands - To configure the LCD

        EEPROM 0,( $24 )    ; %00100100 %0010NF00   Display Format
        EEPROM 1,( $0C )    ; %00001100 %00001DCB   Display On
        EEPROM 2,( $06 )    ; %00000110 %000001IS   Cursor Move

                            ; N : 0 = 1 Line        1 = 2 Lines
                            ; F : 0 = 5x7 Pixels    1 = N/A
                            ; D : 0 = Display Off   1 = Display On
                            ; C : 0 = Cursor Off    1 = Cursor On
                            ; B : 0 = Cursor Steady 1 = Cursor Flash
                            ; I : 0 = Dec Cursor    1 = Inc Cursor
                            ; S : 0 = Cursor Move   1 = Display Shift

        EEPROM 3,( $01 )    ; Clear Screen

        RETURN

    SendCmdByte:

        rsbit = RSCMDmask               ; Send to Command register

    SendDataByte:

        I2CWRITE rsbit,( bite )         ; Send to LCD
        pause 50
	  
        rsbit = RSDATmask               ; Send to Data register next

        RETURN
 
Last edited:

Mycroft2152

Senior Member
Since the character set in in ROM, according to the data sheet, you may be SOOL.

You may just have to display the space character to overwrite the arrow and get a clean look.

Are there any markings on the unit to indicate you have a -R Character CGROM? Does the vendor have any other models?

Myc
 

nfk

Senior Member
Myc,

Yes, this idea of the character set being fixed is one that I have been hoping is not true...but I accept that it is a strong possibility. I can't see any markings but they may be hidden somewhere under the plastic covering. What I can't understand is why any designer would want to use a non-ASCII character set - it just seems to make everything difficult. And why would the standard 'clear screen' command not clear the screen? I can't think of any reason why anyone would want little arrows instead of blank spaces. I guess there must be a good reason - but I wonder what it could be???

Cheers,
Nigel
 
Last edited:

Mycroft2152

Senior Member
NFK,

My crystal ball is a little cloudy. one guess that the arrows reperesent a working unit, where as a blank screen is dead. That being the case, the software would fill in the blanks on any display. I admit, that is a real PITA.

Then on the other hand, these may just be surplus units from a commercial produciton run that made their way into the hobby market.

Myc
 

hippy

Ex-Staff (retired)
Aha ... Myc gives the answer on the mystery of how to change the font; you can't ! However, all the CGROM fonts have the normal ASCII but in the wrong places, so it should be a simple conversion job. This will hopefully give a good first pass attempt although some characters won't be right ...

Delete the "SendCmdByte" and "SendDataByte" and replace with ...

Code:
SendCmdByte:

  rsbit = RSCMDmask               ; Send to Command register
  GOTO SendSomeByte

SendDataByte:

  IF bite > $0F THEN
     bite = byte ^ $80
  END IF

SendSomeByte:

  I2CWRITE rsbit,( bite )         ; Send to LCD
  PAUSE 50
	  
  rsbit = RSDATmask               ; Send to Data register next

  RETURN
 

Mycroft2152

Senior Member
Aha ... Myc gives the answer on the mystery of how to change the font; you can't ! However, all the CGROM fonts have the normal ASCII but in the wrong places, so it should be a simple conversion job. This will hopefully give a good first pass attempt although some characters won't be right ...]
Hippy,

Good catch! simple and elegant!

Myc
 

hippy

Ex-Staff (retired)
What I can't understand is why any designer would want to use a non-ASCII character set - it just seems to make everything difficult.
I blame the British Empire for failing to establish itself and dominate properly :)

If it's not the ex-Empire to blame it's who ever broke the tower of Babel.

I suppose there's a designer somewhere who thinks the font mapping is the answer to their dreams. Why .. we may never know.

And why would the standard 'clear screen' command not clear the screen?
That's a subtle one; it is 'clearing the screen', but not how one would expect it to !

What clear screen does is write code $20 to all of the display / memory. For us ASCII-ites that's a space, so cleared screen, but when $20 is a space with an arrow drawn on it ... Tada !

Yes, that makes 'clear screen' near useless as a command, but one presumes anyone designing for the screen would not use that, and will do what you'll have to; issue a Home Command, write spaces, move to line two and write some more spaces.
 

nfk

Senior Member
Very nice indeed and yes, it works!

For the record, here is the latest code which successfully writes...

"The top line and"
"the bottom line!"

...on the screen.

Code:
        SYMBOL  RSCMDmask = %00000000 ; Select Command register
        SYMBOL  RSDATmask = %01000000 ; Select Data register

        SYMBOL gett=b11
        SYMBOL bite=b12
        SYMBOL rsbit=b13

    PowerOnReset:

        GOSUB InitialiseLcd

    DisplayTopLine:

        EEPROM 6,("The top line and")
'       EEPROM 6,("                ")    Use this line as a guide for how wide the screen is

        FOR gett = 6 TO 21
          READ gett,bite
          GOSUB SendDataByte
        NEXT

    MoveCursorToStartOfSecondLine:

        bite = $C0
        GOSUB SendCmdByte

    DisplayBottomLine:

        EEPROM 22,("the bottom line!")
'       EEPROM 22,("                ")    Use this line as a guide for how wide the screen is

        FOR gett = 22 TO 37
          READ gett,bite
          GOSUB SendDataByte
        NEXT

        END

    InitialiseLcd:

        I2CSLAVE $76, I2CSLOW, I2CBYTE
	  
        FOR gett = 0 TO 3
          READ gett,bite
          GOSUB SendCmdByte
        NEXT

        ' Byte commands - To configure the LCD

        EEPROM 0,( $24 )    ; %00100100 %0010NF00   Display Format
        EEPROM 1,( $0C )    ; %00001100 %00001DCB   Display On
        EEPROM 2,( $06 )    ; %00000110 %000001IS   Cursor Move

                            ; N : 0 = 1 Line        1 = 2 Lines
                            ; F : 0 = 5x7 Pixels    1 = N/A
                            ; D : 0 = Display Off   1 = Display On
                            ; C : 0 = Cursor Off    1 = Cursor On
                            ; B : 0 = Cursor Steady 1 = Cursor Flash
                            ; I : 0 = Dec Cursor    1 = Inc Cursor
                            ; S : 0 = Cursor Move   1 = Display Shift

        EEPROM 3,( $01 )    ; Clear Screen

        RETURN

SendCmdByte:

	  rsbit = RSCMDmask               ; Send to Command register
	  GOTO SendSomeByte

	SendDataByte:

	  IF bite > $0F THEN
	     bite = bite ^ $80
	  END IF

	SendSomeByte:

	  I2CWRITE rsbit,( bite )         ; Send to LCD
		  
	  rsbit = RSDATmask               ; Send to Data register next

	  RETURN
Note that I have removed the pause - it wasn't required. Timing doesn't seem to be an issue.

Next I'm going to mess around with the 'Home' command and see if I can locate data in specific places on the screen.

Cheers!
Nigel
 
Last edited:

hippy

Ex-Staff (retired)
Glad it's all working. Addressing individual locations should be fairly easy ...

bite = $80 | position
GOSUB SendCmdByte

where position is $00 up for first line, $40 up for second.
 

nfk

Senior Member
Thanks for that Hippy,

It all seems to be working quite nicely now thanks to you!

Next project here we come...

Regards,
Nigel
 
Top