PDA

View Full Version : problem with LCD large Numbers



ozarkshermit
- 9th December 2017, 20:52
Hi all
I have been away for a LOONG time, finally getting back working with PICs.

I have developed a program to display large numbers on a 4x20 LCD, using PBP 2.6. The PIC is an 18F14K22.
I used POKECODE to store the number patterns in code space, making the overall program quite efficient.
Everything works great, except for a bug I simply cannot figure out. The code is well commented, so should be easy to follow.
The bug is: when a three digit number is chosen with the units and tens digits BOTH ZERO, or just the tens digit is 0.
When the number is any hundreds (100, 200, 300, etc) or a number with 0 in the tens digit (101, 306, 802, etc).
What happens with the two zero example is: the display is there, but is flickering at a very high rate. At first I thought I might have a CLS command somewhere, but that is not it. With a number with the tens digit 0, the display totally "hangs".

I'm really happy with the code otherwise, but have been pulling out what little hair I have left !

The total program is posted below. Once again, I am using a 18F14K22. Perhaps someone can download the code and try it.


DEFINE OSC 16
OSCCON = %11110110 ' 16 MHZ INTERNAL OSCILLATOR

TX var PORTC.0
TRISC = %10110000


ROW1 con 128 ' VALUES FOR THE ROWS ( USED IN PATTERN DISPLAY)
ROW2 con 192
ROW3 con 148
ROW4 con 212

ROW VAR BYTE '4 X 20 ROW NUMBER - 1 TO 4
COL VAR BYTE '4 X 20 COLUMN NUMBER - 0 TO 19
CHAR VAR BYTE ' SPECIAL LARGE FONT CHARACTER (1 THRU 7)

Z VAR WORD ' USED TO SEQUENCE THROUGH THE POKED CODE
A VAR WORD ' START POINT OF SEARCHED POKE CODE
B VAR WORD ' END POINT OF SEARCHED POKE CODE
NUMBER VAR WORD
TEMP VAR WORD
COL_OFFSET VAR BYTE ' USED TO POSITION UNITS, HUNDREDS, AND TENS
COUNTER VAR BYTE ' A COUNTER FOR THE DIGIT NUMBER
COUNTER = 0
'************************************************* *******************************
NUMBER = 369
'
' THIS IS ANY NUMBER THAT CAN BE DISPLAYED FOR TEST PURPOSES
' CHANGING IT WITH ZEROS IN THE UNITS AND TENS DISPLAY CAUSES A RAPID FLICKER
' PLACING A ZERO IN ONLY THE TENS SPACE "HANGS" THE DISPLAY ! ! !
'************************************************* ********************************

serout2 tx,84,[254,$01] ' CLEAR THE DISPLAY
pause 500


pause 100

