Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Oshon Software I2C LCD Coding

Status
Not open for further replies.
Well!! I haven't a real PCF8574 to check it out so If it works with two line I must work with four line..
Code:
Proc i2clcdbegin()
    WaitMs 15    //// initial wait time for display
    Call cmdwrite(0x33)   /// These next two lines are a kind of pre-amble  you MUST send 0x30 three times
    WaitMs 5
    Call cmdwrite(0x32)  //
    WaitMs 5
    Call cmdwrite(0x2c)  // LCD funtion set  4 bits and two lines.. ( there are always two lines.. They are address 0x80 <-> 0xAF and 0xC0 <-> 0xEF )
    WaitMs 1                   //
    Call cmdwrite(0xc)   //  Display on
    WaitMs 1
    Call cmdwrite(0x6)   // Incrementing
    WaitMs 1
    Call cmdwrite(0x1)   /// Clear display and set position to first char
End Proc
Same as in the datasheet..
 
Code with the adjusted time.

Waitms to 20Ms

Code:
Proc i2clcdbegin()
    WaitMs 20
    Call cmdwrite(0x33)
    WaitMs 5
    Call cmdwrite(0x32)
    WaitMs 5
    Call cmdwrite(0x2c)
    WaitMs 1
    Call cmdwrite(0xc)
    WaitMs 1
    Call cmdwrite(0x6)
    WaitMs 1
    Call cmdwrite(0x1)
End Proc

WaitMs to 5
Code:
Proc cmdwrite(cmd As Byte)
    Dim hi As Byte
    Dim lo As Byte
        lo = ShiftLeft(cmd, 4)
        hi = cmd And 0xf0
        lo = lo And 0xf0
                cmd = hi + bl
            I2CWrite sda, scl, 0x4e, cmd, cmd
                cmd = cmd + 0x4
            I2CWrite sda, scl, 0x4e, cmd, cmd
                cmd = cmd - 0x4
            I2CWrite sda, scl, 0x4e, cmd, cmd
            
            WaitMs 5
        
                cmd = lo + bl
            I2CWrite sda, scl, 0x4e, cmd, cmd
                cmd = cmd + 0x4
            I2CWrite sda, scl, 0x4e, cmd, cmd
                cmd = cmd - 0x4
            I2CWrite sda, scl, 0x4e, cmd, cmd
End Proc

No effect!

In the meantime I have also made my I2C cable as short as possible.
To prevent a possible interference with other signals. But no effect.
 
Change your init routine slightly

This is as correct as I can get it... I can't test it until tonight.

Code:
Proc i2clcdbegin()
    WaitMs 20
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    WaitMs 5
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    WaitMs 5
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    WaitMs 5
    Call cmdwrite(0x2c)
    WaitMs 1
    Call cmdwrite(0xc)
    WaitMs 1
    Call cmdwrite(0x6)
    WaitMs 1
    Call cmdwrite(0x1)
End Proc
 
copied my code. Below.
I have turned off three code lines.
But with this the display fails and no longer shows any sign or image.

Code:
Proc i2clcdbegin()
    WaitMs 20  'wait time for display
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    WaitMs 5
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    WaitMs 5
    I2CWrite sda, scl, 0x4e, 0x34, 0x34
    WaitMs 1
    I2CWrite sda, scl, 0x4e, 0x30, 0x30
    'Call cmdwrite(0x33)
    'WaitMs 5
    'Call cmdwrite(0x32)
    WaitMs 5
    Call cmdwrite(0x2c)  'LCD function set 4 bits and two lines (there are always two lines.. They are adress 0x80 0xAF and 0xC0 0xEF)
    WaitMs 1
    Call cmdwrite(0xc)  'Display on
    WaitMs 1
    Call cmdwrite(0x6)  'Incrementing
    WaitMs 1
    Call cmdwrite(0x1)  'Clear display and set position to first character
End Proc
 
Just before you sent that new code.
I have done another test with another 2 line display.
I used one and the same code for this. So the green display is running well and the blue one is not.
Then it must go wrong somewhere here? Or am I wrong?

Code:
Call i2clcdbegin()
Call cmdwrite(0x80)  '0x80 = 1e line
Call printstr1()
Call cmdwrite(0xc0)  '0xc0 = 2e line
Call printstr2()
Call cmdwrite(0x94)  '0x94 = 3e line
Call printstr3()
Call cmdwrite(0xd4)  '0xd4 = 4e line
Call printstr4()

