• Required reading for all forum users!!!

    Welcome!
    Register to access the full functionality of the GSResources forum. Until you register and activate your account you will not have full forum access, nor will you be able to post or reply to messages.

    A note to new registrants...
    All new forum registrations must be activated via email before you have full access to the forum.

    A Special Note about Email accounts!
    DO NOT SIGN UP USING hotmail, outlook, gmx, sbcglobal, att, bellsouth or email.com. They delete our forum signup emails.

    A note to old forum members...
    I receive numerous requests from people who can no longer log in because their accounts were deleted. As mentioned in the forum FAQ, user accounts are deleted if you haven't logged in for the past 6 months. If you can't log in, then create a new forum account. If you don't get an error message, then check your email account for an activation message. If you get a message stating that the email address is already in use, then your account still exists so follow the instructions in the forum FAQ for resetting your password.

    Have you forgotten your password or have a new email address? Then read the forum FAQ for details on how to reset it.

    Any email requests for "can't log in anymore" problems or "lost my password" problems will be deleted. Read the forum FAQ and follow the instructions there - that's what we have one for...

  • Returning Visitors

    If you are a returning visitor who never received your confirmation email, then odds are your email provider is blockinig emails from our server. The only thing that can be done to get around this is you will have to try creating another forum account using an email address from another domain.

    If you are a returning visitor to the forum and can't log in using your old forum name and password but used to be able to then chances are your account is deleted. Purges of the databases are done regularly. You will have to create a new forum account and you should be all set.

Headlight Modulator Question

  • Thread starter Thread starter bakalorz
  • Start date Start date
Vote early and vote often ... \\:D/
If you are going to offer a choice, with one of them as the default, use 50% as the default.
The "blinking" effect will be more pronounced, and that is what you are looking for. :shock:



.
 
Vote early and vote often ... \\:D/
If you are going to offer a choice, with one of them as the default, use 50% as the default.
The "blinking" effect will be more pronounced, and that is what you are looking for. :shock:

.
 
Ya gotta really fool this board to vote that often. :shock:

First, it won't let you post more often than once every 30 seconds.

Then, it doesn't like it if the post is a duplicate of one that was posted within the last five minutes.

So, you have to add a space here or there to do this kind of evil stuff. 8-[ :-\"


.
 
Well, I got the regulator in the bike and running this weekend.

So here's the schematic and program for the modulator.
Its pretty simple...

a MINUS Five Volt voltage regulator and 3 caps for it.
a PIC 12F683 microcontroller
a CDs Photodetector
a few P-channel Mosfets
3 resistors
an optional diode to protect against reversed connections

A couple of notes:

The Modulator can be completely bypassed by connecting the two terminals marked BYPASS. You could connect them with a switch to turn it off or in case it fails. I didn't bother on mine.

The low beam wire is shown in the schematic. It is not used as part of the modulator. But if you wire yours in in between the socket and the bulb, you will need to make a wire for the low beam connection though.

D1 is only used to protect against reversing the input connections for +
and -
If you know you'll never do this, you can omit it... :)
It is shown as a power diode, but the only power it needs to pass is the
power to the PIC (negligible), the gate drive (negligible), and whatever
the regulator wastes. So any current rating is enough.
Also, the bike-ground wire going to the modulator can be very light wire, since it carries almost no current
The 1k resistor provides gate drive to the FETs.
The 47k resistor provides a weak pull down to drive the fets on
while the PIC is booting up. (and if it ever locks with the output
Tri-stated to high impedance)
Otherwise, there would be a 1/4 sec or so turn on delay when you turned
the high beams on. While this wouldn't be too noticable if the PIC
started modulating, it would kind of suck when you turn the high beams on
at night ... :)
As soon as the PIC starts up (assuming the light sensor sees light), the
PIC will override the 47k resistor.

The Nanny-State government says the modulator is supposed to work on the positive side and not the ground lead ... That means we can't use
N-channel FETs unless we use a special funky driver that will raise the
gates above the positive rail. I'd rather avoid that extra complexity,
so we'll use P-channel FETs. The number of Fets required depends on
their current carrying capacity compared to the headlight current. I
drew three, but mine were about 7 amps each, so I built it with just 2
in the end for a factor of safety of about two and a half. Just parallel
as many as you want/need.

