News:

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

Main Menu

Display of large numbers from 0 to 100 plus percent symbol

Started by Giuseppe, Apr 08, 2021, 05:49 PM

Previous topic - Next topic

Giuseppe

Thanks to Top204 who shared a piece of his code,
I was able to modify the code to do a display test of a percentage from 0 to 100.
I added to the Top204 code the display of the percentage symbol, AD reading and LED lighting at the extremes of the values read by the AD.
I share my code hoping it will be useful to the community.
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [Giuseppe]                                        *
'*  Notice  : Copyright (c) 2021 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 08/04/2021                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'Program test for analogue reading and percentage visualization on large characters display 20X4 with lighting of a
'led1 above a value percentage and lighting of another led2 under a value percentage
'Above a certain value AD prints 100% on the display
'Under an AD value it prints 0% on the display

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

Device = 18F25K22
Declare Xtal = 8

Config_Start
  FOSC = INTIO67 ;Internal oscillator block
  PLLCFG = OFF ;Oscillator used directly
  PRICLKEN = On ;Primary clock enabled
  FCMEN = OFF ;Fail-Safe Clock Monitor disabled
  IESO = OFF ;Oscillator Switchover mode disabled
  PWRTEN = OFF ;Power up timer disabled
  BOREN = SBORDIS ;Brown-out Reset enabled in hardware only (SBOREN is disabled)
  BORV = 190 ;VBOR set to 1.90 V nominal
  WDTEN = On ;WDT is always enabled. SWDTEN bit has no effect
  WDTPS = 32768 ;1:32768
  CCP2MX = PORTC1 ;CCP2 input/output is multiplexed with RC1
  PBADEN = On ;PORTB<5:0> pins are configured as analog input channels on Reset
  CCP3MX = PORTB5 ;P3A/CCP3 input/output is multiplexed with RB5
  HFOFST = On ;HFINTOSC output and ready status are not delayed by the oscillator stable status
  T3CMX = PORTC0 ;T3CKI is on RC0
  P2BMX = PORTB5 ;P2B is on RB5
  MCLRE = EXTMCLR ;MCLR pin enabled, RE3 input pin disabled
  STVREN = On ;Stack full/underflow will cause Reset
  LVP = On ;Single-Supply ICSP enabled if MCLRE is also 1
  XINST = OFF ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
  Debug = OFF ;Disabled
  Cp0 = OFF ;Block 0 (000800-001FFFh) not code-protected
  CP1 = OFF ;Block 1 (002000-003FFFh) not code-protected
  CP2 = OFF ;Block 2 (004000-005FFFh) not code-protected
  CP3 = OFF ;Block 3 (006000-007FFFh) not code-protected
  CPB = OFF ;Boot block (000000-0007FFh) not code-protected
  CPD = OFF ;Data EEPROM not code-protected
  WRT0 = OFF ;Block 0 (000800-001FFFh) not write-protected
  WRT1 = OFF ;Block 1 (002000-003FFFh) not write-protected
  WRT2 = OFF ;Block 2 (004000-005FFFh) not write-protected
  WRT3 = OFF ;Block 3 (006000-007FFFh) not write-protected
  WRTC = OFF ;Configuration registers (300000-3000FFh) not write-protected
  WRTB = OFF ;Boot Block (000000-0007FFh) not write-protected
  WRTD = OFF ;Data EEPROM not write-protected
  EBTR0 = OFF ;Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
  EBTR1 = OFF ;Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
  EBTR2 = OFF ;Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
  EBTR3 = OFF ;Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
  EBTRB = OFF ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
Config_End

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------

'-----Set AD-------------
Declare Adin_Res 10
Declare Adin_Stime 50
'--- Set display 4X20 -----
Declare LCD_Interface 4
Declare LCD_ENPin PORTB.3 ' 
Declare LCD_RSPin PORTB.2 '
Declare LCD_Lines 4
Declare LCD_Data4_Pin PORTB.4 ' 
Declare LCD_Data5_Pin PORTB.5 '
Declare LCD_Data6_Pin PORTB.6 '
Declare LCD_Data7_Pin PORTB.7 '
Declare LCD_CommandUs 2000
Declare LCD_DataUs 100 '
'----------Set ADC ----------------------
ADCON0 = %00000011  '
ADCON1 = %00001110  '
ADCON2 = %10100100  '
'---------------------------------------
LATB = %00000000
TRISB = %0000000 '
LATC = %00000000
TRISC = %00000000 '
LATA = %00000000
TRISA = %00000001 'RA0 set AD

