Advertisement  

Thursday, 03 July 2025
     
 
Main Menu
Home Home
Shop Shop
News News
BASCOM-AVR BASCOM-AVR
BASCOM-8051 BASCOM-8051
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-AVR Help BASCOM-AVR Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login
Username

Password

If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News
 
     
 

 
   
     
 
AN #107 - Logarithmic bar graph (LED and LCD) Print
Logarithmic bar graph (LED and LCD)

Application note written by Ger Langezaal

This program is written to create a logarithmic LED/LCD bar graph dB (VU) meter with peak-hold and drop-down. Scale range is 30dB in 3dB steps.
The smart part is that the log conversion is done with the analog comparator on a RC discharge curve.

Ger created two versions : one with an LCD display and one with LED's. The LED version is included here. The LCD version can be downloaded.

Download source code


'-------------------------------------------------------------------------------
' Filename : BG30dB_LED.bas
' Revision : 1.0
' Controller : AVR AT90S2313-10
' Author : Ger langezaal
' Compiler : BASCOM-AVR Rev. 1.11.6.2
' ROM image : 3EE hex (1006 dec)
'
'---[ Small program description ]-----------------------------------------------
'
' This program is written to create a logarithmic LED bar graph dB (VU) meter
' with peak-hold and drop-down. Scale range is 30dB in 3dB steps.
' Log conversion is done with the analog comparator on a RC discharge curve.
' C1 is charged each 4mS with PB0 as output on a Timer0 Interrupt.
' Then PB0 is set to AIN0 (analog comparator +input) Timer1 is reset
' and start counting, C1 will be discharged by R1.
' Timer1 is counting until AIN0 < AIN1.
' Analog Comparator Output = ACSR bit 5.
' Timer1 value is in T1 stored for calculation.
'
' Display mode is set with PD6 (pin 11).
' 1 = bar mode
' 0 = dot mode (for low current applications)

'---[ LED to AVR connections ]--------------------------------------------------
'
' AVR Resistor Cathode dB
' Port pin Ohm LED nr Scale
' PD5 9 >--[680]--> 11 +6
' PD4 8 >--[680]--> 10 +3
' PD3 7 >--[680]--> 9 0
' PD2 6 >--[680]--> 8 -3
' PD1 3 >--[680]--> 7 -6
' PD0 2 >--[680]--> 6 -9
' PB7 19 >--[680]--> 5 -12
' PB6 18 >--[680]--> 4 -15
' PB5 17 >--[680]--> 3 -18
' PB4 16 >--[680]--> 2 -21
' PB3 15 >--[680]--> 1 -24
' PB2 14 >--[680]--> 0 infinit
'
' All LED Anodes to +5 Volt
'
'---[ Analog comparator inputs ]------------------------------------------------
'
'
' Meter DC input >-------[ R2 ]-------> PB1 (AIN1 pin 13)
' |
' GND <---------||-----
' C2
'
' ---[ R1 ]---
' GND <----| |----> PB0 (AIN0 pin 12)
' -----||-----
' C1
' R1 = 10k 5%
' R2 = 10k
' C1 = 47nF 5%
' C2 = 47nF
'
'---[ DC input versus Timer1 and Led position ]---------------------------------
'
' Measured Timer1 values for calculation:
' DC input = 3500mV Timer1 = 192 ( +6dB)
' DC input = 312mV Timer1 = 1544 (-15dB) 21dB = factor 11.22
' 21dB = 1543 - 192 = 1351 Timer1 counts
' 3dB = 1351 / 7 = 193 Timer1 counts
'
' Input mv Timer1 LED pos dB scale
' 3500 192 11 +6
' 2477 385 10 +3
' 1753 578 9 0
' 1241 771 8 -3
' 879 965 7 -6
'  622 1158 6 -9
' 440 1351 5 -12
' 312 1544 4 -15
' 220 1737 3 -18
' 156 1930 2 -21
' 110 2123 1 -24
' <110 >2123 0  infinit
'
'---[ Compiler and hardware related statements ]--------------------------------

$regfile = "2313def.dat" 'register file for AT90S2313
$crystal = 10000000 '10MHz crystal

Ddrb = &B11111100 'PB0 and PB1 are analog inputs
Portb.0 = 0 'disable input pullup
Portb.1 = 0 'disable input pullup

Ddrd = &B10111111 'config PD6 as input
Portd = &B11111111 'output high and enable input pullup

Acsr.7 = 0 'enable analog comparator ACSR bit 7 = 0

'---[ Variables ]---------------------------------------------------------------

