8th Generation Honda Civic Forum - View Single Post - J-RO'S ADAPTIVE XENON LIGHTS: THE PROJECT
View Single Post
Old 02-03-2007, 08:14 PM   #70 (permalink)
J-Ro
Six eyes
 
J-Ro's Avatar
 
Join Date: Apr 2006
Location: Ontario
Age: 29
Posts: 4,883
Jason
Okay, for all interested, the programming is now complete. All that remains for the electrical part is to mount all the circuitry onto a permanent board and put it in a case.
Here is the program, if anyone wants to replicate this and give it a try.
Anything after a single apostrophe is a comment. Also, I kept both debugging lines, but commented them out to keep them from bogging down the processor.
*EDIT* Sorry, but tabs don't seem to work here... the program is MUCH easier to read with the tabs in place.

'ProjectorControl.bs2
'Author: J-Ro
'Lines: 134
'Written: Dec. 14/2006
'Updated: Feb. 03/2007
'Content: This program provides control of the servomotors actuating xenon projector headlights.
' Real-world analog inputs are variable voltage via a potentiometer connected to the steering
' column and variable voltage via the speedometer signal. These analog signals are fed through
' an RC timer circuit into the BASIC Stamp I/O pins and indirectly converted from analog to
' digital via thePBASIC RCTIME command. The servomotors are powered by a dedicated 5V regulator,
' and the signal voltage is fed directly from the stamp I/O pins.
'
'Features: - Real-time control of projector position
' - Re-centering when car is stopped/re-positioning when car moves
' - Speed-sensitive control, preventing unnecessary movement during high-speed, low-wheel-movement
' maneuvers, such as lane changes
' - easily expandable to include driver-defined (rather than program-defined) settings, such as
' maximum angle, speed sensitivity and inclusion/exclusion of centering feature
'
'Hardware: - 1× Basic STAMP 2 OEM kit
' - 2× TowerPro SG5010 remote-control-style servomotors
' - 1× ML7805A voltage regulator (TO-220 package)
' - 1× 10 kohm, 10-turn potentiometer (McMaster-Carr p/n 7436K31)
' - 1× green, 2× red LEDs
' - 2× 10, 2× 470, 3× 510 ohm 1/4W resistors
' - 2× 1 µF, 50V polar electrolytic capacitors
' - 1× 1A quick-blow AGU fuse, fuse holder
' - 22AWG wire, red/black
' - circuit board etching kit
' - case

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

' {$STAMP BS2}
' {$PBASIC 2.5}

'Variables:
SPEED_IN VAR Word 'Speed signal from speedometer (units) (RCTIME unit = 2 µs)
WHEEL_IN VAR Word 'Wheel signal from potentiometer (units)
WHEEL_REV VAR Word 'Reverse of wheel signal (units)
FACTOR VAR Word 'Wheel vs. speed threshold

'Calibration constants:
SPEED_ZERO CON 271 'Zero value for speed (units)
MAX_L CON 550 'RCTIME value for max left position (units)
CENTRE CON 420 'RCTIME value for centre position (units)
MAX_R CON 240 'RCTIME value for max right position (units)
THR_SPD CON 5000 'Speed threshold (units)
THR_CTR CON 5 'Half of centre threshold (units)
MULT CON 2 'Multiplier for relative movement of outside light

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

MAIN: 'Main program

DIRS=%1111000000000000 'Set stamp I/O pins 0-3 as outputs and 4-15 as inputs

'Pin IDs:
'0 - Left servo OUT
'1 - Right servo OUT
'2 - Left LED OUT
'3 - Right LED OUT
'13 - Direction IN
'14 - Wheel position IN (RC timer circuit)
'15 - Speedometer IN

'PROGRAM LOAD 'Blink L/R LEDs once to confirm program is loaded
LOW 2 'LEDs off
LOW 3
PAUSE 500
HIGH 2 'LEDs on
HIGH 3
PAUSE 500
LOW 2 'LEDs off
LOW 3
PAUSE 500

