The previous post was an attempt to write code for a rotary encoder that would allow the user to increment or decrement the value displayed by a factor of 1, on a 20x4 LCD. The range was set for 00.000 to 10.000. With the push of the shaft button on the rotary encoder, the user could select any of the 4 least significant digits to change their value from 0 to 9 individually. The most significant digit could only be set to 1 or 0, depending on the value of the least 4. If the least 4 were set to all zeros, then the 5th digit could be set to 1.

This next version accomplishes the same results with what I thought would be more efficient code. As it turns out, the original code uses 1549 words if you delete the command to clear PortD.5. It is not used nor necessary. The 2nd version does use less written code from the user but in turn, uses more words in memory than the original. 1572 words total to be exact. I have noticed and increase in word count at the time of compiling in other projects as well. I have come to the conclusion that using only "IF" statements uses less program memory.

I believe this code to be reliable and beneficial to anyone needing the features it provides to the user. I know there is more efficient code out there. I'm not proficient in programming like others who have been doing this for a long time so I leave it to this forum to evaluate and critique it for everyone's gain. If anyone can make use of this code or learn from it, then my task is complete for I have learned from it as well.

Please enjoy the code.
New code below,

csantex

Code:
'*******************************************************************************
;*  Name    : PIC16F887.BAS                                    
;*  Author  : CSANTEX                                   
;*  Notice  : Copyright (c) 2018                                
;*          : All Rights Reserved                               
;*  Date    :                                  
;*  Version : Version 2                                               
;*  Notes   :
'*******************************************************************************
;Max Word count available is 8192.  Max EEPROM available is 256 bytes
;*******************************************************************************
;This code displays a number that is incremented for clockwise rotation or decrements
;for counter-clockwise rotation on a 20x4 LCD.  The display has two digits to the
;left of the decimal and three digits to the right of the decimal.  Each time the
;shaft is pushed in, a digit is selected starting from left to right.  This code
;could be used to display voltages that are preset by a user on a diy power supply
;or for Ampere presets or any of the like.
;The code is a bit long but it works well.

;COULD USE MORE OPTIMIZATION!

;Original workd count=1549
;V2 word count =1572
;*******************************************************************************
;*******************************************************************************
'	include	"PIC16F887.PBPINC"	; processor specific variable definitions
    INCLUDE "Modedefs.Bas" 

    @ ERRORLEVEL -306   ; Suppress messages related to Page Boundries.
;*******************************************************************************
    #CONFIG
	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_ON & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO 
	__CONFIG    _CONFIG2, _WRT_OFF & _BOR40V
	#ENDCONFIG
	
    DEFINE OSC 8
       
    DEFINE LCD_DREG PORTD  ' PORTA is LCD data port 
    DEFINE LCD_DBIT 4  ' PORTA.4 is the data LSB ( 4 BIT MODE ) 
    DEFINE LCD_RSREG PORTB  ' RS is connected to PORTA.1 
    DEFINE LCD_RSBIT 0 
    DEFINE LCD_EREG PORTB  ' E is connected to PORTA.3
    DEFINE LCD_EBIT 1 
    DEFINE LCD_BITS 4  ' 4 lines of data are used (4 BITS)
    DEFINE LCD_LINES 4  ' It is a 4-line display 
    DEFINE LCD_COMMANDUS 1500 ' Use 1500uS command delay 
    DEFINE LCD_DATAUS 44   ' Use 44uS data delay
;*******************************************************************************
    OSCCON  = %01110000     ; Set PIC16F88 to 4MHz = %01100000, or
                            ; 8MHz = %01110000
    TRISA   = %11111111     ; Port A set to inputs
    TRISB   = %11101100     ; Port B set to OUTPUTS
    TRISC   = %01111111     ; Port C set to inputs
    TRISD   = %00000000     ; Port D set to Ouputs
    ANSEL   = %00000000     ; Set all analog pins to digital
    ANSELH  = %00000000
'    LED            var     PortD.7      ; LED for flashing
    A_IN           VAR     PORTC.6
    B_IN           VAR     PORTC.5
    SW_IN          VAR     PORTC.4
;*******************************************************************************
    ONES            VAR BYTE    ; VARIABLE
    TENS            VAR BYTE    ; VARIABLE
    HUND            VAR BYTE    ; VARIABLE
    THOU            VAR BYTE    ; VARIABLE
    TNTH            VAR BYTE    ; VARIABLE
    SUBTTL          VAR WORD    ; VARIABLE
    TOTAL           VAR WORD    ; TOTAL VALUE
    PLACE           VAR BYTE    ; VARIABLE

    MYFLAGS         VAR BYTE
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************        
;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
;******************************************************************************* 
INIT: 
    PAUSE 1000
    CLEAR
    PLACE = 6    

'    LCDOUT $FE, $C0, DEC PLACE    ;FOR DEBUG ONLY
'    LCDOUT $FE, $94, DEC5 (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES   ;FOR DEBUG ONLY

    LCDOUT $FE, $D4, DEC1 TNTH, DEC1 THOU, ".", DEC1 HUND, DEC1 TENS, DEC1 ONES