''' FIRST WRITE THE CHARACTER PATTERNS TO LCD RAM FOR A PATTERN DISPLAY
''
' 0 Left-right UP-ramp (TOP)
serout2 tx,84,[254,$40,$00,$01,$03,$07,$0F,$1F,$1F,$1F]
serout2 tx,84,[254,ROW1, 0]
PAUSE 1
' 1 Right-left DOWN-ramp (TOP)
serout2 tx,84,[254,$48,$00,$10,$18,$1C,$1E,$1F,$1F,$1F]
serout2 tx,84,[254,ROW1+2, 1]
PAUSE 1
' 2 Left-right UP-ramp. (BOTTOM)
serout2 tx,84,[254,$50,$1F,$1F,$1F,$1E,$1C,$18,$10,$00]
serout2 tx,84,[254,ROW1+4, 2]
PAUSE 1
' 3 Right-left DOWN-ramp (BOTTOM)
serout2 tx,84,[254,$58,$1F,$1F,$1F,$0F,$07,$03,$01,$00]
serout2 tx,84,[254,ROW1+6, 3]
pause 1
' 4 UPPER block.
serout2 tx,84,[254,$60,$1F,$1F,$1F,$1F,$00,$00,$00,$00]
serout2 tx,84,[254,ROW1+8, 4]
PAUSE 1
' 5 LOWER block.
serout2 tx,84,[254,$68,$00,$00,$00,$00,$1F,$1F,$1F,$1F]
serout2 tx,84,[254,ROW1+10, 5]
PAUSE 1
'6 SMALL UP-RAMP
serout2 tx,84,[254,$70,$01,$03,$07,$0F,$1F,$00,$00,$00] '6
serout2 tx,84,[254,ROW1+12, 6]
PAUSE 1
' '7 FULL BLOCK
serout2 tx,84,[254,$78,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F] '7
serout2 tx,84,[254,ROW1+14, 7]

PAUSE 2000 ' SHORT DELAY TO DISPLAY THE SPECIAL CHARACTERS
serout2 tx,84,[254,$01] ' CLEAR THE DISPLAY

'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''


START: ' FIRST GET THE THREE DIGITS ( THOUSANDS WILL BE ADDED LATER)



TEMP = NUMBER DIG 0
COUNTER = 1 ' SPACE FOR UNITS DIGIT
GOSUB GET_NUMBER
TEMP = NUMBER DIG 1
COUNTER = 2 ' SPACE FOR TENS DIGIT
GOSUB GET_NUMBER
TEMP = NUMBER DIG 2
COUNTER = 3 ' SPACE FOR HUNDREDS DIGIT
GOSUB GET_NUMBER

GOTO START


GET_NUMBER:
'
IF TEMP = 0 THEN
A = $2400 : B= $2448 ' these are the start and end points for the pattern for zero
GOSUB DISPLAY
ENDIF

IF TEMP = 1 THEN
A = $2450 : B = $246C
GOSUB DISPLAY
ENDIF

IF TEMP = 2 THEN
A = $2470 :B = $24B6
GOSUB DISPLAY
ENDIF

IF TEMP = 3 THEN
A = $24C0 : B = $2506
GOSUB DISPLAY
ENDIF

IF TEMP = 4 THEN
A = $2510 : B = $253E
GOSUB DISPLAY
ENDIF

IF TEMP = 5 THEN
A = $2540 : B = $2586
GOSUB DISPLAY
ENDIF

IF TEMP = 6 THEN
A = $2590 : B = $25DC
GOSUB DISPLAY
ENDIF

IF TEMP = 7 THEN
A = $25E0 : B = $2608
GOSUB DISPLAY
ENDIF

IF TEMP = 8 THEN
A = $2610 : B = $2662
GOSUB DISPLAY
ENDIF

IF TEMP = 9 THEN
A = $2670 : B = $26BC
GOSUB DISPLAY
ENDIF

RETURN ' RETURN T0 START



' ZERO IS 2400 TO 2448 ONE IS 2450 TO 246C TWO IS 2470 TO 24B6
' THREE IS 24C0 TO 2506 FOUR IS 2510 TO 253E FIVE IS 2540 TO 2586
' SIX IS 2590 TO 25DC SEVEN IS 25E0 TO 2608 EIGHT IS 2610 TO 2662
' NINE IS 2670 TO 26BC
'


DISPLAY:

FOR Z = A TO B
PEEKCODE z,ROW
z=z+2
peekcode z,COL
z=z+2
peekcode z,CHAR
IF COUNTER = 1 THEN COL_OFFSET = 14 ' POSITION THE UNITS DIGIT
IF COUNTER = 2 THEN COL_OFFSET = 9 ' POSITION THE TENS DIGIT
IF COUNTER = 3 THEN COL_OFFSET = 4 ' POSITION THE HUNDREDS DIGIT
COL = COL+COL_OFFSET
SEROUT2 TX,84,[254,(ROW + COL),CHAR]
z=z+1
NEXT Z

RETURN ' RETURN TO GET_NUMBER


END

''''''''''''' CODE FOR DIGITS O TO 9 '''''''''''''''''''
'' THE ADDRESSES CHOSEN THE THE DISPLAY WERE COMPLETLY ARBITRARY ''

'''''''''''''''''''' ZERO '''''''''''''''''
POKECODE @$2400,128,0,0,128,1,4,128,2,4,128,3,1,192,0,7,192 ,3,7,148,0,7,148,3,7
POKECODE @$2430,212,0,3,212,1,5,212,2,5,212,3,2 ''' ENDS AT $2448

''''''''''''''''''''' ONE ''''''''''''''''''
POKECODE @$2450,128,0,8,128,1,7,192,1,7,148,1,7,212,1,7 '' ENDS AT $246C

