I2C BASIC HELP PLEASE

Ian

Member
can somebody please head me in the right direction, got a i2c lcd, tried all i can think of, it only displays the initial turn on blocks, no text, code as follows...
Code:
#PICAXE 08M2   'Identify the Picaxe being used.
    PAUSE 500    ; WAIT FOR LCD TO INTIIALIZE
    hi2csetup i2cmaster,$4E,i2cslow,i2cbyte     ; SETUP I2C ADDRESS FOR LCD
MAIN:
    WRITEI2C 0,(254,1,255)        ; CLEAR SCREEN
    PAUSE 30                   ; WAIT FOR LCD TO PROCESS REQUEST
    WRITEI2C 0,(254,128,255)        ; MOVE TO START OF FIRST LINE
    PAUSE 10                   ; WAIT FOR LCD TO PROCESS REQUEST
    WRITEI2C 0,("HELLO",255)     ; OUTPUT MESSAGE
    PAUSE 10                   ; WAIT FOR LCD TO PROCESS REQUEST
    END
 

AllyCat

Senior Member
Hi,

Welcome to the forum. We probably need a product number / link for your particular "I2C LCD".

However, a large number of such devices use an "I2C Expander" (on a backpack) to convert I2C to the 8-bits parallel data + control lines required by a native LCD controller. Since the expanders are normally byte-wide (8 bits), 4 bits are allocated to "control lines" (R/W and backlight might not be actually used) and the data is handled as two nibbles (4 bits) transmitted in series. Thus the I2C data which must be sent to the "LCD" is far more complex than the simple "RS232" serial sent to "intelligent" LCD displays such as the AXE133/4. There are numerous threads on the topic, but first we should identify if this is your specific issue.

Cheers, Alan.
 

Ian

Member
Hi,

Welcome to the forum. We probably need a product number / link for your particular "I2C LCD".

However, a large number of such devices use an "I2C Expander" (on a backpack) to convert I2C to the 8-bits parallel data + control lines required by a native LCD controller. Since the expanders are normally byte-wide (8 bits), 4 bits are allocated to "control lines" (R/W and backlight might not be actually used) and the data is handled as two nibbles (4 bits) transmitted in series. Thus the I2C data which must be sent to the "LCD" is far more complex than the simple "RS232" serial sent to "intelligent" LCD displays such as the AXE133/4. There are numerous threads on the topic, but first we should identify if this is your specific issue.

Cheers, Alan.
thank you for your quick response Alan. please correct me if i'm wrong, it has 4 pins, gnd, vcc, sda, and scl, i've connected them to the correct picaxe pin, isn't it just a matter of running that code and it should work?
 

Ian

Member
thank you for your quick response Alan. please correct me if i'm wrong, it has 4 pins, gnd, vcc, sda, and scl, i've connected them to the correct picaxe pin, isn't it just a matter of running that code and it should work? , its an ebay generic, yes it has a piggyback pcb , here is the link..

 

AllyCat

Senior Member
Hi,