MAIN:
    IF A_IN < B_IN THEN
        IF PLACE = 6 AND TOTAL < 10000 THEN
            IF MYFLAGS.0 = 0 THEN 
                TOTAL = TOTAL + 1
                ONES = TOTAL DIG 0
                TENS = TOTAL DIG 1
                HUND = TOTAL DIG 2
                THOU = TOTAL DIG 3
                TNTH = TOTAL DIG 4
                GOSUB SHOW_TOTAL 
            ENDIF 
        ENDIF
        IF MYFLAGS.0 = 1 THEN
            IF TNTH = 0 THEN 
                SELECT CASE PLACE
                    CASE 5
                        ONES = ONES + 1
                        IF ONES > 9 THEN ONES = 0
                        GOSUB SHOW_ONES
                    CASE 4
                        TENS = TENS + 1
                        IF TENS > 9 THEN TENS = 0 
                        GOSUB SHOW_TENS
                    CASE 3
                        HUND = HUND + 1
                        IF HUND > 9 THEN HUND = 0
                        GOSUB SHOW_HUND
                    CASE 1
                        THOU = THOU + 1
                        IF THOU > 9 THEN THOU = 0
                        GOSUB SHOW_THOU
                END SELECT
            ENDIF
            IF SUBTTL = 0 THEN     
                IF PLACE = 0 THEN
                    TNTH = TNTH + 1
                    IF TNTH > 1 THEN TNTH = 0
                    GOSUB SHOW_TNTH
                    GOTO PUSHBUTTON
                ENDIF
            ENDIF 
        ENDIF   
        GOSUB SUM_TOTALS
        IF TOTAL = 10000 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            LCDOUT $FE, $80, "MAXIMUM LIMIT"
            PAUSE 1000
            LCDOUT $FE, $80, "             "
        ENDIF        
    ENDIF 
    
PUSHBUTTON:
    IF SW_IN = 0 THEN 
        PLACE = PLACE + 1
        IF PLACE = 2 THEN PLACE = 3 
        IF PLACE > 6 THEN PLACE = 0 
        LCDOUT $FE, $D4+PLACE
        
        IF PLACE = 6 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            MYFLAGS.0 = 0
        ELSE
            LCDOUT $FE, $0F
            LCDOUT $FE, $D4+PLACE
            MYFLAGS.0 = 1
        ENDIF  
               
        GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.         
    ENDIF
    GOSUB SUM_TOTALS        
    IF PLACE != 6 THEN  
        LCDOUT $FE, $0F
        LCDOUT $FE, $D4+PLACE
    ENDIF  

DECREMENT:
    IF B_IN < A_IN THEN 
        IF PLACE = 6 AND TOTAL > 0 THEN
            IF MYFLAGS.0 = 0 THEN
                TOTAL = TOTAL - 1
                ONES = TOTAL DIG 0
                TENS = TOTAL DIG 1
                HUND = TOTAL DIG 2
                THOU = TOTAL DIG 3
                TNTH = TOTAL DIG 4 
                GOSUB SHOW_TOTAL 
            ENDIF
        ENDIF
        IF MYFLAGS.0 = 1 THEN
            IF TNTH = 0 THEN 
                SELECT CASE PLACE
                    CASE 5
                        ONES = ONES - 1
                        IF ONES > 9 THEN ONES = 9
                        GOSUB SHOW_ONES
                        GOTO MAIN
                    CASE 4
                        TENS = TENS - 1
                        IF TENS > 9 THEN TENS = 9 
                        GOSUB SHOW_TENS
                        GOTO MAIN
                    CASE 3
                        HUND = HUND - 1
                        IF HUND > 9 THEN HUND = 9
                        GOSUB SHOW_HUND
                        GOTO MAIN
                    CASE 1
                        THOU = THOU - 1
                        IF THOU > 9 THEN THOU = 9
                        GOSUB SHOW_THOU
                        GOTO MAIN
                END SELECT
            ENDIF 
            IF SUBTTL = 0 THEN       
                IF PLACE = 0 THEN
                    TNTH = TNTH - 1
                    IF TNTH > 1 THEN TNTH = 1
                    GOSUB SHOW_TNTH
                    GOTO MAIN
                ENDIF
            ENDIF 
        ENDIF
        GOSUB SUM_TOTALS
        IF TOTAL = 0 THEN 
            LCDOUT $FE, $0C  ;BLINK OFF
            LCDOUT $FE, $80, "MINIMUM LIMIT"
            PAUSE 1000
            LCDOUT $FE, $80, "             "
        ENDIF     
    ENDIF 
    GOTO MAIN
    
SHOW_TOTAL: 
'    LCDOUT $FE, $94, DEC5 (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES    ;FOR DEBUG ONLY

    LCDOUT $FE, $D4, DEC1 TNTH, DEC1 THOU, ".", DEC1 HUND, DEC1 TENS, DEC1 ONES     

DEBOUNCE:    
    WHILE A_IN=0 OR B_IN=0 OR SW_IN=0   ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    WEND
    RETURN 

;******************************************************************************* 
SHOW_TNTH:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D4, DEC1 TNTH
    LCDOUT $FE, $D4
    LCDOUT $FE, $0F ;BLINK ON
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_THOU:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D5, DEC1 THOU
    LCDOUT $FE, $D5
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_HUND:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D7, DEC1 HUND
    LCDOUT $FE, $D7
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_TENS:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D8, DEC1 TENS
    LCDOUT $FE, $D8
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SHOW_ONES:
    LCDOUT $FE, $0C ;BLINK OFF
    LCDOUT $FE, $D9, DEC1 ONES
    LCDOUT $FE, $D9
    LCDOUT $FE, $0F
    GOSUB DEBOUNCE  ;DO NOTHING WHILE WE WAIT TO RELEASE THE BUTTON.
    RETURN
SUM_TOTALS:
    TOTAL = (TNTH*10000)+(THOU*1000)+(HUND*100)+(TENS*10)+ONES
    SUBTTL = (THOU*1000)+(HUND*100)+(TENS*10)+ONES
    RETURN
;******************************************************************************* 
  
;*******************************************************************************
    END