'------variables----------

Dim flag As Byte
Dim value_xcento As Byte      '
Dim x As Byte             '
Dim read_tot As Word      '
Dim lettura As Word       '
Dim value_pot As Word     ' 
Dim state_pot As Word
Dim var_pot As Word
Dim dec_sec As Byte       '
Dim pistone As Byte

'------Symbol--------------
Symbol led1 = PORTC.5    '
Symbol led2 = PORTC.4    '
Symbol GIE = INTCON.7
Symbol PEIE = INTCON.6
Symbol RCIE = PIE1.5
Symbol RCIF = PIR1.5
Symbol TMR1IE = PIE1.0
Symbol TMR1IF = PIR1.0
Symbol display_clean flag.0
Symbol update_display = flag.1
'-------------------------------
dec_sec = 0
flag = 0
value_pot = $0000
Clear state_pot
Clear var_pot
Clear value_xcento
Set led1             'off led1
Set led2             'off led2

DelayMS 200
LCD_Setup_UDGs()     ' Setup the LCD's UDG
Cls                  ' Clear the LCD
print_x100()

'--------------------------------------------------------------------------------------

read_pot:

read_tot = 0
For x = 0 To 4         '5 readings AD 
lettura= ADIn 0           
read_tot = read_tot + lettura     
 Next x
    value_pot = read_tot/5
Return

'------------------------------------------
work:

Clrwdt

GoSub read_pot           'read AD

value_xcento = value_pot/10
value_xcento = value_xcento + 2  '
   
   If state_pot <> value_pot Then     'AD variation control
        DelayMS 200
        If state_pot <> value_pot Then
         
         If state_pot > value_pot Then
           var_pot = state_pot - value_pot
           If var_pot > 4 Then
              update_display = 1    ' ok  update display
           EndIf   
         EndIf
         If state_pot < value_pot Then
           var_pot =  value_pot - state_pot 
           If var_pot > 4 Then
              update_display = 1   ' ok  update display
           EndIf   
         EndIf
         state_pot = value_pot '
         
        EndIf
     EndIf 

If update_display = 1 Then

Select value_pot

Case 60 To 959

If display_clean = 1 Then
   Cls                   '
   print_x100()
   Clear display_clean
End If   

LCD_DisplayValue(value_xcento)

High led1 : High led2     'off led1 and off led2
Clear update_display

Case < 60                 'AD value < 60  Under an AD value it prints 0% On the display
 Clear update_display
 Cls
 print_0x100()
 value_xcento = 0
 LCD_DisplayValue(value_xcento)
 Low led2
 Set display_clean

Case > 959               'AD value > 959  Above an value AD prints 100% On the display
 Clear update_display
 Cls
 print_100x100()
 value_xcento = 100
 LCD_DisplayValue(value_xcento)
 Low led1
 Set display_clean
 
End Select
EndIf

GoTo work

 
'--------------------------------------------------------------------------------------------
' Display a value on the LCD using large digits
' Input     : pValue holds the value to display (maximum 9999 on a 4x20 LCD)
' Output    : None
' Notes     : Uses the LCD's UDGs for the shapes of the digits
'
Proc LCD_DisplayValue(pValue As Word)
    Dim bIndex  As Byte                                     ' Holds the index to the flash memory table holding the digit UDG data
    Dim wDecade As Word                                     ' Holds the value for  blanking
    Dim bDigit  As Byte                                     ' Holds the current digit to display
    Dim bLine   As Byte                                     ' Holds the line to display the UDGs on
    Dim wPattern As Word                                    ' Holds the pattern read from the flash memroy UDG data
