News:

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

Main Menu

Remote Serial LCD

Started by Peter Truman, Jun 03, 2023, 04:40 AM

Previous topic - Next topic

Peter Truman

Hi All

I'm struggling a bit with the following problem

I have a board with a 2x16 alpha numeric LCD (nothing special) - this board has a 16F688 PIC which controls the LCD

My main board (18F25k22) is connected via a ribbon cable - I am passing a simple serial 32 chr string from the main board to the remote board for display on the LCD. The 32 bits comprise 2 x 16 chr lines.

My code constructs the 32 chr string from various subroutines that need to write to the LCD. In general my code is ok but.... I'm struggling with constructing my string when the position is not 1

I refresh the upload string everytime there is a change and send it out to the remote board every 100ms or so in between changes.

So - an example of the data the subroutine sends is

S_Pnt_Line="1,01,Wait... Stopping":GoSub upload
The upload routine works out where to put this string in the 32 chr upload string.
Mostly I generate a full 16 chr string for each line (easy so far)

Problems arise when I want to write to a particular part of the LCD - like this

S_Pnt_Line="1,05,Wait
So I want to insert the word 'Wait' at position 5 on line 1 - without disturbing anything else that may be already on line 1 (so just overwrite 4 chrs at line 1 pos 5)

I've been round the block with this until my brains start running out of my ears - I just can't seem to get it right!

I have a vague recollection of a similar piece of code which I thought I had seen on the old forum?

My code so far (excuse my debugging - I like to write to a terminal as I go - only debugging option I have at the moment)

I'm using the Old IDE and Compiler ver 3.7.3.6

upload:   


S_Tmp=Mid$(S_Pnt_Line,3,2)                                          'extract pos string
B_S_Pos=Val(S_Tmp,Dec)                                              'convert to an integer

S_Dest=Left$(S_Pnt_Line,1)
If S_Dest="1" Then 'convert for upload pos
    B_S_Pos=B_S_Pos-1                                                   'start at upload element 0 for pos 1
Else
    B_S_Pos=B_S_Pos+15                                                  'start at upload element 15 for pos 1
EndIf
B_Length=Len(S_Pnt_Line)-5                                              'length of the string to print
S_Pnt_Line=Right$(S_Pnt_Line,B_Length)                                  'chop off the pos data
Clear B_Upld_Local_1                                                    'clear the element var

HRSOut "<",S_Pnt_Line,">",13

'rewrite the upload string
For B__UP_G=B_S_Pos To B_S_Pos+B_Length-1                               'position each chr appropriately
    S_Up_String[B__UP_G]=S_Pnt_Line[B_Upld_Local_1]                     'add each element
    Inc B_Upld_Local_1
Next B__UP_G



'Make sure everything is printable
For B__UP_G=0 To 31
    If S_Up_String[B__UP_G]<32 Or S_Up_String[B__UP_G]>126 Then         'not printable
        HRSOut "NPC",13
        S_Up_String[B__UP_G]=" "                                        'so replace with a space
    EndIf
Next B__UP_G

 'calculate the crc
Clear B_CRC_LCD                                                         'clear the crc var
For B__UP_G=0 To Len(S_Up_String)                                       
    B_CRC_LCD=B_CRC_LCD+S_Up_String[B__UP_G]                            'just add all the ASCII values together
Next B__UP_G
'HRSOut ">",S_Up_String,"<",Dec3 B_CRC_LCD,13
GoTo send_2_LCD                                                         'jump the refresh routine

send_2_LCD:
RsOut 2,S_Up_String,B_CRC_LCD,3                                         'upload to the display
Clear S_Pnt_Line
BusOut Display,[B_EX_Port]                                              'update display outputs every 100ms

DelayMS 5                                                              'allow display time to complete
Return


If anyone can offer any assistance or point me at some example code I'd be very grateful - many thx in advance

trastikata

If it's an alpha numeric display, then you can use control commands to move the cursor around:

$FE, $02 = Move cursor to beginning of first line
$FE, $C0 = Move cursor to beginning of second line
$FE, $10 = Move cursor left one position
$FE, $14 = Move cursor right one position

Thus place the cursor at whatever position you'd like to start and send te characters to be printed out.