No. Almost all I2C modules will have those pins, but the actual data transmitted may be totally different (the code you've listed appears to be RS232 Serial data for an AXE133 or similar). As I said, we need the type / model number of your "I2C LCD", or at least a photo of its PCB (rear side) if you have no other details.

UPDATE: Yes, that's an I2C expander "backpack" shown in the rear photo. It's too late at night for me to do a full search of the forum, but try the code in Post #6 HERE. That particular listing doesn't appear to even specify the I2C address, so you might need to identify that as well.

PS: Most of that complication gets "hidden" in an Arduino "Library" !

Cheers, Alan.
 

inglewoodpete

Senior Member
I see that you have used some "commands" that were originally intended for the AXE133 serial interface for a 16x2 LCD. Eg:WRITEI2C 0,(254,1,255) ;

The AXE133 is a "smart" interface (that actually uses another PICAXE chip) to initialise the LCD and change simple commands into the more complex commands that the LCD requires. This solution is by far the simplest solution but, as you are finding, not the cheapest in dollar terms.

On the other hand, you have bought "dumb" i2c to LCD interface and now need to configure code that will get this interface to do things like initialise the LCD to get it to a state where it can clear its screen, place the cursor and display text. Just initialising the LCD screen requires a series of commands specific to your particular backpack and its interconnect with the LCD.

It can be likened to jumping into the deep end a a swimming pool when you haven't learned to swim yet. And I use the word "yet" because, depending on your skill level and understanding of what is required to get the LCD working, you CAN make it work. It will be a steep learning curve. However, stick with it - many forum members are prepared to help you get your LCD working. You will have to do a lot of the research and work yourself - we can guide you when you hit a snag.
 

Ian

Member
I see that you have used some "commands" that were originally intended for the AXE133 serial interface for a 16x2 LCD. Eg:WRITEI2C 0,(254,1,255) ;

The AXE133 is a "smart" interface (that actually uses another PICAXE chip) to initialise the LCD and change simple commands into the more complex commands that the LCD requires. This solution is by far the simplest solution but, as you are finding, not the cheapest in dollar terms.

On the other hand, you have bought "dumb" i2c to LCD interface and now need to configure code that will get this interface to do things like initialise the LCD to get it to a state where it can clear its screen, place the cursor and display text. Just initialising the LCD screen requires a series of commands specific to your particular backpack and its interconnect with the LCD.

It can be likened to jumping into the deep end a a swimming pool when you haven't learned to swim yet. And I use the word "yet" because, depending on your skill level and understanding of what is required to get the LCD working, you CAN make it work. It will be a steep learning curve. However, stick with it - many forum members are prepared to help you get your LCD working. You will have to do a lot of the research and work yourself - we can guide you when you hit a snag.
thanks mate, where do i start?
 

AllyCat

Senior Member
Hi,

Morning now :) . Yes, the (whole) thread that I linked above seems quite a good starting point. The program in #4 is partially in French, so we may be able to find another if the additional level complexity causes difficulties, but I "expect" the program from hippy in #6 to work well. In principle, it's only necessary to add two "Subroutines" (which do things similar to the Arduino's Library):

The first subroutine is needed to create the sequence of I2C commands that are required to send a single byte to the LCD. The second, as mentioned by Inglewoodpete, is to send a sequence of control bytes (perhaps via the first subroutine) to configure the "LCD controller". This starts by telling the LCD to receive data nibbles (4 bits wide) instead of its native bytes (8 bits wide). That's perhaps the most "challenging" part, because nothing can work until it's done.

However, if you need to identify the Slave Address, then the code in post 7 is NOT a good starting point, but I have modified it in post #14. It's quite complicated, but if you just copy and paste the whole program into the PICaxe Editor and change the 3rd line to: #define picaxe08 , then Programming that into your PICaxe should also test if the hardware and program downloading are working correctly.

Cheers, Alan.
 

Ian

Member
i've been an electronics tinkerer for 40 years, but just started with picaxe, and this is my first forum so please bear with me.
a couple of questions please.
1. i'm confused because the code i posted at the beginning of this thread came straight out of the axe033.pdf, on page 6 titled 'i2c programming details, so why the heck would they put that there?
2. this is my first contact with forums, so i am unfamiliar with post numbers, where do i find post#14 that alan mentions above.?
Regards
Ian
 

neiltechspec

Senior Member
axe033 pdf page 6 ?????, it only has 5 pages without anything about i2c.

post number is on extreme right at the top of each post, eg.. your last one was post 10, this one will be post 11.
 

AllyCat

Senior Member
Hi,

AFAIK (As Far As I Know) the AXE033 is an "Obsolete" LCD display which uses a (PICaxe) "custom" IC that has both "semi-intelligent" RS232 and I2C interfaces. The I2C interface (data protocol) is specific to that custom IC which apparently is still available from the PICaxe store and (when mounted on an assembled PCB) does much more (i.e. has more "intelligence") than the I2C backpack on your LCD. One of the "advantages" of PICaxe is that it is highly "Backwards Compatible" and supports "Legacy" devices (e.g. ICs that have been in your "spares" box for 10 years ;) ), but this does mean that some of the information in the Manuals may be obsolete, misleading, or even occasionally "wrong".

I2C is just a specific type of hardware bus which defines the basic method of transmitting addresses and data bytes. But the actual data (protocol) will be totally dependent of the device receiving that data. Those LCDs have a "display controller" which receives quite complex commands on an 11-bit wide parallel interface (8 data bits plus 3 control lines). Sometimes it will be driven directly from an "intelligent" microcontroller (as is the case with the PICaxe or custom chip in the AXE 133 or 033) or by a "dumb" interface such as the I2C expander in your display's I2C backpack. Thus your driving software needs to overcome the "hurdles" of the basic I2C data bus, the I2C Expander chip and the LCD display controller.

