PDA

View Full Version : Big Digits on 4x20 LCD



Heckler
- 18th February 2013, 23:48
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!!


' 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

Heckler
- 19th February 2013, 00:00
I wish the code formatting would transfer when posing in a "CODE" window.
It seems all the tabs and spaces get lost.

Here is the .pbp file which should be formatted better for reading and editing...
You may need to delete the .txt extension and keep the .pbp extension.

6840

Heckler
- 19th February 2013, 03:39
Here is a photo of the display...

6842

SteveB
- 19th February 2013, 07:16
Looks good!

andymuller
- 26th February 2014, 01:20
Hello Heckler,

Thank you in advance for sharing this valuable routine.

I have some questions:


Would you please let me know if I want to add a point between 1st and 2nd digits? I'd like to show pressure by this method, so would you please modify your source code for this purpose? And how about the "R/w" pin of LCD? Can you please draw a simple diagram on and attach here? Honestly, I cannot understand how you would write your new-design characters inside LCD,

I would deeply appreciate you, if you enforce the answer please.

Kind regards,

Andy

Heckler
- 27th February 2014, 03:05
Hi Andy,

Well, as you can see it has been a full year since I posted that code.
I would have to spend several hours studying it to make suggestions that you request.

Have you tried to load it up and see if you can make it work as is? Just as a starting point?
As to your question about the R/W pin of the lcd... I was using an LCD with Serial backpack.
If you don't know what that is take a look here...
http://store.melabs.com/cat/displays.html
So if you go that route then you will not have to worry about the R/w line.
They sell just the backpack if you have your own lcd.
these are VERY handy for prototyping and testing code because they can be written to via a SEROUT command.

It should work with a regular LCD also just follow the example in the PBP manual as a starting point.

The real way to learn is to study and try and modify a small portion of the code or the font data table and see what it does.

They sell just the backpack if you have your own lcd.
these are VERY handy for prototyping and testing code because they can be written to via a SEROUT command.

My suggestion is that you load the code up in Microcode studio... or even better is the IDE called FineLine as it allows you to visualize the various subroutines and loops very well.

Give the code a try and then ask questions.

It is very easy to just copy the code above and past it into your IDE and study it there. Then it will be color coded and easier to read.

If you havent tried FineLine then give it a try.

Just search the forum here for FineLine as the author is a regular here and you should be able to find a link to down load it.

good luck

andymuller
- 1st March 2014, 23:18
I would have to spend several hours studying it to make suggestions that you request.

... I was using an LCD with Serial backpack.


Hi Heckler,

I hope it finds you well.

Thank you for your kind replying here.

I really appreciate you in advance for your support.

My suggesstion is to modify your written routine under my Microcode studio and just assign a pin for "R/w". and using LCDIN command for writing in LCD's RAM and so on. Because I should work with usual LCDs. I think I should all these two headers



DEFINE LCD_RWREG PORTE ' LCD read/write pin port
DEFINE LCD_RWBIT 2 ' LCD read/write pin bit


What do you think Sir?

After I received your help, if my suggestion be right, it seems, it would be easy to fix this section. But now, I am hardly busy at something else, a damn PID routine for pressure control.:confused: and honestly I cannot focus on anything else. My mind is 100% busy :confused:

May I very kindly ask you twice to take a look again at your valuable work and give me some points/remedy for implementing a dot, between 1st and 2nd numbers (from left side)?

I really appreciate you in advance for your support.

I would never forget your kind help.

Best regards,

Andy