'''''''''''''''''''''' TWO '''''''''''''
POKECODE @$2470,128,0,0,128,1,4,128,2,4,128,3,1,192,2,5,192 ,3,4,148,0,5,148,1,4
POKECODE @$24A0,212,0,7,212,1,5,212,2,5,212,3,5 ''ENDS AT $24B6

''''''''''''''''''' THREE '''''''''''''
POKECODE @$24C0,128,0,2,128,1,4,128,2,4,128,3,1,192,3,7,148 ,1,4,148,2,4,148,3,7
POKECODE @$24F0,212,0,1,212,1,5,212,2,5,212,3,2 '' ENDS AT $2506

'''''''''''''''''' FOUR ''''''''''''''
POKECODE @$2510,128,0,7,128,3,7,192,0,7,192,1,5,192,2,5,192 ,3,7,148,3,7,212,3,7
' ENDS AT $253E
''''''''''''''''''''FIVE '''''''''''''''''''''
POKECODE @$2540,128,0,7,128,1,4,128,2,4,128,3,4,192,0,7,192 ,1,5,192,2,5,148,3,1
POKECODE @$2570,212,0,5,212,1,5,212,2,5,212,3,2 ''ENDS AT $2586

''''''''''''''''''''''''''''''''''' SIX ''''''''''''
POKECODE @$2590,128,0,0,128,1,4,128,2,4,128,3,1,192,0,7,148 ,0,7,148,1,4,148,2,4 '
POKECODE @$25C0,148,3,1,212,0,3,212,1,5,212,2,5,212,3,2 '' ENDS AT $25DC

'''''''''''''''''''''' SEVEN ''''''''''''''

POKECODE @$25E0,128,0,4,128,1,4,128,3,2,128,2,4,192,2,7,148 ,1,7,212,0,7 'ENDS AT $2608

''''''''''''''''''' EIGHT '''''''''''''''
POKECODE @$2610,128,0,0,128,1,4,128,2,4,128,3,1,192,0,3,192 ,1,5,192,2,5,192,3,2
POKECODE @$2640,148,0,0,148,3,1,212,0,3,212,1,5,212,2,5,212 ,3,2 'ENDS AT $2662