To drive them, it's easiest if the PIC voltage will go all the way to
the positive rail (which acts as the ground for P type FETs) So we use a
NEGATIVE regulator, which provides a regulated voltage 5 volts below the
12 volt rail (instead of a positive regulator which rovides a regulated
voltage 5 volts above the ground rail) So the regulator section looks a
little strange, with "ground" being +12 volts ...

Also, since the P-FETs are on when the gate voltage is negative, the PWM
output is "active low".

The Photodetector and its resistor form a voltage divider. This is read
by the A/D converter in the PIC. To make it easy, I just read the first
bit ... That bit changes when the resisance of the Photodetector is
equal to the resistor ... slick and easy ... So pick a photodetector
that has a resistance of 10k at your desired level of darkness. The one
I show in the parts list is 10k at 10 to 15 minutes after sundown.

Internal weak pull-ups are enabled on pins 2,6, and 7. These let you
provide input to the PIC by either leaving them open or shorting them to
the Vss terminal. (the PICs local ground ... not to be confused with
the bikes ground)

The government says the "full brightness" time should be 50 to 70
percent of the total. I wanted to try both, and see what worked better.
If pin 2 of the pic is high, the duty cycle is 50%; If pin 2 is low, the
duty cycle is 67%. Internal weak pullups are enabled on pin 2, so if it
is unconnected it will be high. To pull it low, short it to Vss via a
jumper or Solder-bridge. Alternatively, if you connect pin 2 to Vss via
a switch you can vary the duty cycle by flipping the switch.

Pins 6 and 7 can be used to change the flash rate.
If neither pin 6 nor 7 is connected, the default rate is 240 flashes/min
connect pin 6 to Vss to change the rate to 202 flashes/min
connect pin 7 to Vss to change the rate to 278 flashes/min
(if both are connected, the rate will be 202)
If you connect Vss to the center, and pins 6 and 7 to the outside of a
SPDT-center-off switch, you will have a switch that provides all three
speeds in order.

Pin 4 (mclr) should be connected to Vss or Vdd after programming. It
doesn't matter which, it just shouldn't float.

Otherwise, pins 4, 6, and 7 are not connected, however, they are brought
out to pieces of wire which are used for initially programming the PIC.
Pin 1 and pin 8 are also used in programming, so there are wires brought
out for them too. These wires can be clipped after the pic is
programmed.

Also, PIN 8 (Vss) is eventually connected to the regulator, but during
programming it should not be connected to the regulator. The programmer
will supply power to Vdd and Vss, which would damage the regulator if
the regulator were connected at that time. So pin 8 is connected to the
rest of the board via an intentional solder bridge which is formed after
programming is complete. If you ever need to reprogram the PIC, make
sure to temporarily melt that bridge.
 
Bleah, it looks like the forum butchered the formating ...
hopefully not so badly that it doesn't load into the pic



;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: Martin Bakalorz *
; Company: *
; *
; *
;**********************************************************************
; *
; Files required: p12F683.inc *
; *
; *
; *
;**********************************************************************
; *
; Notes: *
; *
; *
; *
; *
;**********************************************************************
list p=12F683 ; list directive to define processor
#include <p12F683.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.


;***** VARIABLE DEFINITIONS
INNERDELAY EQU 0x73
MIDDLEDELAY EQU 0x74
OUTERDELAY EQU 0x75

;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program