It may depend which forum software you're using (e.g. the 'phone App may be different) but the post number (of the viewed thread) should be in the top RH corner of each post. IIRC (If I Recall Correctly) , #14 was the last post in that particular thread.

Cheers, Alan.
 

Ian

Member
thanks all, the the french code worked as is!!! (pity i cant speak french!)
has anybody developed any subroutines to handle lcds, eg: displayinit: , would setup the display
then perhaps let message="hello world", then gosub displaydata:, would output the message to the lcd?
cheers
ian
 

neiltechspec

Senior Member
Right, it's listed as an optional clock upgrade. Way too pricy for me to have considered, thats why I have never looked at that.

I wouldn't consider it for any future projects as the DS1307 is way to inacurate (drifts lots) as I found out years ago,
so threw them away & replaced them with DS3231.

The i2c may possibly have been useful, but it uses 1 more I/O pin(4 wires) than serial (3 wires). I
always seem to use all available I/O for other things except when using DS3231's, only ever used 3 of those anyway.

Neil.
 

inglewoodpete

Senior Member
Neil, please find attached my axe033.pdf with the page 6 titled 'i2c programming details'
Since Neil has missed what has caused your concerns Ian, I will provide this answer.

The i2c backpack that you purchased and the AXE033 are i2c slaves but configured quite differently. If you want to display text on the LCD screen using your backpack, you must use an i2c Master processor (your PICAXE chip) and a protocol (quite complicated) that the backpack is expecting.

If you use the AXE033, its i2c slave interface has been configured differently (much smarter) and you can enter much simpler commands.
 
Last edited:

AllyCat

Senior Member
Hi,

First, to qualify my previous post, I think the AXE033 (LCD) is obsolete because Rev Ed consider all LCDs to be obsolete and prefer to supply the equivalent OLED displays, which carry a Y (for Yellow) suffix. I believe the AXE033Y, which was out-of-stock for some time, is now available, but more costly than the similar AXE133Y. The AXE133Y doesn't have an I2C interface, but it uses a standard 18M2 PICaxe chip which can be reprogrammed with alternative or additional features. AFAIK the 033 and 133 use the "characters" 0 - 7 differently (for User-Defined "Strings" and Characters respectively) and both use 253 - 255 "unconventionally" (replacing the native characters). So I have some long-term plans to re-organise the 133 code, probably within an 08M2 to drive an I2C backpack display (but don't hold your breath).
... the french code worked as is!!! (pity i cant speak french!)
So details such as the I2C Slave address and your hardware functionality have been verified. Actually, Google Translate seems to do a very good job on that page, so you only need to notice that "EnvoiByteCommInit: " represents "Initialise_SendCommandByte:", etc. ;)

has anybody developed any subroutines to handle lcds, eg: displayinit: , would setup the display
then perhaps let message="hello world", then gosub displaydata:, would output the message to the lcd?
The "French" and hippy's code in those posts #4 and #6 do have some subroutines although there might be slightly better versions in other threads on the forum. But PICaxe Basic subroutines really just start with a label (having a colon suffix) and finish with a RETURN, they don't support sophisticated features such as Parameter-passing, Local variables or String-handling. These can be emulated to some extent by using the MACRO facility, but my preference is to KISS (Keep It SimpleS).

Thus, there is no direct way to handle "Strings" of characters for subroutines and it depends where the "text" is to be stored. For characters stored in RAM you can use POKE/PEEK commands or the @bptr variable; within the EEPROM use READ{TABLE} of characters stored by WRITE or {TABLE}DATA commands. Or something like LOOKUP b1, ("Hello World") ,b0 is commonly used directly within a (FOR .. NEXT) program loop.

Cheers, Alan.
 

Ian

Member
thanks, ive taken your google translate advice and converted it to english, then i've modified the code (within the ;=====) to try to display a pot% reading on the lcd, but the second line only displays 4 blocks, what am i doing wrong?
Regards
Ian