IMG_20191030_175101.jpg


IMG_20191030_175010.jpg
 
What did our other colleague mean by this?

So the address of each line is 0x00,0x40,0x10,0x50. These numbers need the top bit added before being sent as a command.

I regularly come across these addresses in datasheets. (0x00,0x40,0x10,0x50.)
But if I use it in this program, it doesn't work either.
Why do you use these hex codes in this program? (0x80,0xc0,0x94,0xd4)
That is a piece that I still do not fully understand
 
The address starts at 0x80 as you know this is the starting figure.. So line two is 0x40 add together = 0xC0.. Line three 0x10 + 0x80 = 0x90... etc.. Nothing magical...

I need to test the code I sent you as I think another I2C write is needed for each command..

Data sheet said that you must send three sets of 0x30 then the function command 0x2C.. but the command write has upper and lower so 0x33 is seen as two and then I usually send 0x32.. then finally 0x2C... For most displays this works..
 
Finally I come across a list that explains a few things.
This is the explanation for 4x20, but the list can also be used for 2x16.

I assume.

20x4_In_2_Line_Mode2.png


Data sheet said that you must send three sets of 0x30 then the function command 0x2C.. but the command write has upper and lower so 0x33 is seen as two and then I usually send 0x32.. then finally 0x2C... For most displays this works..

I only half understand what you are saying here, but I will try to figure it out.
 
I now also understand that the problems cannot be caused by this.
Because if this address is incorrect, you will see in the display that the beginning of the sentence starts at a different location.
 
Hi Ian,
You don't believe it but the problem is solved!
See below the code!

What makes the big difference is the reversal of the clear display and the incrementing.
So first "clear display" then the next step.
As can be seen in the previous diagram.

Code:
Proc i2clcdbegin()
    WaitMs 20  'wait time for display
    Call cmdwrite(0x33)  '33
    WaitMs 5
    Call cmdwrite(0x32)  '32
    WaitMs 1
    Call cmdwrite(0x2c)  'LCD function set 4 bits and two lines (there are always two lines.. They are adress 0x80 0xAF and 0xC0 0xEF)
    WaitMs 1
    Call cmdwrite(0x0c)  'Display on/off control
    WaitMs 1
    Call cmdwrite(0x01)  'Clear display and set position to first character
    WaitMs 1
    Call cmdwrite(0x06)  'Incrementing
End Proc

IMG_20191030_224212.jpg
 
I just tested all other displays and they all work now.
Thank you very much for your patience and your help.
I have learned a lot from I2C in recent days.
It's a nice start!

Enough Still to do!
 
I suspect that the one that didn't work had an original Hitachi HD44780 chip as these were very fussy about initialization order and timing. Most of the newer clones are much more forgiving in this manner. Anyway, congratulations and good luck with the rest of your project.

Mike.
 
Hi again,
I try to send a variable in this setup but the compiler keeps giving a warning.
What am I doing wrong here?

Code:
Proc printstr1()
    Dim x As Byte
    Dim ch As Byte
    Dim tw As Byte
        For x = 0 To 19
            Adcin 2, tw
            ch = LookUp("Test"(", #tw,") "), x
            Call datawrite(ch)
        Next x
End Proc
 
The lookup function has no formatting functionality.. You need to build the string first..

I would write a function to take a string and a value and format it myself.. But I've been doing this for years so it's easy for me..
 
Oke,
Am I close?

Code:
Proc printstr1()
    Dim x As Byte
    Dim ch As Byte
    Dim tw As Byte
    Adcin 2, tw
        For x = 0 To 19 
            ch = result(x)
            Call datawrite(ch)
        Next x
End Proc                                         

Function result(tw As Byte) As Byte
    result = tw
End Function
 
Vladimir does allow a better concept using "strings" but it's an add-on,
I did this..

Code:
dim str1 as string

str1 = "Testing = " + #data
call printstr( str1)

Proc printstr(str As String) // takes a string
  Dim x As Byte
  Dim ch As Byte
  Dim idx As Byte
  idx = Len(str) - 1        /// work out its size
  For x = 0 To idx
           ch = Asc(str) // grab the first character
            Call datawrite(ch) // print it
           str = LRotateStr(str) /// rotate so new character can be printed
Next x
End Proc
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top