B4R Question code module instance


Active Member
Licensed User
I have B4R code module called Glcd it's an lcd driver, I want to driver 2 lcds and instantiate this module with different properties(pin assignment, col, rows..etc). for example

private LCD1 as Glcd
private LCD2 as Glcd


or should I create new module(a copy of original one) and name them LCD1, LCD2?



Well-Known Member
Licensed User
You can reasonably successfully emulate objects / classes by morphing your example slightly:

Type Glcd( _
    InitializedFlag As Boolean, _
    ClockPin As Byte, _
    DataPin As Byte, SelectPin As Byte, _
    NumCols As Byte, _
    NumRows As Byte, _
    Row As Byte, _
    Col As Byte, _
    other per-instance variables _

Private LCD1 As Glcd
Private LCD2 As Glcd

Glcd_Initialize(LCD1, 1, 2, 3)
Glcd_Initialize(LCD2, 4, 5, 6)

'poor man's object.method of LCD1.ClearScreen

'poor man's object.method of LCD1.Print("String")
Glcd_Print(LCD1, "String")

'poor man's object.method of LCD1.PrintAt(1, 10, "World")
Glcd_PrintAt(LCD1, 1, 10, "World")

'and then implement class methods as subs, passing specific instance as first parameter, eg:

Sub Glcd_Print(LCD As Glcd, S As String)

    For I = 0 To S.Length - 1
        Glcd_PrintChar(LCD, S.CharAt(I))
    Next I

End Sub

Sub Glcd_PrintChar(LCD As Glcd, C As Char)

    Glcd_OutputByte(LCD, Asc(C))

    LCD.Col = LCD.Col + 1
    If LCD.Col > Lcd.NumCols then
        LCD.Col = 1
        If LCD.Row < LCD.NumRows Then
            LCD.Row = LCD.Row + 1
        End If
    End If

End Sub

Sub Glcd_OutputByte(LCD as Glcd, B as Byte)

    'you'd probably need to insert some delays in here,
    'eg on a 160 MHz or whatever CPU, the signalling would likely be too fast for the LCD

    SetPin(LCD.ClockPin, False)
    SetPin(LCD.SelectPin, True)

    Dim BitMask As Byte = 1

    For BitNumber = 0 to 7
        SetPin(LCD.DataPin, Bit.And(B, BitMask) <> 0)
        SetPin(LCD.ClockPin, True)
        SetPin(LCD.ClockPin, False)
        BitMask = BitMask + BitMask

    SetPin(LCD.SelectPin, False)

End Sub

Sub Glcd_Clear(LCD As Glcd)

    Glcd_OutputByte(LCD, 12)    'ASCII Form Feed = Clear Screen
    LCD.Row = 1
    LCD.Col = 1

End Sub
You could generalize the whole thing so that your Print, PrintAt, Locate, ClearScreen etc routines can work with different display modules, but since one project tends to only have one type of display module, doing so usually adds extra complexity for no added benefit. You'd be better off having a code module for each type of display module, but with standardized Sub names and formats, and just include the code module applicable to the display module of the project.
Last edited:


Well-Known Member
Licensed User
or should I create new module(a copy of original one) and name them LCD1, LCD2?
Just to make sure you don't head off down this path to misery multiplication: if the LCD's are of the same type, then the answer is: NO NO NO

Last edited:


Active Member
Licensed User
oh, I'm using 'type' to create fonts, never thought to use same method with LCD. thanks so much @emexes

Type Fonts(FontID As Byte,FontCols As Byte,BytesPerCol As Byte,BytesOrder As Byte,ByteReflection As Byte,ASCIIstartChar As Byte,ROMstartPage As UInt,FontFileName As String)

    Public Font5x8 As Fonts
    Public Font8x8 As Fonts
Private Sub SetFontProperties()
    Font5x8.FontID = 1
    Font5x8.FontCols = 5
    Font5x8.BytesPerCol = 1
    Font5x8.BytesOrder = BYTES_ORDER_LSB
    Font5x8.ByteReflection = REFLECT_BYTE_NONE
    Font5x8.ASCIIstartChar = 32
    Font5x8.ROMstartPage = 0
    Font8x8.FontID = 2
    Font8x8.FontCols = 8
    Font8x8.BytesPerCol = 1
    Font8x8.BytesOrder = BYTES_ORDER_MSB
    Font8x8.ByteReflection = REFLECT_BYTE
    Font8x8.ASCIIstartChar = 0 'this char set starts from char 0 and it has some extra icons and arabic chars
    Font8x8.ROMstartPage = 455
i use it like this:
Klcd.PutString(0,0,NumberFormat(hours, 2, 0),Klcd.Font8x8,False)