DO
IF(IN13=1) THEN GOSUB REV_SERVO 'If reverse gear has been selected
GOSUB GET_SPEED 'Go to GET_SPEED subroutine to store speed data
GOSUB GET_POS 'Go to GET_POS subroutine to store wheel position data
FACTOR=SPEED_IN*ABS(CENTRE-WHEEL_IN)
IF(SPEED_IN>SPEED_ZERO) THEN 'Car must be in motion
'------------------
' DEBUG DEC WHEEL_IN, " ", DEC MAX_R, " ", DEC MAX_L, " ", DEC SPEED_IN, " ", DEC IN13, " ", DEC FACTOR, CR
'------------------
IF(SPEED_IN*ABS(CENTRE-WHEEL_IN)<THR_SPD) THEN 'If wheel vs. speed threshold is not being exceeded
LOW 2
LOW 3
PULSOUT 0, CENTRE
PULSOUT 1, CENTRE
ELSEIF(WHEEL_IN>MAX_R AND WHEEL_IN<MAX_L) THEN 'Keep signals between max L/R positions (~80° sweep)
IF(WHEEL_IN>(CENTRE+THR_CTR)) THEN 'Left turn, 2*THR_CTR threshold (keeps from jumping L/R)
HIGH 2 'Left LED on
LOW 3
PULSOUT 0,WHEEL_IN
PULSOUT 1,((WHEEL_IN-CENTRE)/MULT)+CENTRE 'Want less movement on outside light
ELSEIF(WHEEL_IN<(CENTRE-THR_CTR)) THEN 'Right turn, 2*THR_CTR threshold (keeps from jumping L/R)
LOW 2 'Right LED on
HIGH 3
PULSOUT 0,CENTRE-((CENTRE-WHEEL_IN)/MULT) 'Want less movement on outside light
PULSOUT 1,WHEEL_IN
ENDIF
ELSEIF(WHEEL_IN>MAX_L) THEN 'If wheel input signal goes beyond max left position
HIGH 2
LOW 3
PULSOUT 0,MAX_L
PULSOUT 1,((MAX_L-CENTRE)/MULT)+CENTRE
ELSEIF(WHEEL_IN<MAX_R) THEN 'If wheel input signal goes beyond max right position
LOW 2
HIGH 3
PULSOUT 0,MAX_R
PULSOUT 1,CENTRE-((CENTRE-MAX_R)/MULT)
ELSE 'Centre lights under all other conditions
HIGH 2
HIGH 3
PULSOUT 0, CENTRE
PULSOUT 1, CENTRE
ENDIF
ELSEIF(SPEED_IN<=SPEED_ZERO) THEN 'Centre the lights if the car is stopped
LOW 2
LOW 3
PULSOUT 0, CENTRE
PULSOUT 1, CENTRE
ELSE 'Error case (covers any/all erroneous I/O)
PULSOUT 0, CENTRE
PULSOUT 1, CENTRE
DO 'Flash L/R LEDs to indicate error
LOW 2
LOW 3
PAUSE 250
HIGH 2
HIGH 3
PAUSE 250
LOOP
ENDIF
LOOP 'Run continuously
END

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

GET_POS: 'Subroutine to acquire wheel position data
HIGH 14 'Charge the capacitor
PAUSE 2
RCTIME 14,1,WHEEL_IN 'Store wheel position data to WHEEL_IN
RETURN

GET_SPEED: 'Subroutine to acquire speed data
HIGH 15 'Charge the capacitor
PAUSE 2
RCTIME 15,1,SPEED_IN 'Store speed data to SPEED_IN
RETURN

REV_SERVO: 'Subroutine that reverses servo output
DO WHILE(IN13=1)
GOSUB GET_SPEED 'Go to GET_SPEED subroutine to store speed data
GOSUB GET_POS 'Go to GET_POS subroutine to store wheel position data
WHEEL_REV=2*CENTRE-WHEEL_IN 'Function inverts WHEEL_IN about CENTRE for WHEEL_REV
'-------
' DEBUG DEC WHEEL_REV, " ", DEC MAX_R, " ", DEC MAX_L, " ", DEC SPEED_IN, " ", DEC IN13, CR
'-------
IF(WHEEL_REV>MAX_R AND WHEEL_REV<MAX_L) THEN 'Keep signals between max L/R positions (~80° sweep)
IF(WHEEL_REV>(CENTRE+THR_CTR)) THEN 'Wheel left, lights right
HIGH 2 'Left LED on
LOW 3
PULSOUT 0,WHEEL_REV
PULSOUT 1,((WHEEL_REV-CENTRE)/MULT)+CENTRE 'Want less movement on outside light
ELSEIF(WHEEL_REV<(CENTRE-THR_CTR)) THEN 'Wheel right, lights left
LOW 2 'Right LED on
HIGH 3
PULSOUT 0,CENTRE-((CENTRE-WHEEL_REV)/MULT) 'Want less movement on outside light
PULSOUT 1,WHEEL_REV
ENDIF
ELSEIF(WHEEL_REV>MAX_L) THEN 'If wheel input signal goes beyond max left position
HIGH 2
LOW 3
PULSOUT 0,MAX_L
PULSOUT 1,((MAX_L-CENTRE)/MULT)+CENTRE
ELSEIF(WHEEL_REV<MAX_R) THEN 'If wheel input signal goes beyond max right position
LOW 2
HIGH 3
PULSOUT 0,MAX_R
PULSOUT 1,CENTRE-((CENTRE-MAX_R)/MULT)
ELSE 'Centre lights under all other conditions
HIGH 2
HIGH 3
PULSOUT 0, CENTRE
PULSOUT 1, CENTRE
ENDIF
LOOP
IF NOT(IN13=1) THEN 'Centre lights, then wait 5 s
HIGH 2 'Re-centers headlights while driver is shifting out of
HIGH 3 'reverse and gives time to start driving forwards
PULSOUT 0, CENTRE 'before main routine begins again
PULSOUT 1, CENTRE
PAUSE 5000
ENDIF
RETURN
J-Ro is offline   Reply With Quote