Hey group,

I have been working on this code to display big digits on a 4 x 20 serial LCD. The one I am using is from MElabs.
I bet this code would work on other serial and non-serial LCD's.

I found the basis for theis code in this thread... http://www.picbasic.co.uk/forum/showthread.php?t=5443
Thanks mister_e !! and others who contributed.

I took that code and made it work for my needs. Some of the things I changed from mister_e's version...
cleaned up the font data
eliminated one of the custom characters that was un-needed (the solid block, which $FF will do)
added another custom character (upper DOT that could be used for a colon in a time display, etc
made the code only update the digit that changed to the LCD. Instead of clearing and re-writing the whole LCD every time
other code improvements, variable name changes, and LOTS of comments.

I hope someone else can use it and have FUN with it.

I have only tested it with a 16F690

enjoy!!

Code:
' 16F690
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2007 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 11/25/2007                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
' ---------- [ CONFIGURATION BITS ]---------------------
  '  The following config for 16F1828 may need some work and the various
  '     ADCON's, CMCON0, CMCON1, ANSEL, ANSELH, etc. etc. will need to be
  '     reviewed and corrected for the 16f1828.

  '  THE CODE HAS ONLY BEEN TESTED ON A 16F690

    #IF __PROCESSOR__ = "16F1828"
        #CONFIG
        __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
        __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_25 & _LVP_OFF
        #endconfig
    #ELSE
        #IF __PROCESSOR__ = "16F690"
            #CONFIG
            __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF
            #endconfig
        #ELSE
            #ERROR "Program does not support " + __PROCESSOR__
        #ENDIF
    #ENDIF

    #msg "compiling for target " + __PROCESSOR__


  '  DEFINE LCD_DREG PORTD     ' LCD data port
  '  DEFINE LCD_DBIT 4         ' LCD data starting bit 0 or 4
  '  DEFINE LCD_RSREG PORTD    ' LCD register select port
  '  DEFINE LCD_RSBIT 2        ' LCD register select bit
  '  DEFINE LCD_EREG PORTD     ' LCD enable port
  '  DEFINE LCD_EBIT 3         ' LCD enable bit
  '  DEFINE LCD_BITS 4         ' LCD bus size 4 or 8
  '  DEFINE LCD_LINES 4        ' Number lines on LCD
  '  DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
  '  DEFINE LCD_DATAUS 50      ' Data delay time in us

' -----[ I/O CONFIGURATION ]-------------------------------------------------
    DEFINE ADC_BITS 8
    DEFINE ADC_CLOCK 3                                      `
    DEFINE ADC_SAMPLEUS 50

    DEFINE OSC 4

    TRISA = %00111111     'PortA 2 A/D input
    TRISB = %00110000     'PortB 6,7 out to LCD 4,5 in from buttons
    TRISC = %00000000     'PortC all output 8 bit binary display

    ADCON0 = %00001001  'left justified  0xxxxxxx or right justified 1xxxxxxx
                        'vdd             x0xxxxxx
                        'AN2             xx0010xx through AN11 xx1011xx
                        'go/done         ------x- don't care
                        'ADC enabled     xxxxxxx1

    ADCON1 = %00010000    'fOSC/8  % x001xxxx
    ANSEL  = %00000100    'and set AN2 pin to Analog
    ANSELH = %00000000
    CM1CON0 = 0           'turn off the comparator 1
    CM2CON0 = 0           'turn off the comparator 2
'================================================================
' ============[ Variables for LCD routines only ]  ==============
'================================================================
    Pattern      VAR WORD[11]
    Line         VAR BYTE[4]
    Value       VAR WORD
    Value   =   0
    Row         VAR BYTE
    Col         VAR BYTE
    block       VAR BYTE
    Char1       VAR BYTE
    Char2       VAR BYTE
    Char3       VAR BYTE
    Char4       VAR BYTE
    Last0       VAR BYTE
    Last1       VAR BYTE
    Last2       VAR BYTE
    Last3       VAR BYTE
    Digit       VAR BYTE
    Digit=0
    Last0=1     'these "LAST" variables are used to determine if
    Last1=1     '   each of the digits hase changed and the LCD needs
    Last2=1     '   updating.  They are initialised to 1 and assume
    Last3=1     '   the starting "Value" variable will be 0000

' -----[ Constants ]-------------------------------------------------------
    Cmd     CON $FE        'LCD prefix for Command
    Clr     CON 1          'LCD CLEAR SCREEN
    Hm      CON 2          'LCD HOME COMMAND

    Line[0]=$80         ' LCD line 1
    Line[1]=$C0         ' LCD line 2
    Line[2]=$94         ' LCD line 3
    Line[3]=$D4         ' LCD line 4

'==========================================================
'===  Main program variables not part of LCD routines =====
'===     Your program variables go here               =====
'==========================================================
    x  VAR WORD
'===========================================================
' -----[ Font definitions -->> PIC EEprom Data ]------------
    Zero    DATA 5  ,0  ,0  ,4
    DATA $FF,$20,$20,$FF
    DATA $FF,$20,$20,$FF
    DATA 2  ,1  ,1  ,3

    One     DATA $20,5  ,$ff,$20
    DATA $20,$20,$ff,$20
    DATA $20,$20,$ff,$20
    DATA $20,$20,$ff,$20

    Two     DATA 0  ,0  ,0  ,4
    DATA $20,$20,$20,$ff
    DATA 5  ,0  ,0  ,0
    DATA $ff,1  ,1  ,1

    Three   DATA 0  ,0  ,0  ,4
    DATA $20,$20,$20,$ff
    DATA $20,0  ,0  ,$ff
    DATA 1  ,1  ,1  ,3

    Four    DATA $ff,$20,$20,$FF
    DATA $ff,$20,$20,$ff
    DATA 0  ,0  ,0  ,$ff
    DATA $20,$20,$20,$ff

    Five    DATA $FF,0  ,0  ,0
    DATA $ff,$20,$20,$20
    DATA 0  ,0  ,0  ,4
    DATA 1  ,1  ,1  ,3

    Six     DATA 5  ,0  ,0  ,$20
    DATA $ff,$20,$20,$20
    DATA $ff,0  ,0  ,4
    DATA 2  ,1  ,1  ,3

    Seven   DATA 0  ,0  ,0  ,4
    DATA $20,$20,$20,$ff
    DATA $20,$20,$20,$ff
    DATA $20,$20,$20,$ff

    Eight   DATA 5  ,0  ,0  ,4
    DATA 2  ,1  ,1  ,3
    DATA 5  ,0  ,0  ,4
    DATA 2  ,1  ,1  ,3

    Nine    DATA 5  ,0  ,0  ,4
    DATA 2  ,1  ,1  ,$ff
    DATA $20,$20,$20,$ff
    DATA $20,1  ,1  ,3

    Dot     DATA $20,$20,$20,$20
    DATA $20,$20,$20,$20
    DATA $20,$20,$20,$20
    DATA $20,  7,$20,$20

    Pattern[0]=Zero
    Pattern[1]=One
    Pattern[2]=Two
    Pattern[3]=Three
    Pattern[4]=Four
    Pattern[5]=Five
    Pattern[6]=Six
    Pattern[7]=Seven
    Pattern[8]=Eight
    Pattern[9]=Nine
    Pattern[10]=Dot

' -----[ Custom LCD characters used to create BIG fonts ]-----------------------
    DumpCustChar:
    Row=0
    PAUSE 500
    REPEAT                         ' Define custom characters
        LOOKUP Row,[_
        Cmd,064,31,31,31,31,00,00,00,00,_      ; Cust Char #0  upper half
        Cmd,072,00,00,00,00,31,31,31,31,_      ; Cust Char #1  lower half
        Cmd,080,31,31,31,15,07,03,01,00,_      ; Cust Char #2  \^  upper
        Cmd,088,31,31,31,30,28,24,16,00,_      ; Cust Char #3   /^ upper
        Cmd,096,00,16,24,28,30,31,31,31,_      ; Cust Char #4  \   lower
        Cmd,104,00,01,03,07,15,31,31,31,_      ; Cust Char #5   /  lower
        Cmd,112,14,31,31,31,14,00,00,00,_      ; Cust Char #6  upper dot
        Cmd,120,00,00,00,14,31,31,31,14],Char1 ; Cust Char #7  lower dot
        SEROUT2 PortB.7, 16468, [Char1]        'Store custom char in LCD mem
        Row=Row+1
    UNTIL Row=80

' -----[ Initialization ]--------------------------------------------------

    PAUSE 500
    SEROUT2 PortB.7, 16468, [$1b,$2a,128]   'LCD backlight half on
    SEROUT2 PortB.7, 16468, [Cmd,Clr]       'clear LCD

'======================================================
'======================================================
' This is where your main program goes... what ever you want to do
' and what ever you want to display on the LCD using big digits.
' From this section you GOSUB LCDupdat with your 1 to 4 digit number
' loaded into the variable called "Value"
' That number can be a temperature, counter, A/D value, voltage etc.
'     NOTE:  You may need to create other Letter Font definitions
'            in order to display your data. (-,+,F, etc.)
'---------------------------------------------------------------
    Main:
    FOR x=0 TO 9999
        Value = x
        GOSUB LCDupdate
        PAUSE 100
    NEXT x

    GOTO Main
    END

'=========================================================================
'=======  SubRoutine determine which LCD digit needs updating   ==========
'=========================================================================
    LCDupdate:                         'Col is the LCD column to write to from L to R
    LL:   Col=0                    ' Left most digit
    Digit=Value DIG 3
    IF Last3 = Digit THEN LC   'This digit didn't change so skip it
    GOSUB LCDwrite             'Digit did change so update display
    Last3=Digit

    LC:   Col=5                    ' Left-of-Center digit
    Digit = Value dig 2
    IF Last2 = Digit THEN RC   'This digit didn't change so skip it
    GOSUB LCDwrite             'Digit did change so update dispay
    Last2=Digit

    RC:   Col=10                   ' Right-of-center digit
    Digit = Value dig 1
    IF Last1 = Digit THEN RR   'This digit didn't change so skip it
    GOSUB LCDwrite             'Digit did change so update display
    Last1=Digit

    RR:   Col=15                   ' Right most digit
    Digit=Value DIG 0
    IF Last0 = Digit THEN done 'This digit didn't change so skip it
    GOSUB LCDwrite             'Digit did change so update display
    Last0=Digit
    done:
    RETURN

'=======================================================================
'================  SubRoutine to Write to the LCD  =====================
'=======================================================================
    LCDwrite:   'this will erase the digit before writing the new one

    FOR Row = 0 TO 3
        SEROUT2 PortB.7, 16468,[Cmd,Line[Row]+Col]  'move cursor into position
        SEROUT2 PortB.7, 16468,[$20,$20,$20,$20]              'erase line
    NEXT Row
   ' pause 100    'pause will make display look more animated but will slow it down
'-------------------------------------------------------------------
    DigitWrite:  ' Now write the digit
    FOR Row=0 TO 3
        LOOKUP Row,[0,4,8,12],block
        SEROUT2 PortB.7, 16468,[Cmd,Line[Row]+Col] 'move cursor into position
        READ Pattern[Digit]+block,Char1,Char2,Char3,Char4   'read font data
        SEROUT2 PortB.7, 16468,[Char1,Char2,Char3,Char4]     'write character data
    NEXT Row
    RETURN