code as follows...
Code:
;Use expander PCF8574 with LCD MM 19082017
;Test minimum LCD1602
;    SCL sur C.1
;    SDA sur C.2
#picaxe 08M2
dirsC =%000111
symbol rsbit=bit0
symbol cpt=b1
symbol car=b2
symbol dat=b3
symbol vari= w13

SYMBOL VIN = C.4
symbol potval = w12

    setfreq M32            
; Initialisation I2C 4 bits , etc ********
    hi2csetup i2cmaster,%01001110, i2cslow_32, i2cbyte       
; Initialisation LCD *********
    for cpt=0 to 5
        lookup cpt,($33,$32,$28,$c,$6,$01),car
        gosub Initialise_SendCommandByte
    next
    pause 100    ;init LCD 
;=====================================================================
; Display text first line heading   ********           
    car= 128    'set cursor to line 1, POS 1
    gosub SendByteComm   
    for cpt=0 to 4
        lookup cpt,("Pot %"),car
        GOSUB SendByteData   
    next

DO
    readadc vin,potval
; Display text line 2 data    ********           
    car= 192    'set cursor to line 2, POS 1
    gosub SendByteComm   
    for cpt=0 to 3
        lookup cpt,(potval),car
        GOSUB SendByteData   
    next
    pause 100       ; wait 100ms for next reading
loop            ;loop

;=====================================================================
       
; Sub sending to LCD via I2C *************
Initialise_SendCommandByte:
    pause 15
SendByteComm:
    rsbit=0
SendByteData:
;1st Half
    dat=car & $F0 | %1000 | rsbit ;%1000 for lighting
    hi2cout (dat)
    pause 2       
    dat=dat | %1100
    hi2cout (dat)        ;pulse sur E cad P2
    pause 2               ;pause 2 for 32 MHz
    dat=dat | %1000        ;end pulse
    hi2cout (dat)
    pause 2   
;2nd Half
    dat=car & $0F * 16 | %1000 | rsbit
    hi2cout (dat)
    pause 2
    dat=dat | %1100
    hi2cout (dat)
    pause 2
    dat=dat | %1000 & %1011
    hi2cout (dat)   
    rsbit=1
    return
 

AllyCat

Senior Member
Hi,
lookup cpt,(potval),car
At the most optimistic (in a SERTXD or SEROUT..command) that should use #potval to automatically convert the single Word value into a string of ASCII characters (i.e the individual digits which make up the number), but unfortunately LOOKUP deosn't work that way.

LOOKUP requires a sequence of individual bytes (in this case representing ASCII characters) separated by commas. The only concession is that an explicit string of ASCII characters (within quotes) is automatically expanded out to the individual characters / bytes separated by commas (e.g. "Hello" --> "H" , "e" , "l" , "l" , "o" --> 72 , 101 , 108 , 108 , 111 ).

To simplify this a little, PICaxe Basic has the BINTOASCII command so that you can write:
Code:
BINTOASCII potval , b10 , b11 , b12 , b13 , b14     ; 5 bytes must be named when using a source Word value
FOR cpt = 1 to 4
LOOKUP cpt , (b10, b11 , b12 , b13 , b14 ) , car    ; Note first byte is at cpt = 0
.....etc.
[ E&OE ;) ]

Cheers, Alan.
 

Ian

Member
Thanks Alan, where can i learn these things, is there a picaxe for dummies i haven't found, with examples?, im and old dog trying to learn new tricks!!!
Cheers
Ian
 

lbenson

Senior Member
is there a picaxe for dummies
So far as I know, the only specific PICAXE book is ancient, with many code examples which would now be deprecated. Your best bet might be to read through Manual 3, although that also is dated.
 

AllyCat

Senior Member
Hi,

No I don't think there's a "PICaxe for Dummies"; a few members have posted "example" code from books that they're read, but IMHO they're generally of a poor standard (educationally). So I recommend reading the (free) PICaxe Manuals 1, 2 (p/o) and 3 (or they might be called "sections" in the on-line version). Manual 2 is the main problem, in that IMHO there are "too many" commands, so you should only quickly "scan" them to see what exists. The trouble is that some commands are intended only for young novices (e.g Forward and Backward), and many are ONLY for the X2 chips. I would like to see (at least) three separate lists of commands aimed at the relevant user(s). There is also the issue of "real" versus the "pseudo" (System Macro) commands.