''''''''''''''''''''' NINE ''''''''''''
POKECODE @$2670,128,0,0,128,1,4,128,2,4,128,3,1,192,0,3,192 ,1,5,192,2,5,192,3,7
POKECODE @$26A0,148,3,7,212,0,3,212,1,5,212,2,5,212,3,2 ' ENDS AT $26BC

richard
- 10th December 2017, 05:48
I can't quite see why the pgm misbehaves like you mention ,. but I will make these comments



I used POKECODE to store the number patterns in code space, making the overall program quite efficient.


peek/poke is the least efficient way to use progmem, it only stores 1 byte per every word of flash it uses
readcode is faster and better and on a pic18 can use the entire progmem word

there is no need to store the row/col data in the font ,the "display" routine can calculate that information along with the column offset

the font can be compressed to this [blank added]



asm
db 0,4,4,1, 7,32,32,7, 7,32,32,7, 3,5,5,2 ;0
db 32,8,7,32, 32,32,7,32, 32,32,7,32, 32,32,7,32 ;1
db 0,4,4,1, 32,32,5,4, 5,4,32,32, 7,5,5,5 ;2
db 2,4,4,1, 32,32,32,7, 32,4,4,7, 1,5,5,2 ;3
db 7,32,32,7, 7,5,5,7,32, 32,32,7, 32,32,32,7 ;4
db 7,4,4,3, 7,5,5,32, 32,32,32,1, 5,5,5,2 ;5
db 0,4,4,1, 7,32,32,32, 7,4,4,1, 3,5,5,2 ;6
db 4,4,4,1, 32,32,32,7, 32,32,7,32, 32,7,32,32 ;7
db 0,4,4,1, 3,5,5,2,0, 32,32,1, 3,5,5,2 ;8
db 0,4,4,1, 3,5,5,7, 32,32,32,7, 32,5,5,2 ;9
db 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32 ;blank
endasm

fully defining the font and adding a blank make leading zero suppression/ field justification far easier


my take for a pic18f26k22 [pbp3]



#CONFIG
CONFIG FOSC = INTIO67
CONFIG PLLCFG = ON
CONFIG PRICLKEN = OFF
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRTEN = OFF
CONFIG BOREN = SBORDIS
CONFIG BORV = 190
CONFIG WDTEN = ON
CONFIG WDTPS = 32768
CONFIG CCP2MX = PORTC1
CONFIG PBADEN = OFF
CONFIG CCP3MX = PORTB5
CONFIG HFOFST = ON
CONFIG T3CMX = PORTC0
CONFIG P2BMX = PORTB5
CONFIG MCLRE = EXTMCLR
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG
DEFINE OSC 64
OSCCON = %01110000
ANSELb = 0
ANSELA = 0
ANSELC = 0
OSCTUNE.6=1
goto overasm
asm
bigfont ;pic18 only must be in 1st 64k block
db 0,4,4,1, 7,32,32,7, 7,32,32,7, 3,5,5,2 ;0
db 32,8,7,32, 32,32,7,32, 32,32,7,32, 32,32,7,32 ;1
db 0,4,4,1, 32,32,5,4, 5,4,32,32, 7,5,5,5 ;2
db 2,4,4,1, 32,32,32,7, 32,4,4,7, 1,5,5,2 ;3
db 7,32,32,7, 7,5,5,7,32, 32,32,7, 32,32,32,7 ;4
db 7,4,4,3, 7,5,5,32, 32,32,32,1, 5,5,5,2 ;5
db 0,4,4,1, 7,32,32,32, 7,4,4,1, 3,5,5,2 ;6
db 4,4,4,1, 32,32,32,7, 32,32,7,32, 32,7,32,32 ;7
db 0,4,4,1, 3,5,5,2,0, 32,32,1, 3,5,5,2 ;8
db 0,4,4,1, 3,5,5,7, 32,32,32,7, 32,5,5,2 ;9
db 32,32,32,32, 32,32,32,32, 32,32,32,32, 32,32,32,32 ;blank

ft1=_rowbuff ;shortcut to read data into rowbuffer 0:1
ft2=_rowbuff+2 ;shortcut to read data into rowbuffer 2:3
GLetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
movlw High Label ; get high byte
movwf Wout + 1
BANKSEL 0
endm
endasm


overasm:
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
Define LCD_Bits 4
DEFINE LCD_LINES 4
Define LCD_Commandus 2000
Define LCD_DATAUS 50


ROW VAR BYTE '4 X 20 ROW NUMBER - 0 TO 3
COL VAR BYTE '4 X 20 COLUMN NUMBER - 0 TO 4
slz var bit
rows var byte[4] ;lcd page start addresses
rowbuff var byte[4] ;a row of data for lcd
ctemp var word
ft1 var word ext ;shortcut to read data into rowbuffer 0:1
ft2 var word ext ;shortcut to read data into rowbuffer 2:3
parsedig var byte

NUMBER VAR WORD
TEMP VAR WORD
COL_OFFSET VAR BYTE ' USED TO POSITION font
font var word ;address of data


NUMBER = 0

lcdout 254,$01 ' CLEAR THE DISPLAY
pause 500
arraywrite rows,[128,192,148,212] ;pbp3 for earlier rows[0]=128:rows[0]=192: etc.........
pause 100
@ GLetAddress bigfont ,_font ;get font address

''' FIRST WRITE THE CHARACTER PATTERNS TO LCD RAM FOR A PATTERN DISPLAY

