''*************************************************************************************************
''IMPORTANT: Please run this code and attempt to understand it before advancing
'' Future examples will be added and each will
'' increase in complexity and/or cover a different concept.
''*************************************************************************************************
''
'' EXAMPLE Light meter, LED both measure light and indicates brightness
'' Brightness is indicated by bar graph on 8 leds on demo board
''
'' DIFFICULTY LEVEL: Very easy
''
'' Submitted by Tracy Allen, 1 March 2006
'' File: lightMeter2.spin
''
''PURPOSE:
'' -- This program builds on lightmeter1.spin, to add a bar graph indicator.
'' The demo board has 8 leds attached to pins a16 to a23, such that
'' bringing those pins high causes the yellow leds on the demo board to
'' light. This program turns those leds into a bar graph that
'' displays the ratiometric light level in a logarithmic progression,
'' like a VU meter--Double the light, one more bar, halve it, one less bar.
'' -- Teaches reading a value into a variable, a couple of math operators,
'' and displaying a result using available hardware.
'' -- Same circuit as lightMeter1:
''
'' 330Ω green Led
'' a1 ─────┳───────┐ a1 (+) ─────────── (-) a0
'' │ │ I ────
'' └────────┫
'' 220pf │
'' a0 ─────────────────┘ a1 (-) ─────────── (+) a0
'' ────── I
''
''*************************************************************************************************
'' CORRECT OUTPUT: The LED mounted on the prototyping block will blink at a rate that depends on
'' ambient light level. And the 8 yellow leds will light up as a bar graph VU meter
'' to show the light level. The program captures the intial light level (when you first run
'' the program) and calls that the middle value. Subsequently, when you shade the LED
'' there are fewer bars, and when you increase the light there are more bars.
''*************************************************************************************************
CON
ledn = 0 ' LED cathode (negative, n-type semiconductor) attached to this pin
ledp = 1 ' LED anode (positive, p-type semiconductor) attached to this pin
'This program leaves the clock at the default ~12 mHz RC clock source.
VAR
long ticker, ticker0
word ratio
PUB light_meter ' make a light meter from an LED
blipLED
readLED
ticker0 := ticker ' initial value, defines our maximum light level.
repeat ' repeat the following indented statements forever.
blipLED
readLED
logTicker ' Display the bar graph
PRI blipLED ' briefly flash the LED
outa[ledp] := 1 ' see lightMeter1 for comments
dira[ledp] := 1
outa[ledn] := 0
dira[ledn] := 1
waitcnt(240000 + cnt)
PRI readLED ' read the time it takes for photocurrent to charge capacitor
outa[ledp] := 0 ' see lightMeter1 for comments
dira[ledp] := 1
outa[ledn] := 1
dira[ledn] := 1
waitcnt(2400 + cnt)
ticker := 0 ' going to measure time ticks using this variable
dira[ledn] := 0
repeat until ina[ledn] == 0
++ticker ' every time around the loop, ticker increases by 1
' so it measures the time until ina[ledn] goes low
' ticker is a small number in bright light.
PRI logTicker ' to display the result time as logarithmic (VU) bar graph
dira := dira | $00ff0000 ' the yellow leds on demo booard are on a16-a23
ratio := ticker0 * 8 / ticker ' ratio = 8 when current light level = initial light level
' this ratio can range from 0 in dim light
' (when ticker is a large number, > ticker0 * 8)
' to a large number in bright light (ticker =1)
outa := (|< >| ratio -1) << 16 ' makes the output VU bar graph on a16--a23
' explanation of the math:
' There are two unary operators before ratio,
' so the one right before ratio is evaluated first:
' >| ratio says "what is highest bit set in ratio?..
' (plus 1)", so if ratio=17, then >| ratio is 5,
' because 17=%10001 and the highest bit set is bit 4
' Add one and get 5. If ratio=0, (in dim light where ticker is
' large), then (>| ratio)=0.
' On to (|< N). This says, "change the value, N,
' to a binary number that has a bit set in position n".
' For example, if (>| ratio) is 5, then (|< >| ratio) will be
' %100000. If >| ratio is zero, then ( |< >| ratio) is %1
' The resulting number is one of these binary value:
' 1,2,4,8,16,32,64,128, and so on. E.g., If ratio is
' 16--31, the output of the function is 16.
' In order of precedence, the formula then subtracts
' 1 from the pure binary value to get a number in the
' series 0,1,3,7,15,31,63,127,255 and so on.
' The final step, << 16, shifts the pattern 16 bits left
' so the pattern appears to light LEDs on pins a16 to a23.
' When ticker = ticker0, then
' (|< >| ratio -1) = 15
' and 4 of the leds will be lit. In brighter light
' when ticker