However an advantage of BASIC is that many of the commands are reasonably "plain English" so you can guess what might be appropriate and then read the On-Line-Reference, or Manual 2, for the exact details of how it works. Also there is the "Finished Projects" and in Particular the Code Snippets sections of the forum, for examples of code. Then if you have a specific project/problem in mind, the forum Search Engine is better than it used to be, but you may still have more success doing a global Google search with "PICaxe" as one of the search terms.

Cheers, Alan.
 

Ian

Member
thanks, that worked!!!, now ive substituted the pot for an ir sensor tsop4838, ran the program, it displayed varying data which changed when i pressed the sony remote buttons, so i assumed its working ok, so i changed the adc command to irin to try to show the code of the pressed button, but the second line is blank, is there something i'm missing?, only code i changed is the pot to irval declaration, and the adc changed to irin
Cheers
Ian

Code:
;Use expander PCF8574 with LCD MM 19082017
;Test minimum LCD1602
;    SCL sur C.1
;    SDA sur C.2
#picaxe 08M2
dirsC =%000111
symbol rsbit=bit0
symbol cpt=b1
symbol car=b2
symbol dat=b3
symbol vari= w13

SYMBOL VIN = C.4
symbol irval = w12

    setfreq M32            
; Initialisation I2C 4 bits , etc ********
    hi2csetup i2cmaster,%01001110, i2cslow_32, i2cbyte       
; Initialisation LCD *********
    for cpt=0 to 5
        lookup cpt,($33,$32,$28,$c,$6,$01),car
        gosub Initialise_SendCommandByte
    next
    pause 100    ;init LCD 

; Display text first line heading   ********           
    car= 128    'set cursor to line 1, POS 1
    gosub SendByteComm   
    for cpt=0 to 9
        lookup cpt,("Ir Code is"),car
        GOSUB SendByteData   
    next
;=====================================================================
DO
    irin C.3,w12
; Display text line 2 data    ********           
    car= 192    'set cursor to line 2, POS 1
    gosub SendByteComm   
    BINTOASCII irval , b10 , b11 , b12 , b13 , b14     ; 5 bytes must be named when using a source Word value
    FOR cpt = 0 to 4
        LOOKUP cpt , (b10, b11 , b12 , b13 , b14 ) , car    ; Note first byte is at cpt = 0
            GOSUB SendByteData   
        next
    pause 100       ; wait 100ms for next reading
loop            ;loop

;=====================================================================
       
; Sub sending to LCD via I2C *************
Initialise_SendCommandByte:
    pause 15
SendByteComm:
    rsbit=0
SendByteData:
;1st Half
    dat=car & $F0 | %1000 | rsbit ;%1000 for lighting
    hi2cout (dat)
    pause 2       
    dat=dat | %1100
    hi2cout (dat)        ;pulse sur E cad P2
    pause 2               ;pause 2 for 32 MHz
    dat=dat | %1000        ;end pulse
    hi2cout (dat)
    pause 2   
;2nd Half
    dat=car & $0F * 16 | %1000 | rsbit
    hi2cout (dat)
    pause 2
    dat=dat | %1100
    hi2cout (dat)
    pause 2
    dat=dat | %1000 & %1011
    hi2cout (dat)   
    rsbit=1
    return
 

Vlkap

New member
can somebody please head me in the right direction, got a i2c lcd, tried all i can think of, it only displays the initial turn on blocks, no text, code as follows...
Code:
#PICAXE 08M2   'Identify the Picaxe being used.
    PAUSE 500    ; WAIT FOR LCD TO INTIIALIZE
    hi2csetup i2cmaster,$4E,i2cslow,i2cbyte     ; SETUP I2C ADDRESS FOR LCD
MAIN:
    WRITEI2C 0,(254,1,255)        ; CLEAR SCREEN
    PAUSE 30                   ; WAIT FOR LCD TO PROCESS REQUEST
    WRITEI2C 0,(254,128,255)        ; MOVE TO START OF FIRST LINE
    PAUSE 10                   ; WAIT FOR LCD TO PROCESS REQUEST
    WRITEI2C 0,("HELLO",255)     ; OUTPUT MESSAGE
    PAUSE 10                   ; WAIT FOR LCD TO PROCESS REQUEST
    END
Hello Ian,
Try follows code for Arduino I2C LCD with PICAXE 08M2>
 

Attachments

Top