• PicŪ Basic


  • LED Bargraph with Peak Hold LED

    LED-Bargraph-HOLD-PEAK-Help

    This question got me curious, so I've created a simple program, without any code tweaks, to create an LED bar and have a single LED peak mechanism that only lasts for so long. The code could be tweaked for better optimisation, but it seems to work OK.

    Because all the LEDs do not fit on a single PORT, Oring and Anding would have actually produced a lot more code, and made it more complex to read and understand, so this code uses simple port and bit manipulations.

    A mechanism could also be created within the code to make the peak LED drop down until it reaches the actual voltage. This would be done with another counter variable. Then when reached, it decrements the bPeakValue variable until it reaches bBarValue. The counter variable would be used to slow down the decrement rate.


    Code:
    ' A simple LED bar for Voltage that also includes a simple peak LED display
    ' This version performs a bar graph
    ' Written by Les Johnson for the Proton BASIC compiler
    '
        Device = 16F88
        Declare Xtal = 10            
    '    
    ' Define ADC parameters
    '
        Declare Adin_Res = 8            ' 8-bit result required
        Declare Adin_Tad = FRC          ' RC OSC chosen
        Declare Adin_Stime = 50         ' Allow 50us sample time
                          
        Dim bBarValue As Byte           ' Holds the value to display
        Dim bPeakValue As Byte          ' Holds the peak value
        Dim bAudioIn As Byte            ' Holds the value from the ADC
        Dim wPeakSamples As Word        ' Holds the amount of ADC samples before the peak is removed
    '
    ' Define the port and pins used for the LEDs
    '
    $define LED_Port PORTB
    $define LED0 PORTB.0
    $define LED1 PORTB.1
    $define LED2 PORTB.2
    $define LED3 PORTB.3
    $define LED4 PORTB.4
    $define LED5 PORTB.5
    $define LED6 PORTB.6
    $define LED7 PORTB.7
    $define LED8 PORTA.3
    $define LED9 PORTA.4
    
    $define cPeakAmount 1000                    ' The amount of ADC samples to take before the peak is reset
            
        GoTo Main                               ' Jump to the main program loop
    
    '----------------------------------------------------------------------------------
    ' Display the standard voltage between 0 to 255 on all 10 LEDs as a bar
    ' Input     : bBarValue holds the value to display
    ' Output    : None
    ' Notes     : None
    '
    $define LED_Voltage(pValue) '
        bBarValue = pValue      '
        GoSub _LED_Voltage
                    
    _LED_Voltage:
        Select bBarValue                         ' Do a comparison on the voltage value
            Case 0                               ' Is the value 0?
                LED_Port = $00                   ' \
                Clear LED8                       ' | Yes. So extinguish all the LEDs 
                Clear LED9                       ' / 
            Case 1 To  24                         ' Is it enough for LED0?
                LED_Port = $01                   ' \
                Clear LED8                       ' | Yes. So  LEDs
                Clear LED9                       ' /
            Case 25 To 49                        ' Is it enough for LED1?     
                LED_Port = $03                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 50 To 74                        ' Is it enough for LED2?  
                LED_Port = $07                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs 
                Clear LED9                       ' / 
            Case 75 To 99                        ' Is it enough for LED3? 
                LED_Port = $0F                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 100 To 124                      ' Is it enough for LED4?
                 LED_Port = $1F                  ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 125 To 149                      ' Is it enough for LED5? 
                LED_Port = $3F                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 150 To 174                      ' Is it enough for LED6? 
                LED_Port = $7F                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 175 To 199                      ' Is it enough for LED7?        
                LED_Port = $FF                   ' \
                Clear LED8                       ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 200 To 224                      ' Is it enough for LED8?         
                LED_Port = $FF                   ' \
                Set LED8                         ' | Yes. So illuminate the LEDs
                Clear LED9                       ' /
            Case 225 To 255                      ' Is it enough for LED9?        
                LED_Port = $FF                   ' \
                Set LED8                         ' | Yes. So illuminate the LEDs
                Set LED9                         ' /
        EndSelect
        Return
    
    '----------------------------------------------------------------------------------
    ' Display the peak voltage between 0 to 255 on one of 10 LEDs
    ' Input     : bPeakValue holds the value to display
    ' Output    : None
    ' Notes     : The Peak LED only lasts for as long as the amount of samples in wPeakSamples compared to cPeakAmount
    ' 
    $define LED_Peak(pValue) '
        bPeakValue = pValue  '
        GoSub _LED_Peak
                    
    _LED_Peak:
        Select bPeakValue                       ' Do a comparison on the voltage value
            Case 1 To 24                        ' Is it enough for LED0?
                Set LED0
            Case 25 To 49                       ' Is it enough for LED1?     
                Set LED1  
            Case 50 To 74                       ' Is it enough for LED2?  
                Set LED2
            Case 75 To 99                       ' Is it enough for LED3?
                Set LED3
            Case 100 To 124                     ' Is it enough for LED4?
                Set LED4
            Case 125 To 149                     ' Is it enough for LED5? 
                Set LED5
            Case 150 To 174                     ' Is it enough for LED6? 
                Set LED6
            Case 175 To 199                     ' Is it enough for LED7?        
                Set LED7
            Case 200 To 224                     ' Is it enough for LED8?         
                Set LED8
            Case 225 To 255                     ' Is it enough for LED9?       
                Set LED9
        EndSelect
        Inc wPeakSamples                        ' Increment the peak samples value
        If wPeakSamples >= cPeakAmount Then     ' Have we reached the time to reset the peak?
            Clear wPeakSamples                  ' Yes. So reset the counter
            Clear bPeakValue                    ' Clear the peak voltage value
        EndIf
        Return
            
    '----------------------------------------------------------------------------------                   
    ' The main program loop starts here
    '
    Main:
        ADCON0 = 0                              ' Make PORTA.0 analogue input
        ADCON1bits_ADFM = 0                     ' Set left justify result for 8-bit operation
        Low LED_Port                            ' \
        Low LED8                                ' | Set the LED pins output low
        Low LED9                                ' /
        bPeakValue = 0
        wPeakSamples = 0
    
        Do                                      ' Create a loop                
            bAudioIn = ADIn 0                   ' Get an ADC reading        
            LED_Voltage(bAudioIn)               ' Display the standard voltage on the LEDs        
            If bAudioIn > bPeakValue Then       ' Is the ADC reading grreater than the current peak value?
                bPeakValue = bAudioIn           ' Yes. So update the peak value
            EndIf
            LED_Peak(bPeakValue)                ' Display the peak voltage on an LED
                   
            DelayMS 10                          ' A small delay
        Loop                                    ' Do it forever
    Here's a screenshot of Isis simulating the above code. Notice the bargraph with the seperate LED for peak.

    This article was originally published in forum thread: LED Bargraph - HOLD PEAK - Help started by stefano View original post