main
; ***** initialize Stuff *****
BCF STATUS,RP0 ;Bank 0
MOVLW 07h ;Set GP<2:0> to
MOVWF CMCON0 ;digital I/O
movlw b'00000000' ; load w with 0000 0000
movwf GPIO ; set GPIO (except maybe pin 2-determine later) --- sets voltage of pins if outputs --- 0 = low voltage
; *** NOTE *** assuming active low on PWM drivers
BSF STATUS,RP0 ;Bank 1
movlw b'00011000' ; load w with 0101 1000
movwf ANSEL ; SET AN/DIGITAL to digital I/O except pin an3, and also set Tad to Tosc/8
movlw b'00111011' ; load w with 0011 1011
movwf TRISIO ; configure GPIO as all inputs except GP-2 (PWM-output)
movlw b'00100011' ; load w with 0010 0011
movwf WPU ; Turn on weak pullups on pins 2,6,7
movlw b'01111111' ; load w with 0111 1111
movwf OPTION_REG ; enable weak pullups (globally)
BCF STATUS,RP0 ;Bank 0
; Prepare A/D converter for use
movlw b'00001101' ; load w
movwf ADCON0 ; configure adcon (left, Vdd, an3, A/D on)
; ***** setup PWM stuff *****
; setup period
BSF STATUS,RP0 ;Bank 1
MOVLW b'11111110' ; ; setup W register
MOVWF PR2 ; setup period

;Setup Initial Duty Cycle
BCF STATUS,RP0 ;Bank 0
MOVLW 0x00 ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
BCF CCP1CON,4 ;set lowest bit
BCF CCP1CON,5 ;set 2nd lowest bit
MOVLW b'00000101' ; setup W register
MOVWF T2CON ; set timer2: postscale=1, prescale=4, on

MOVLW B'00001100' ; prime W
MOVWF CCP1CON ;enable PWM (start the PWM)
; ***** Begin Looping part of Program ******************************
restart
; 1st period (High duty cycle)
BCF STATUS,RP0 ;Bank 0
MOVLW 0x00 ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
BCF CCP1CON,4 ;set lowest bit
BCF CCP1CON,5 ;set 2nd lowest bit
call Delay ; go to Delay subroutine 1st time
;-----------------------------------------------------------

; 2nd period (still High duty cycle) - call A/D let it run during cycle
BCF STATUS,RP0 ;Bank 0
BSF ADCON0,GO ; Run an A/D conversion
call Delay ; go to Delay subroutine 2nd time
;-----------------------------------------------------------

; 3rd period (still High duty cycle)
call Delay ; go to Delay subroutine 3rd time
;-----------------------------------------------------------

; 4th period ... variable high percentage, Read A/D and percentage I/O, then low or high depending on light level and duty cycle setting
BTFSC ADRESH,7 ;read highest bit of A/D
goto dutyhigh1
; BTFSC GPIO,5 ;read pin 5 of gpio (high/low on time) skip if clear pick one of these two depending on the default duty cycle desired
BTFSS GPIO,5 ;read pin 5 of gpio (high/low on time) skip if set pick one of these two depending on the default duty cycle desired
goto dutyhigh1

; this is the low one (ie modulated)
dutylow1 ; gets here if A/D < 2.5v (light) AND low on-time
BCF STATUS,RP0 ; Bank 0
MOVLW b'11010001' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
goto done1
; this is the high one (ie NOT modulated)
dutyhigh1 ; gets here if A/D > 2.5v (dark) OR high on-time
BCF STATUS,RP0 ; Bank 0
MOVLW b'00000000' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits

done1
call Delay ; go to Delay subroutine 4th time
;-----------------------------------------------------------


; 5th period ... Read A/D, then low or high depending on light level
BTFSC ADRESH,7 ;read highest bit of A/D
goto dutyhigh2

; this is the low one (ie modulated)
dutylow2 ; gets here if A/D < 2.5v (light)
BCF STATUS,RP0 ; Bank 0
MOVLW b'11010001' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
goto done2
; this is the high one (ie NOT modulated)
dutyhigh2 ; gets here if A/D > 2.5v (dark)
BCF STATUS,RP0 ; Bank 0
MOVLW b'00000000' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits

done2
call Delay ; go to Delay subroutine 5th time
;-----------------------------------------------------------

; 6th period ... same intensity as 5th
call Delay ; go to Delay subroutine 6th time
;-----------------------------------------------------------


goto restart ; back to the infinite loop


; ************************************************************************************
; ************************************************************************************
; ************************************************************************************


Delay
movlw 0x01
; movlw 0x04 ; FOR TESTING sets (0xA1) period to 1 sec
movwf OUTERDELAY ; set outer delay loop
DelayOuter

