' Code for 12F629 PIC ' www.imakeprojects.com ' Mar 4 2007 ' ' Purpose: Read inputs from a pocket wifi-finder ' and output a "heatbeat" of a pace corresponding to ' the signal strength read from the inputs. ' ' The inputs are LEDs. (Not all are used.) ' The output is a vibe motor. ' Another output is to trigger the sensor. ' Note: the inputs are only stable if lit for > 500ms. ' ' 12F629 ' Pin 1 +V ' Pin 2 "pin 5" in PBC speak (GP5) ' Pin 3 "pin 4" (GP4) ' Pin 4 "pin 3" (GP3) Note: useful as an /input only (open coll) ' Pin 5 "pin 2" (GP2) ' Pin 6 "pin 1" (GP1) ' Pin 7 "pin 8" (GP0) ' Pin 8 GND ' ' Sensor: ' LED 4 (highest) to GP5 ' LED 3 to GP4 ' LED 2 to GP3 ' LED 1 No connection (GP1 acts funny on 12f629) ' LED 0 (red - no signal) OR connection to GP5 ' SW (activation switch) to GP2 ' ' Vibe Motor: to GP0 symbol signal_strength = b0 ' 0,1,2,3,4 = none, low, med, hi, full symbol activation_time = b1 ' loops between activations of sensor symbol loop_counter = b2 ' loop counter symbol loop_max = b3 ' max loops till reset symbol pulseloop = b4 ' For timing beats symbol hi_none_led = b5 ' Keeps track of LED lit state from loop to loop symbol med_led = b6 symbol low_led = b7 'symbol lowest_led = b8 ' Not actually used symbol last_hi_none = b9 symbol last_med = b10 symbol last_low = b11 'symbol last_lowest = b12 ' Not actually used symbol flag = b13 ' Inits ' Main loop description ' ' Each "loop" is about 500ms. Functions are padded if necessary. ' There are "timer counters" to use as "alarm clocks". Such as ' activation_time which - when this number of loops has been reached - ' results in triggering the sensor activation. ' ' The main loop increments the loop counter and checks to see ' if it is time to do anything (such as activate the sensor). ' ' The outputs (all but the lowest signal detection setting) are ' watched to see if any remain lit for at least 500ms. If so, set ' the signal strength according to the LEDs lit. ' ' The end of the main loop handles doing the "heartbeats" from the vibe motor ' at a rate matching the pulse rate (which is the signal strength). ' Inits activation_time = 40 loop_counter = 0 loop_max = activation_time + 1 'should equal biggest + 1 signal_strength = 0 pulseloop = 0 hi_none_led = 0 med_led = 0 low_led = 0 'lowest_led = 0 ' To signal is alive at powerup gosub heartbeat ' Alternate main loop start (see below at beginning of START) reset_loops: gosub sensor_activate loop_counter = 0 start: loop_counter = loop_counter + 1 ' Is it time to trigger the sensor? (Once every activation_time loops) if loop_counter = loop_max then reset_loops ' Look to see whether any LED has remained lit for ' at least 500ms. ' GP5 = HIGH SIGNAL (or NO SIGNAL) ' GP4 = MED SIGNAL ' GP3 = LOWER SIGNAL ' GP2 = LOWEST SIGNAL (NOT CONNECTED) ' GP5 = NO SIGNAL (it is an OR with HIGH SIGNAL) ' ' If an LED has been lit for at least 500ms then we're ' done scanning. Read what the signal strength is, and ' set the signal_strength accordingly. ' ' We do this by keeping the last reading and comparing to what ' it is now. ' last_hi_none = hi_none_led last_med = med_led last_low = low_led ' hi_none_led = pin5 med_led = pin4 low_led = pin3 ' Compare to see whether both of any are = 0 ' flag = last_hi_none + hi_none_led if flag = 0 then stable_signal flag = last_med + med_led if flag = 0 then stable_signal flag = last_low + low_led if flag = 0 then stable_signal ' else goto skip_scanning stable_signal: ' Set signal_strength according to highest led lit. ' But since HIGH SIGNAL and NO SIGNAL are shared, ' we need to do an additional check. ' ' On a genuine "HIGH SIGNAL", MED SIGNAL will also be set (the ' next LED down). ' Otherwise if it is really a NO SIGNAL, then MED SIGNAL will not ' be set. if hi_none_led = 0 then additional_check if med_led = 0 then signal_str_3 if low_led = 0 then signal_str_2 additional_check: if pin4 = 0 then signal_str_4 if pin4 = 1 then no_signal ' This should not happen... but just in case let user know ' something is pooched with an anomalous beat. error_cond: high 8 pause 150 low 8 pause 150 goto error_cond signal_str_4: signal_strength = 4 goto done_scanning signal_str_3: signal_strength = 2 goto done_scanning signal_str_2: signal_strength = 1 goto done_scanning no_signal: signal_strength = 0 goto done_scanning done_scanning: skip_scanning: ' Each main loop option here must take about 500ms (1/2 sec). ' Strongest signal results in one "heartbeat" per loop (1/500ms) ' Weakest results in one beat per four loops (1/2sec) ' Note that this corresponds nicely to signal strength from 1-4. ' ' Skip all if there is no signal anyway if signal_strength = 0 then no_pulse pulseloop = pulseloop + 1 ' increment the pulse loop "timer" if pulseloop <= 4 then not_reset_yet ' else reset pulseloop = 1 not_reset_yet: ' If the loop (1-4) is smaller or equal to signal str, then beat. if pulseloop <= signal_strength then pulsetime ' else goto no_pulse pulsetime: gosub heartbeat ' Takes 500ms to run goto start no_pulse: pause 500 ' each loop must be 500ms goto start ' Subroutines sensor_activate: low 2 pause 50 high 2 return heartbeat: high 0 pause 100 low 0 pause 400 return