'
' Each large digit is represented by four lines of four UDGs
'
    Dim DigTable As Flash16 = $0551, $7067, $0551, $0551,_
                              $6776, $6555, $0557, $2556,_
                              $0551, $0551, $6776, $7767,_
                              $7743, $7743, $6776, $2441,_
                              $6041, $7703, $2443, $6776,_
                              $6776, $7767, $0577, $7751,_
                              $2556, $7776, $6776, $7767,_
                              $0551, $2536, $2443, $7464,_
                              $6444, $2443, $7776, $2443,_
                              $2443, $7767, $2443, $7443   
    For bLine = 0 To 3                                      ' Create a loop for the four lines to display the digit
        wDecade = 100                                       ' Load the decade counter before entering the loop to display the digits
        Cursor bLine + 1,0                                  ' Position the cursor on the correct line
        For bDigit = 2 To 0 Step -1                         ' Create a loop for each digit                   
            bIndex = (Dig value_xcento, bDigit) + (bLine * 10)  ' Calculate the index to the data table containing the digit data
            wPattern = CRead16 DigTable[bIndex]                 ' Get the data for the digits Cread16
   
            If bDigit <> 0 And pValue < wDecade Then        ' \
               Print " "                                    ' | Blank out the digits Cancella le cifre
            Else                                            ' /
                Print (wPattern.HighByte & %11110000) >> 4,_ ' \
                      wPattern.HighByte & %00001111,_        ' | Print the big digit
                      (wPattern.LowByte & %11110000) >> 4,_  ' |
                      wPattern.LowByte & %00001111           ' /
            EndIf         
            If bDigit <> 0 Then
                Print " "
            EndIf
            wDecade = wDecade / 10
        Next
    Next
EndProc

'--------------------------------------------------------------------------------------------
' Sets up the UDGs used for the digits in the 4x20 alphanumeric LCD
' Input     : None
' Output    : None
' Notes     : None
'
Proc LCD_Setup_UDGs()
    Dim bIndex As Byte
'
' Define bit patterns for the LCD's UDGs
'
    Dim UDG_Data As Flash8 = %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00001,_       ' | Left-right up-ramp
                             %00011,_       ' |
                             %00111,_       ' |
                             %01111,_       ' |
                             %11111,_       ' /
                           
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %10000,_       ' | Right-left
                             %11000,_       ' |
                             %11100,_       ' |
                             %11110,_       ' |
                             %11111,_       ' /
                           
                             %11111,_       ' \
                             %01111,_       ' |
                             %00111,_       ' |
                             %00011,_       ' | Left-right down ramp
                             %00001,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                           
                             %11111,_       ' \
                             %11110,_       ' |
                             %11100,_       ' |
                             %11000,_       ' | Right-left
                             %10000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                           
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' | Lower block
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' /
                           
                             %11111,_       ' \
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' | Upper block
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' /
                           
                             %11111,_       ' \
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' | Full block
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' |
                             %11111,_       ' /
                           
                             %00000,_       ' \
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' | Full blank
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000,_       ' |
                             %00000         ' /   
    Print $FE, $40                          ' Enter CGRAM mode in the LCD
    For bIndex = 0 To 63                    ' Create a loop to read the UDG data
        Print CRead8 UDG_Data[bIndex]       ' Output the bit patterns to the LCD
    Next
EndProc

'------------------------------------------------------------------------
'To move the percentage symbol on the display according to the AD values

Proc print_100x100()  'print large symbol % a value 100%

    Print At 1,17,6
    Print At 1,20,6
    Print At 2,19,6
    Print At 3,18,6
    Print At 4,17,6
    Print At 4,20,6
     
EndProc
'-----------------------------------------------------------------------
Proc print_0x100()   'print large symbol % a value 0%

    Print At 1,12,6
    Print At 1,15,6
    Print At 2,14,6
    Print At 3,13,6
    Print At 4,12,6
    Print At 4,15,6
     
EndProc
 '------------------------------------------------------------------------
Proc print_x100()    'print large symbol % a value 1 to 99%

    Print At 1,15,6
    Print At 1,18,6
    Print At 2,17,6
    Print At 3,16,6
    Print At 4,15,6
    Print At 4,18,6
     
EndProc


top204

Nicely adapted to your requirements Giuseppe.

And nicely done to create the percentage character. The Proton compiler makes it all so straightforward doesn't it? Not simpler code, but easier to understand and manage.

Giuseppe

I fully agree Proton makes everything so simple and lends itself to the various customization of the code according to everyone's needs