Peter Truman

Hmm. Understood. I'm slightly limited by the fact that I don't want to mess with the code on the remote board (in order to maintain backward compatibility with older systems out there). I had originally decided I would manage the txt in the 32 chr format in the master system. Previously I didn't need to worry about dropping data anywhere other than the start of each line)

I'll change it if I have to but it seems to me it should be possible to stick to the old approach - if only I can figure it out.

trastikata

#3
Quote from: Peter Truman on Jun 03, 2023, 07:53 AMHmm. Understood. I'm slightly limited by the fact that I don't want to mess with the code on the remote board (in order to maintain backward compatibility with older systems out there).

Then use two 16 character string variables that will represent each LCD line to keep track of what is being displayed. Insert the new partial string in those two String variables at whatever position you need by overwriting the old characters and send the entire string to be printed out.

Some basic code to start with:

'String Variables
Dim sLineOne As String * 16
Dim sLineTwo As String * 16

'Initialize the strings
sLineOne = "TEST LINE 1     "
sLineTwo = "TEST LINE 2     "

'Insert string "OK" in Line1 at position 12
'Result should be "TEST LINE 1 OK  "
InsertString(1, 12, "OK")      

End

'Procedure to update the code in the line strings before sending to the display
'bLine = 1 or 2 / Which line to modify
'bPosition = 0 to 15 / overwrite with the new text from this position
'sString = .... / some text to insert 
Proc InsertString (bLine As Byte, bPosition As Byte , sString As String * 16)
    Dim bCounter As Byte
   
    bCounter = 0
   
    If bLine = 1 Then
        While sString[bCounter] <> 0
            sLineOne[bPosition + bCounter] = sString[bCounter]
            Inc bCounter   
        Wend  
    ElseIf bLine = 2 Then
        While sString[bCounter] <> 0
            sLineTwo[bPosition + bCounter] = sString[bCounter]
            Inc bCounter   
        Wend
    EndIf
EndProc

Peter Truman

Many thanks - I'll give it a try

This will be my first use of a procedure in Positron - always something new to learn!

I appreciate the help

Peter Truman

Ok  spent some time on this

Not only did it solve my problem (thanks Trastikata) - it introduced me to using procedures.

So.. two birds with one stone!

I've reposted my final code here in case anyone else ever has the same issue (All credit to Trastikata) - all I did was shift the 'pos' value down 1 so I could keep the format as P_At(1,1,"Txt"), renamed the procedure to make it more convenient to use and rename the variables to comply with my usual format (I use b_Xxxx for a bit var, B_Xxxx, for a byte, W_Xxx for a word and so on - that way I never get confused (or have to look up) what type of var I am using in the code)

I will do some more work later on - I need to add some formatting characters (flash, underline etc) so I'll trap them in the procedure and handle them there)   

'Call > P_At(1, 12, "OK")  where 1 is the line and 12 is the pos
Proc P_At (B_bLine As Byte, B_bPosition As Byte , S_sString As String * 16)                'setup the procedure

B_bPosition=B_bPosition-1                                                                        'pos 1=lcd pos 0   

Dim B_bCounter As Byte                                                                            'Local Var

B_bCounter = 0                                                                                    'Start with element 1

If B_bLine = 1 Then                                                                                '1st Line
    While S_sString[B_bCounter] <> 0
        S_sLine_1[B_bPosition + B_bCounter] = S_sString[B_bCounter]                                'element by element
        Inc B_bCounter  
    Wend 
ElseIf B_bLine = 2 Then                                                                            '2nd line
    While S_sString[B_bCounter] <> 0
        S_sLine_2[B_bPosition + B_bCounter] = S_sString[B_bCounter]
        Inc B_bCounter  
    Wend
EndIf


'Concatonate and calculate the crc
S_Up_String=S_sLine_1+S_sLine_2

Clear B_CRC_LCD                                                                                 'clear the crc var
For B__UP_G=0 To Len(S_Up_String)                                      
    B_CRC_LCD=B_CRC_LCD+S_Up_String[B__UP_G]                                                    'just add all the ASCII values together
Next B__UP_G

RsOut 2,S_Up_String,B_CRC_LCD,3                                                                 'upload to the display
EndProc