''************************************************************************************************* ''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 LED both measures light and indicates brightness '' '' DIFFICULTY LEVEL: Very easy '' '' Submitted by Tracy Allen, 1 March 2006 '' Files: lightMeter1.spin '' ''PURPOSE: '' -- A green LED is hooked up between two pins so that it can be both forward biased to make '' it light up, and then reverse biased so that it can be used as a photodiode to measure '' ambient light levels. In the second mode, a capacitor is charged up to 5 volts '' and the program measures how long it takes for the capacitor to discharge '' down to 1.65 volts (like RCTIME on the Stamp). '' -- The Propeller runs on 3.3 volts, and its input switching threshold is 1/2 of that, '' close to 1.65 volts. The tiny photocurrent produced by light discharges the capacitor, '' and a propeller input pin detects when the voltage level hits the threshold. '' -- Each time through the loop, the program turns the LED to its normal use and has it emit a '' brief flash of light. This indicates how fast the program loop is running, and '' therefore the light level. '' -- This example illustrates the electronics of the LED as both an input and an output device, '' and how to wire up a simple circuit on the prototyping block. '' -- This program shows how to set a Propeller pin for input and how to make it wait '' until the voltage at the input hits the threshold. '' -- The program shows how to do that using a coded repeat loop with the "until" '' modifier, and alternatively how to use the unique propeller commands waitpeq and waitpne '' to accomplish the same thing. The program uses only one COG. '' -- Parts required, one green LED, one 330 ohm resistor, one 220pf capacitor, one jumper wire. '' These parts must be mounted on the white prototyping block with connection to the '' Propeller pins. The LED is connected between two input pins, with the anode (long lead) '' to pin LEDp=1 and the cathode to pin LEDn=0. It uses two pins so it can use the LED '' in normal forward mode to blink it, '' -- The following is the circuit diagram rendered in ascii... '' '' 330 green LED '' a1------/\/\---o--->|-----; a1 (+) ----->|----- (-) a0 '' | p n | ------> forward bias '' | | lights LED '' === 220pf | '' | | '' a0-------------o----------' a1 (-) ----->|----- (+) a0 '' <------ reverse bias '' discharges capacitor '' rate proportional to light '' '' -- The following are the same diagrams, rendered in the Parallax font... '' Find the character chart on the HELP menu. '' '' 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. Note: if you actually touch the led or even if you almost touch it, '' even in the dark, it will start to blink very fast. That is due to 60hz noise coupling from the '' AC power lines. ''************************************************************************************************* 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. PUB light_meter repeat ' repeat the following two lines forever. blipLED readLED ' -- end of repeat9 PRI blipLED ' briefly flash the LED, forward bias outa[ledp] := 1 ' LEDp is a high output dira[ledp] := 1 outa[ledn] := 0 ' LEDn is a low output dira[ledn] := 1 waitcnt(240000 + cnt) ' wait 24000 counts = about 2 milliseconds with 12 mhz clocking PRI readLED outa[ledp] := 0 ' reverse bias the LED and charge the 100 pf capacitor dira[ledp] := 1 ' both pins are outputs, opposite polarity outa[ledn] := 1 dira[ledn] := 1 waitcnt(2400 + cnt) ' allow time for the capacitor to charge, about 200 microseconds dira[ledn] := 0 ' make pin LEDn an input, no longer forced high, ' capacitor starts to discharge through LED. repeat until ina[ledn] == 0 ' pin LEDn reads high to start, but after time will drop to low ' the program loops here until the pin reading drops to low. '' -- Other things to try & observe... '' -- alternative, comment out the whole repeat line just above and comment in the following: '' '' waitpeq(0, |< ledn, 0) '' '' this single command means "wait until pin equals". The first parameter selects the state '' to wait for (=zero), and the second paramter is a mask for "which pin". The syntax, '' |< ledn '' means, "create a binary pattern that has only the ledn'th bit set to one, all others zero. '' -- A second alternative is "wait for pin not equal": '' '' waitpne( |< ledn, |< ledn, 0) '' '' Here it is waiting for the state to drop from its starting value of 1 '' (in the correct bit position, ledn). '' -- Experiment with different capacitors and different LEDs. '' Maybe green LED is not the best? Maybe you need to measure higher or lower light levels. '' Remember that light our eyes can respond to varies over 9 orders of magnitude, '' from 100000 lux in bright sunlight to less than 0.001 lux in quarter moonlight. '' The illumination level in a typical room is 10-1000 lux '' -- Note that the program stops working if you change the time from 2400 to 240 in the waitcnt instruction '' That is not because the capacitor wouldn't have time '' to charge. The time constant is 330 * 100 = 33 nanoseconds, so 20 microseconds should '' be plenty. It must be delays inherent in the Spin interpreter. With 240 there, '' the system counter moves faster than the interpreter's capability to check it. '' Keep time delays in mind as you program in Spin.