PDA

View Full Version : Scale 8bit ADC RGB LED voltmeter



Ryan7777
- 22nd February 2008, 02:19
I borrowed some code from a EDN.com article for what they call a "rainbow voltmeter" programmed in PBP.. the article takes a 12F675 and uses a RGB led to display a different color based on an 8 bit ADC input, shifting from "aqua" to "white" based on a voltage from 0 to 5 volts. at 2.5 volts the circuit switches the LED off for center dark. I modified the code a bit to get rid of the dark part, as i thought it was un-needed. I would like however, to scale the software to the lowest color "aqua" to = 1.60V and the highest color "white" = to 2.25V. I cant access the VREF pin (not because its in use by the LED, but because the circuit is already built)and "biasing" my input is a no go as well. It will have to be a mod of the software. they say that it is possible to do so in the article, but don't really say how and my math is terrible, like learning disability terrible! so if someone could show me some code, or the math, thank you! anyway, the following is the orignal code as printed by EDN.com

' PicBasic Pro program to read A/D on 12F675 ADC
' and display voltage A/D output using multi-color LED
' using a cold-to-hot color pallette. Center of range
' is dark.
'
' (c) 2003 by David Prutchi
'

i VAR BYTE ' Define loop variable
blue VAR BYTE ' Define blue pulse-width variable
green VAR BYTE ' Define green pulse-width variable
red VAR BYTE ' Define red pulse-width variable
' GPIO port 0 to GREEN LED
' GPIO port 1 TO RED LED
' GPIO port 2 to BLUE LED
color VAR BYTE ' Define LED color variable
x VAR BYTE ' Allocate A/D variable

' Set A/D Parameters
DEFINE ADC_BITS 8 ' Use 10-bit A/D as 8-bit A/D
ANSEL.3=1 ' Set ANS3 as analog input pin
ANSEL.4 = 0 ' Set A/D clock
ANSEL.5 = 1
ANSEL.6 = 0
ADCON0.0 = 1 ' Turn On A/D
ADCON0.2 = 1 ' A/D channel 3
ADCON0.3 = 1
ADCON0.6 = 0 ' VDD is voltage reference
ADCON0.7 = 0 ' Left Justify result

' Set GPIO port pins 0, 1 and 2 as outputs
TRISIO.0=0
TRISIO.1=0
TRISIO.2=0


GoTo mainloop ' Skip subroutines

' SUBROUTINES
' -----------

' Subroutine to read a/d converter
getad:

ADCON0.1 = 1 ' Start conversion
PauseUs 50 ' Wait for conversion
x = ADRESH
Return


' MAIN
' ----

mainloop:


GoSub getad ' Get x value by performing A/D conversion


' RGB ENCODING FUNCTION
' Convert A/D reading into color table
' Each color has 14 possible intensity levels


IF x<=42 Then 'aqua
red=x/3
blue=14
green=(42-x)/3
EndIF
IF x>42 AND x<=84 Then 'shades of violet
red=(84-x)/3
green=0
blue=14
EndIF
IF x>84 AND x<=126 Then 'shades of green
red=0
green=0
blue=(126-x)/3
EndIF
IF x>126 AND x<=130 Then 'dark
red=0
green=0
blue =0
EndIF
IF x>130 AND x<=172 Then 'shades of red
red=(x-130)/3
green=0
blue=0
EndIF
IF x>172 AND x<=214 Then 'red / orange / yellow
red=14
green=(x-172)/3
blue=0
EndIF
IF x>214 Then 'yellow to white
red=14
green=14
blue=(x-214)/3
EndIF


' PULSE WIDTH MODULATOR
' Each PWM frame has 14 steps.

For i = 1 TO 14 ' Cycle through 14 steps of frame
color=0
IF red>0 Then
color=color+2
red=red-1
EndIF
IF green>0 Then
color=color+1
green=green-1
EndIF
IF blue>0 Then
color=color+4
blue=blue-1
EndIF
GPIO=color
PauseUs 100 ' Allow LEDs to shine for a few microseconds
Next i
GPIO=0
GoTo mainloop ' Do it forever

End

skimask
- 22nd February 2008, 03:37
disable
blue var byte:green var byte:red var byte:greenled var gpio.0
redled var gpio.1:ansel=$68:greenled var gpio.0:trisio=0:temp var word
pwmcount var byte:adread var word:adcon=$8d:goto mainloop
on interrupt goto inthandle
inthandle:
if intcon.2 = 1 then 'tmr 0 overflow fired off
intcon.2 = 0 : pwmcount = pwmcount + 1 : if pwmcount = 0 then gpio = 0
if green > pwmcount then greenled = 1
if blue > pwmcount then blue = 1
if red > pwmcount then red = 1
endif
if pir1.6 = 1 then 'a/d convert int fired off
pir1.6=0:adread.highbyte=adresh:adread.lowbyte=adr es
if adread < 327 then adread = 0 'if less than minimum zero it
if adread > 460 then adread = 133 'if more than max, max it out
adread = adread - 327 'range of 133 (.0048828125 volts/bit)
adread = adread * 30 'scale it up to reach 12 usable bits
red=0:red.7=adread.11:red.6=adread.10:red.5=adread .9:red.4=adread.8
blue=0:blue.7=adread.7:blue.6=adread.6:blue.5=adre ad.5:blue.4=adread.4
green=0:green.7=adread.3:green.6=adread.2:green.5= adread.1:green.4=adread.0
endif
resume
enable
mainloop: @ nop
if adcon.1 = 0 then adcon.1 = 1
@ nop
goto waitforad
End


Try that for grins...
The LEDs should follow the voltage from 0 to 5v. If it actually works (I haven't tried it), you should be able to scale adread when it's read according to what you want to do. I just threw this together. Anything less than 1.6v, LEDs are dark, more than 2.25v LEDs are full bright, anything in between, the number gets converted to a 12bit value, high 4 bits to red, mid 4 bits to green, low 4 bits to blue.