; 0x8B --> 278/min
; 0xA1 --> 240/min
; 0xBF --> 202/min
BCF STATUS,RP0 ;Bank 0
movlw 0xA1
; movlw 0x55 ;FOR TESTING
movwf MIDDLEDELAY ; set middle delay loop
movlw 0x8B
; movlw 0x1C ;FOR TESTING
BTFSS GPIO,0 ;read pin 7 (GPIO 0) (high/low on time) skip if SET
movwf MIDDLEDELAY ; shorten middle delay loop if pin 7 grounded
movlw 0xBF
; movlw 0xFF ;FOR TESTING
BTFSS GPIO,1 ;read pin 6 (GPIO 1) (high/low on time) skip if SET
movwf MIDDLEDELAY ; LENGTHEN middle delay loop if pin 6 grounded
DelayMiddle
movlw 0x55
movwf INNERDELAY ; set inner delay loop
DelayInner
decfsz INNERDELAY,F
goto DelayInner
decfsz MIDDLEDELAY,F
goto DelayMiddle

decfsz OUTERDELAY,F
goto DelayOuter
return

; initialize eeprom locations
ORG 0x2100
DE 0x00, 0x01, 0x02, 0x03

END ; directive 'end of program'
 
Well, I went riding for a second week with the modulator.

One thing I noticed last week, was that when the light was modulating, the headlight never quite made it up to full brightness.
This is not the fault of the modulator, but just a charachteristic of the bulb.
All bulbs take a fraction of a second to come up to full output, and a fraction of a second to decay as well.

So this week I connected the wires that make the duty cycle 67% instead of 50%
That gave enough extra time for the bulb to come up to full brightness.

So I am attaching an edited version of the program that defaults to 67% full brightness vice 50%. (50% is still available as an option by shorting the duty cycle wire to Vss)

The change is done by REMing one line with a semicolon, and unREMing the one above it .




;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: Martin Bakalorz *
; Company: *
; *
; *
;**********************************************************************
; *
; Files required: p12F683.inc *
; *
; *
; *
;**********************************************************************
; *
; Notes: *
; *
; * revised to change default duty cycle to 67%
; *
; *
;**********************************************************************
list p=12F683 ; list directive to define processor
#include <p12F683.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.


;***** VARIABLE DEFINITIONS
INNERDELAY EQU 0x73
MIDDLEDELAY EQU 0x74
OUTERDELAY EQU 0x75

;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program


main
; ***** initialize Stuff *****
BCF STATUS,RP0 ;Bank 0
MOVLW 07h ;Set GP<2:0> to
MOVWF CMCON0 ;digital I/O
movlw b'00000000' ; load w with 0000 0000
movwf GPIO ; set GPIO (except maybe pin 2-determine later) --- sets voltage of pins if outputs --- 0 = low voltage
; *** NOTE *** assuming active low on PWM drivers
BSF STATUS,RP0 ;Bank 1
movlw b'00011000' ; load w with 0101 1000
movwf ANSEL ; SET AN/DIGITAL to digital I/O except pin an3, and also set Tad to Tosc/8
movlw b'00111011' ; load w with 0011 1011
movwf TRISIO ; configure GPIO as all inputs except GP-2 (PWM-output)
movlw b'00100011' ; load w with 0010 0011
movwf WPU ; Turn on weak pullups on pins 2,6,7
movlw b'01111111' ; load w with 0111 1111
movwf OPTION_REG ; enable weak pullups (globally)
BCF STATUS,RP0 ;Bank 0
; Prepare A/D converter for use
movlw b'00001101' ; load w
movwf ADCON0 ; configure adcon (left, Vdd, an3, A/D on)
; ***** setup PWM stuff *****
; setup period
BSF STATUS,RP0 ;Bank 1
MOVLW b'11111110' ; ; setup W register
MOVWF PR2 ; setup period

;Setup Initial Duty Cycle
BCF STATUS,RP0 ;Bank 0
MOVLW 0x00 ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
BCF CCP1CON,4 ;set lowest bit
BCF CCP1CON,5 ;set 2nd lowest bit
MOVLW b'00000101' ; setup W register
MOVWF T2CON ; set timer2: postscale=1, prescale=4, on

