MEL PICBASIC Forum - LED bar graph with selectable range min and max


  • LED bar graph with selectable range min and max


    Click image for larger version.

    Code:
    DEFINE OSC 4
    ;----[USART Settings]-------------------------------------------------------
    DEFINE HSER_RCSTA 90h    ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h    ' Enable transmit, BRGH=1
    DEFINE HSER_SPBRG 25     ' 9600 Baud @ 4MHz, 0.16%
    DEFINE HSER_CLROERR 1    ' Clear overflow automatically
    
    ;----[LCD Settings]---------------------------------------------------------
    DEFINE LCD_DREG PORTA     ' LCD data port
    DEFINE LCD_DBIT 4         ' LCD data starting bit 0 or 4
    DEFINE LCD_RSREG PORTA    ' LCD register select port
    DEFINE LCD_RSBIT 2        ' LCD register select bit
    DEFINE LCD_EREG PORTA     ' LCD enable port
    DEFINE LCD_EBIT 3         ' LCD enable bit
    DEFINE LCD_BITS 4         ' LCD bus size 4 or 8
    DEFINE LCD_LINES 2        ' Number lines on LCD
    DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
    DEFINE LCD_DATAUS 50      ' Data delay time in us
    
    ;----[A/D Settings]---------------------------------------------------------
    DEFINE ADC_BITS 10        ' ADCIN resolution  (Bits)
    DEFINE ADC_CLOCK 1        ' ADC clock source  (Fosc/8)
    DEFINE ADC_SAMPLEUS 11    ' ADC sampling time (uSec)
    
    ;----[Variables]------------------------------------------------------------
    GraphMAX   VAR WORD
    GraphMIN   VAR WORD
    GraphVal   VAR WORD
    X          VAR WORD
    ADval      VAR WORD
    Xmax       VAR WORD
    Xmin       VAR WORD
    char       VAR BYTE
    OverRange  VAR BIT
    UnderRange VAR BIT
    
    ;----[Aliases]--------------------------------------------------------------
    RCIF       VAR PIR1.5
    OverPin    VAR PORTC.5
    UnderPin   VAR PORTC.4
    
    ;----[Default Values]-------------------------------------------------------
    GraphMAX   = 100
    GraphMIN   = 0
    Xmax    = 100
    Xmin      = 0
    
    ;----[Initialize]-----------------------------------------------------------
    PORTB = 0
    TRISB = 0
    PORTD = 0
    TRISD = 0
    ANSEL = %00000001
    ANSELH = 0
    ADCON1.7 = 1
    PAUSE 250 : LCDOUT $FE,1 : PAUSE 250 : LCDOUT $FE,1
    GOSUB ShowMenu
    GOSUB ShowLimits
    OverRange = 0
    UnderRange = 0
    
    ;----[Main Program Loop]----------------------------------------------------
    Main:
        IF RCIF THEN GOSUB Terminal
        GOSUB GetAD
        GOSUB ShowGraph
        GOSUB CheckOverUnder
    GOTO Main
    
    ;----[Get and Scale Analog Reading]-----------------------------------------
    GetAD:
        ADCIN 0, ADval
        X = ADval * (Xmax - Xmin)
        X = DIV32 1023 + Xmin
        LCDOUT $FE,$80, "AD=",DEC ADval, "    "
        LCDOUT $FE,$8B, "X=",DEC X, "    "
    RETURN
    
    ;----[Show the BarGraph]----------------------------------------------------
    ShowGraph:
        IF X > GraphMAX THEN
            OverRange = 1
        ELSE
            OverRange = 0
        ENDIF
        IF X < GraphMIN THEN
            UnderRange = 1
        ELSE
            UnderRange = 0
        ENDIF
        X = (X MIN GraphMAX) MAX GraphMIN
        
        ;-- This is the formula being tested ---------------------
        GraphVal = $FFFF >> (16-(((X - GraphMIN) * 16) / (GraphMAX - GraphMIN)))
        
        PORTD = GraphVal & $FF
        PORTB = GraphVal >> 8
    RETURN
    
    ;----[Show Menu for Terminal]-----------------------------------------------
    ShowMenu:
        HSEROUT ["MENU: 1=GraphMAX, 2=GraphMIN, 3=Xmax, 4=Xmin :"]
    RETURN
    
    ;----[Handle the RS232 Terminal]--------------------------------------------
    Terminal:
        HSERIN [char]
        SELECT CASE char
          CASE "1" : HSEROUT [13,10,"Enter the GraphMAX: "]
                     HSERIN  [DEC GraphMAX]
          CASE "2" : HSEROUT [13,10,"Enter the GraphMIN: "]
                     HSERIN  [DEC GraphMIN]
          CASE "3" : HSEROUT [13,10,"Enter the Xmax: "]
                     HSERIN  [DEC Xmax]
          CASE "4" : HSEROUT [13,10,"Enter the Xmin: "]
                     HSERIN  [DEC Xmin]
          CASE ELSE : HSEROUT [7]
        END SELECT
    
    ;----[Show Limits]----------------------------------------------------------
    ShowLimits:
        LCDOUT $FE,$C0,"    GRAPH    X      "
        LCDOUT $FE,$94,"MAX:                "
        LCDOUT $FE,$D4,"MIN:                "
        LCDOUT $FE,$99,DEC GraphMAX
        LCDOUT $FE,$D9,DEC GraphMIN
        LCDOUT $FE,$A1,DEC Xmax
        LCDOUT $FE,$E1,DEC Xmin
    
    RETURN
    
    ;----[Look for Over and Under Range]----------------------------------------
    BlinkSpeed  CON 50
    BlinkCount  VAR WORD
    
    CheckOverUnder:
        BlinkCount = BlinkCount + 1
        IF BlinkCount = BlinkSpeed THEN
            BlinkCount = 0
            IF OverRange THEN
                TOGGLE OverPin
            ELSE
                LOW OverPin
            ENDIF
            IF UnderRange THEN
                TOGGLE UnderPin
            ELSE
                LOW UnderPin
            ENDIF
        ENDIF
    RETURN
    
    This article was originally published in forum thread: Whats the quickest way to set bits? started by bearpawz View original post