' 0 Left-right UP-ramp (TOP)
lcdout 254,$40,$00,$01,$03,$07,$0F,$1F,$1F,$1F
lcdout 254,rows[0], 0
PAUSE 1
' 1 Right-left DOWN-ramp (TOP)
lcdout 254,$48,$00,$10,$18,$1C,$1E,$1F,$1F,$1F
lcdout 254,rows[0]+2, 1
PAUSE 1
' 2 Left-right UP-ramp. (BOTTOM)
lcdout 254,$50,$1F,$1F,$1F,$1E,$1C,$18,$10,$00
lcdout 254,rows[0]+4, 2
PAUSE 1
' 3 Right-left DOWN-ramp (BOTTOM)
lcdout 254,$58,$1F,$1F,$1F,$0F,$07,$03,$01,$00
lcdout 254,rows[0]+6, 3
pause 1
' 4 UPPER block.
lcdout 254,$60,$1F,$1F,$1F,$1F,$00,$00,$00,$00
lcdout 254,rows[0]+8, 4
PAUSE 1
' 5 LOWER block.
lcdout 254,$68,$00,$00,$00,$00,$1F,$1F,$1F,$1F
lcdout 254,rows[0]+10, 5
PAUSE 1
'6 SMALL UP-RAMP
lcdout 254,$70,$01,$03,$07,$0F,$1F,$00,$00,$00 '6
lcdout 254,rows[0]+12, 6
PAUSE 1
' '7 FULL BLOCK
lcdout 254,$78,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F '7
lcdout 254,rows[0]+14, 7
PAUSE 2000 ' SHORT DELAY TO DISPLAY THE SPECIAL CHARACTERS
lcdout 254,$01 ' CLEAR THE DISPLAY
'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''

START: ;display 4 digits right justified with noleading zeros
parsedig = 4
slz = 1 ;suppress leading zeros on
col = 0
while parsedig
parsedig = parsedig - 1
TEMP = NUMBER DIG parsedig
if slz then
if temp then ;if temp > 0 then display it and cancel zero suppression
GOSUB DISPLAY
slz = 0 ;suppress zeros cancelled
else
if parsedig then temp = 10;blank suppress all zeros except for dig 0
GOSUB DISPLAY
endif
else
GOSUB DISPLAY
endif
col = col + 1
wend
pause 10
NUMBER = number + 1
if number>9999 then number=0
GOTO START


;pic18 only font must be in 1st 64k block for readcode to function
DISPLAY: ;disp big digit in TEMP var @ column COL digits 0-9 and blank
COL_OFFSET = (col*5)
ctemp = font + (temp*16); 16 bytes per chr
for row = 0 to 3 ;read data as words to reduce code and more speed
readcode ctemp,ft1 ;shortcut to read data into rowbuffer 0:1
ctemp = ctemp + 2 ;next word
readcode ctemp,ft2 ;shortcut to read data into rowbuffer 2:3
ctemp = ctemp + 2 ;next row
lcdout 254,(COL_OFFSET + rows[row]),str rowbuff\4;for early versions pbp might need rowbuff[0],rowbuff[1],rowbuff[2],rowbuff[3]
next
RETURN



END

ozarkshermit
- 10th December 2017, 14:49
Richard:

Thanks for your response. I modified your program to use with a 18F14K22, and since I have a serial LCD backpack, I changed the LCD stuff to SEROUT2. Also, no PB3 here, still on 2.6, but the program works great. Got 4 Warnings regarding the assembly stuff, I will try to figure that out, but the program runs just fine.

My intent in developing this program was to have a routine to add to my programs that use LCD's with some numeric display requirements.

I still plan on spending some (a little) time on my original program, to try to figure out the problem - hate to have an error like that that I do not understand.

once again THANKS

Dave
- 10th December 2017, 20:52
ozarkshermit, Attached is a program I wrote quite a few years ago to test the theory of using BIG numbers on a 4 x 20 LCD display. Enjoy...

Art
- 13th December 2017, 17:02
Your Z loop increments Z by 6 for each iteration.
You increment Z by 5 manually within the loop, and the NEXT Z used to close the loop iterates another 1.

If you take the difference between your start and end indexes for each digit A and B,
the difference between A and B for digit zero is the only set that is evenly divisible by 6.
The other digits overshoot the loop index by 2.

Heckler
- 13th December 2017, 17:15
You might also check this thread...

http://www.picbasic.co.uk/forum/showthread.php?t=17707

good luck
Dwight