MOVLW B'00001100' ; prime W
MOVWF CCP1CON ;enable PWM (start the PWM)
; ***** Begin Looping part of Program ******************************
restart
; 1st period (High duty cycle)
BCF STATUS,RP0 ;Bank 0
MOVLW 0x00 ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
BCF CCP1CON,4 ;set lowest bit
BCF CCP1CON,5 ;set 2nd lowest bit
call Delay ; go to Delay subroutine 1st time
;-----------------------------------------------------------

; 2nd period (still High duty cycle) - call A/D let it run during cycle
BCF STATUS,RP0 ;Bank 0
BSF ADCON0,GO ; Run an A/D conversion
call Delay ; go to Delay subroutine 2nd time
;-----------------------------------------------------------

; 3rd period (still High duty cycle)
call Delay ; go to Delay subroutine 3rd time
;-----------------------------------------------------------

; 4th period ... variable high percentage, Read A/D and percentage I/O, then low or high depending on light level and duty cycle setting
BTFSC ADRESH,7 ;read highest bit of A/D
goto dutyhigh1
BTFSC GPIO,5 ;read pin 5 of gpio (high/low on time) skip if clear pick one of these two depending on the default duty cycle desired
; BTFSS GPIO,5 ;read pin 5 of gpio (high/low on time) skip if set pick one of these two depending on the default duty cycle desired
goto dutyhigh1

; this is the low one (ie modulated)
dutylow1 ; gets here if A/D < 2.5v (light) AND low on-time
BCF STATUS,RP0 ; Bank 0
MOVLW b'11010001' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
goto done1
; this is the high one (ie NOT modulated)
dutyhigh1 ; gets here if A/D > 2.5v (dark) OR high on-time
BCF STATUS,RP0 ; Bank 0
MOVLW b'00000000' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits

done1
call Delay ; go to Delay subroutine 4th time
;-----------------------------------------------------------


; 5th period ... Read A/D, then low or high depending on light level
BTFSC ADRESH,7 ;read highest bit of A/D
goto dutyhigh2

; this is the low one (ie modulated)
dutylow2 ; gets here if A/D < 2.5v (light)
BCF STATUS,RP0 ; Bank 0
MOVLW b'11010001' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits
goto done2
; this is the high one (ie NOT modulated)
dutyhigh2 ; gets here if A/D > 2.5v (dark)
BCF STATUS,RP0 ; Bank 0
MOVLW b'00000000' ; setup W register
MOVWF CCPR1L ; set Duty cycle top 8 bits

done2
call Delay ; go to Delay subroutine 5th time
;-----------------------------------------------------------

; 6th period ... same intensity as 5th
call Delay ; go to Delay subroutine 6th time
;-----------------------------------------------------------


goto restart ; back to the infinite loop


; ************************************************************************************
; ************************************************************************************
; ************************************************************************************


Delay
movlw 0x01
; movlw 0x04 ; FOR TESTING sets (0xA1) period to 1 sec
movwf OUTERDELAY ; set outer delay loop
DelayOuter

; 0x8B --> 278/min
; 0xA1 --> 240/min
; 0xBF --> 202/min
BCF STATUS,RP0 ;Bank 0
movlw 0xA1
; movlw 0x55 ;FOR TESTING
movwf MIDDLEDELAY ; set middle delay loop
movlw 0x8B
; movlw 0x1C ;FOR TESTING
BTFSS GPIO,0 ;read pin 7 (GPIO 0) (high/low on time) skip if SET
movwf MIDDLEDELAY ; shorten middle delay loop if pin 7 grounded
movlw 0xBF
; movlw 0xFF ;FOR TESTING
BTFSS GPIO,1 ;read pin 6 (GPIO 1) (high/low on time) skip if SET
movwf MIDDLEDELAY ; LENGTHEN middle delay loop if pin 6 grounded
DelayMiddle
movlw 0x55
movwf INNERDELAY ; set inner delay loop
DelayInner
decfsz INNERDELAY,F
goto DelayInner
decfsz MIDDLEDELAY,F
goto DelayMiddle

decfsz OUTERDELAY,F
goto DelayOuter
return

; initialize eeprom locations
ORG 0x2100
DE 0x00, 0x01, 0x02, 0x03

END ; directive 'end of program'




-
 
Back
Top