News:

Let's find out together what makes a PIC Tick!

Main Menu

i2c 2 line LCD not using "Print"

Started by TimB, Jul 01, 2023, 08:54 AM

Previous topic - Next topic

TimB


Hi all

I am in the middle of converting the i2c lcd routines that use busout to the software i2c routines Les wrote

Then it dawned on me that I'm already using print for my GLCD and this display is an aux display.

Has anyone got any clues on how to make this useable with out Print?

I was thinking to hijack the rsout command but it does not help with the AT commands eg what line and char on the display

Any pointers appreciated.

Tim

flosigud

What display are you refering to?

flosigud

I have a driver for SSD1306 both SPI and I2C without PRINT and few other things. I just tried to post that but was unable to attach the zip.

TimB


Hi and thanks

My GLCD code is for a ST7565 via SPI and it replaces Print and adds more routines like changing the font, dump from ram to screen etc. I'm not looking to change it.

I would be interested to see how your routine handles things like Print Dec xyz etc

I have already done most of the work for my i2cLCD 2x16 line i2c code and for now as I only need a few Dec variants I will hard code a few routines so you can specify various functions eg

i2cLCD_PrintDecFloat(3,xyz)

Where the 3 is the number of digits and xyz is the float to be displayed

Cheers

Tim

Fanie

I google'd ST7565 display programming
https://www.ramtex.dk/glcd/glcd07xx.htm

Maybe one of the links will offer something.

Dompie

Hi @TimB , why not let Positron do the work and just print strings.
i2cLCD_PrintString(str$(dec3,xyz))
Or is this not what you mean?

Johan

TimB


Johan

Thanks, I figured it out now. As the screen is small I just make a one line string with room for the null and using string commands write to it

eg

        sMyString = "Result = " + str$(Dec2 fMyFloat)

        i2cLCD_SetCursor(2,1)

        i2cLCDPrintStr(sMyString)



'*******************************************************************************
'* Title  :  i2cLCDPrintStr
'* Input  :  pString as String
'* Notes  :  Prints the contents of the string until > 17 or Null is seen
'*******************************************************************************
    Proc i2cLCDPrintStr(pString as String * 17)

        Dim bIndex as byte = 0
        Dim bTemp1 as Byte
        DIm cNull as 0

        DO

            bTemp1 = pString[bIndex]                                            ' Get the data from the string
            if bTemp1 = CNull then Break                                        ' Break if null
            i2cLCDWrData(bTemp1)                                                ' Print the data

            Inc bIndex
            If bIndex > 17 then Break

        Loop

flosigud

ST7565 seems similar to SSD1306 so drivers for the latter could be used as a start.I just posted mine among the many others.

https://protoncompiler.com/index.php?action=downloads;sa=view;down=18

TimB


Perhaps this thread is not being read fully

I have a extremely well written ST7565 routines. I do not need any others

I wanted to write to a i2c 2x16 lcd. I had some routines that redirected "Print" but as print was already being used I needed another route.

That has been resolved using strings as in another thread.

top204

#9
The compiler's commands do have their benefits, as opposed to procedures, in that they accept multiple parameters and parameter types and modifiers. So bypassing a command's calls to its library subroutine is a good way of giving a lot of flexability to a program's listing.

If the Print command has already beed bypassed, another multiple parameter command can also be bypassed if it is not actually used in a program for its original use, or been bypassed in another library used. For example RSout, HRSout1, HRSout2, HRSout3, HRsout4, RSin, HRSin1, HRSin2, HRSin3, HRSin4 etc...

Then, within the library's include file, add some meta-macros that will make life easier. For example, if using the RSout command to print to an I2C LCD, use the meta macro:

$define Print_I2C RSout

So everytime the Print_I2C name is used in the program's listing, the program will actually use the RSout command that has been bypassed.

I have not made the command bypassing common knowledge or added it to the compiler's manuals for a few reasons:

1. It is easily broken if not understanding what compiler system variables are used in the command's library subroutine, and then they are used in the replacement routines. For example, if displaying decimals or floating point, the compiler uses a lot of system variables, and if not implemented correctly, nonesense will be displayed when they are over-written by commands used in the user's bypass routine.

2. It is a complex method that must only be attempted by a person who understands the compiler's mechanisms.

3. It can easily break a program's operation if not implemented correctly, and then the compiler gets blamed and not the user's understanding of what has been done. I have come across this type of behaviour for over 20 years now, so I keep the compiler's secrets out of the manual, so it is classed as a "development mechanism".

4. If any changes are made to the compiler's underlying operations, it can effect the bypassing of a command, and it will not work correctly. Then, again, the compiler is blamed for improvements that have been made under its hood. :-)

5. The compiler library routines have very specific requirements because it is a controlled environment underneath the compiler hood, and if the controls are not implemented in the user's replacement routines, they will not always work, then, again, the compiler is blamed. :-)

There are other reasons, but they, essentially, follow the above reasons.

The Positron16 compiler does have an underlying InReserveX and OutReserveX mechanism that I experimented with, but was too apprehensive to bring out to the users because it can easily break a program's operation if not implemented carefully, and any system variables used, saved on the stack etc... I may look into it again, and implement it on the Positron8 compiler using the software stack mechanism it has.

It allows up to four extra in and out "commands" with multiple parameters and parameter types and modifiers to be used, then the names changed to something more readable using preprocessor meta-macros. I did use it in the FAT library I created for the PIC24 devices when I first created the mechanism (FileSys24.inc), but that was also when I decided not to make it public, when I found that it could easily make a program not work correctly with some modifiers and some very subtle anomalies produced if it was not implemented correctly and fully. :-)

However, once implemented correctly, a command bypass works extremely well and extremely efficiently.

TimB

#10
Thanks Les!!

Way nicer now

The code is simple
    #Disable Rsout
    $define  Print_I2C Rsout

    @__Rsout_

    Wreg_Byte _bWregCopy                       ; save the W Register

    i2cLCDWrData(_bWregCopy)

    Byte_Wreg _bWregCopy                       ; restore the W Register
    Return

Before
sMyString = "NC " + str$(Dec2 fLastNCResult) + " SH " + str$(Dec1 fLastSHResult)
i2cLCDPrintStr(sMyString)

Now
Print_I2C "NC ", Dec2 fLastNCResult, " SH ", Dec1 fLastSHResult


top204

#11
Glad you got it working Tim.

Try it this way:

Sub __Rsout_()
    _bWregCopy = WREG           ' Save the W Register
    i2cLCDWrData(_bWregCopy)
    WREG = _bWregCopy           ' Restore the W Register
EndSub

Then it is tidier to read and any RAM banks will be managed by the Sub-EndSub directives that still make a standard subroutine, but a subroutine that is better managed by the compiler because it knows what the label is and where the beginning and end of the subroutine is.

With the 18F and enhanced 14-bit core devices, WREG is a bankless SFR, so it can be treated as a variable within the commands, but a very volatile variable that will have its contents changed every few instructions, so it is used temporarily to hold a value. Hence its name: Working Register.