Dim Peak_pos As Byte
Dim Peak_hold As Byte
Dim Drop_hold As Byte
Dim Led_pos As Word
Dim Bar_pattern As Word
Dim T1 As Word

'---[ Constants ]---------------------------------------------------------------

Const Peak_hold_time = 200
Const Drop_down_time = 40
Const Led_max = 11 'Led 0 - 11
Const T1_fs = 192 'full scale Timer1 value
Const T1_step = 193 '3dB step Timer1 value
Const T1_range = T1_step * Led_max + T1_fs 'Calculate Timer1 range

Displ_mod
Alias Pind.6 'display mode 1 = Dot 0 = Bar
Ac_out
Alias Acsr.5 'analog comparator output = ACSR bit 5

'---[ Timer Configuration ]-----------------------------------------------------

Config Timer0 = Timer , Prescale = 256 'On Interrupt Timer
Config Timer1 = Timer , Prescale = 8 'R/C Timer
Config Watchdog = 1024 'reset after 1 Sec no reset watchdog
Enable Interrupts
Enable Timer0
Enable Timer1
On Timer0 Dc_input_sample 'on overflow timer0 jump to label
Timer0 = 0
Timer1 = 0
Start Timer0
Start Timer1

'---[ Main program loop ]-------------------------------------------------------

Do
 Bar_pattern
= &HFFFF 'set all bits

 
If Displ_mod = 1 Then 'bar display mode
 Bar_pattern
= Lookup(led_pos , Bar_mode)
 
Else 'dot display mode
 Bar_pattern
.led_pos = 0 'reset dot bit
 
End If

 Bar_pattern
.peak_pos = 0 'reset peak bit

 
Portd.5 = Bar_pattern.11 'led 11 = bit 11
 
Portd.4 = Bar_pattern.10
 
Portd.3 = Bar_pattern.9
 
Portd.2 = Bar_pattern.8
 
Portd.1 = Bar_pattern.7
 
Portd.0 = Bar_pattern.6
 
Portb.7 = Bar_pattern.5
 
Portb.6 = Bar_pattern.4
 
Portb.5 = Bar_pattern.3
 
Portb.4 = Bar_pattern.2
 
Portb.3 = Bar_pattern.1
 
Portb.2 = Bar_pattern.0 'led 0 = bit 0
Loop

'-------------------------------------------------------------------------------
End
'-------------------------------------------------------------------------------

'---[ Interrupt Service Routine on Timer0 overflow ]---------------------------

Dc_input_sample
:
 
Timer0 = 100 'preset Timer0 for sample rate of 4mS

 
Ddrb.0 = 1 'set AIN0 as PB0 output
 
Portb.0 = 1 'set PB0 high to charge C1
 
Waitus 200 'wait for charge complete
 
Ddrb.0 = 0 'reset PB0 as AIN0 analog input
 
Portb.0 = 0 'disable AIN0 pullup

 
Timer1 = 0 'clear R/C Timer1
 
Bitwait Ac_out , Reset 'wait for AIN0 < AIN1
 T1
= Timer1 'read Timer1 value

 
If T1 < T1_fs Then 'check T1 low limit
 T1
= T1_fs 'T1 clipping
 
Elseif T1 > T1_range Then 'check T1 high limit
 T1
= T1_range 'T1 clipping
 
End If

 Led_pos
= T1_range - T1 'calculate led position
 Led_pos
= Led_pos T1_step 'led_pos = 0 - 11

 
If Led_pos >= Peak_pos Then 'new peak value
 Peak_pos
= Led_pos 'store peak value
 Peak_hold
= Peak_hold_time  'preset peak hold timer
 
Else
 
If Peak_hold > 0 Then
 
Decr Peak_hold
 
Else
 
If Drop_hold > 0 Then
 
Decr Drop_hold
 
Else
 Drop_hold
= Drop_down_time 'preset drop down timer
 
If Peak_pos > 0 Then Decr Peak_pos 'drop down one position
 
End If
 
End If
 
End If
 
Reset Watchdog
Return

'---[ Led Bar pattern lookup data ]---------------------------------------------

' Led 11......... 0
Bar_mode
:
Data &B1111111111111110% 'Word constants must end with the %-sign
Data &B1111111111111100%
Data &B1111111111111000%
Data &B1111111111110000%
Data &B1111111111100000%
Data &B1111111111000000%
Data &B1111111110000000%
Data &B1111111100000000%
Data &B1111111000000000%
Data &B1111110000000000%
Data &B1111100000000000%
Data &B1111000000000000%

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