DIY Auto Headlights with keyless entry

BenjiHoggi

OEM+
:
Oregon, USA
:
22v Protege5
I've always liked the idea of adding smart convenience features to an older vehicle. As someone with a background in what boils down to electrical and computer engineering, it's not too challenging of a proposition, depending on the vehicle and desired functionality. And I just so happen to own an old car, so I figured I'd give this a shot😉

The enhancement in question is to add functionality to the keyless entry system so that the headlights turn on when the car is unlocked using the fob. When the car is unlocked (either with a single press to unlock the drivers door or a double press to unlock all doors, or both), the following conditions will be checked: battery voltage, outside light level, and whether doors are open. Based on these conditions, the headlights will be turned on for a certain amount of time. They will turn off either when they timeout (the car relocks), or the driver gets into the car.

As far as convenience features go, this one is pretty mid-tier. Top of my list would be to add auto-up-down window switches to my car, but that's not such a trivial task, so I'm starting simple.

I have yet to further flesh out my design for this, but I have a lot of details already figured out, and I'll add some of those with time.

This is not intended to be a DIY guide, but it could be used as that for more tech savvy folks depending on how successful the project is.
 
  • Like
Reactions: 323
This might get a little nerdy. Mostly documenting for future reference for myself and others.

Technical Details
  • I'm using an Arduino nano. Main reason for this is the convenience of the built in voltage regulator which supports an input of 7-12v per the Arduino spec sheet, but according to the component datasheet should take as much as 20v. So I can power this straight off any 12v line.
    • I highly considered an ESP32 (specifically the Wemos ESP32-S2 mini), as I could add wireless unlocking capabilities, and the ESP32 supports ultra low power modes. But, the ESP32 does not have a voltage regulator and thus would require a step down to 3.3v.
  • Light sensing will be done likely using a photoresistor, which I still need to buy. It will be externally connected and mounted somewhere on the dashboard.
  • Battery voltage measurement and detection of other signals from the keyless entry module can be done using the GPIO pins on the Arduino and some voltage dividers. Maybe not the safest approach but should be fine.
    • The battery voltage measurement could be harder the Arduino will probably struggle to get an accurate reference voltage if it's powered off of the same power source that it is attempting to measure. We'll see how that goes.

Relevant Datasheets:

Harness connector to keyless entry module. PCB also has pins labeled (yay!)
1725249336653.webp


Pin functions
1725249405648.webp

1725249418908.webp


(Above info was taken from FSM sections 9-14-10 through 9-14-13)


Interfacing with the vehicle

The FSM lists what is functionally a LOW voltage state as "Below 1.0", but I'm lazy and am just going to refer to that state as 0v here.
B+ state is I believe 12v, but not positive.

All keyless entry pins below which could be useful:
  • Pin A is an input which indicates when the key is in the On position
    • 0v is the nominal state
    • 12v (B+) is the signal state
  • Pin B is 12v power to the module
  • Pin C is an input which indicates if the doors are open
    • 0v is the nominal state
    • 12v is the signal state
  • Pin D is an input which indicates if the hatch is open
    • 0v is the nominal state
    • 12v is the signal state
  • Pins K and O are outputs which control the locks for the vehicle.
    • Pin K can be used to detect when unlock button is pressed twice.
      • 5v is the nominal state
      • Sequence is 5v->0v->5v
    • Pin O can be used to detect when the lock or unlock buttons are pressed twice.
      • 5v is the nominal state
      • Unlock button pressed sequence is 5v->0v->5v
      • Lock button pressed sequence is 5->2.5v->5v
  • Pin L is Ground to the module
Additional pins below could be useful but i don't have a plan for them right now. I may wire them to the Arduino anyways though just for easy future software control.
  • Pin E controls the horn
  • Pin H controls the hazards


Vehicle Interface plan
  • Power to the Arduino can be directly provided via Pins L and B.
  • Pins A, C, and D can be used to detect if doors are open or the key is in the ignition, which would allow the Arduino to be aware that someone has entered the vehicle after unlocking it. This would likely be used to turn off the headlights.
  • Pins K and O can be used to detect when the car is unlocked or locked.
  • I don't have control of the headlights figured out yet. I would guess that I could tap into the relay that controls them and provide a signal to it to trigger them to turn on. This could be a little tricky with the Arduino. A relay or mosfet would likely be needed.

Other ideas
  • I am planning to make some modifications to the keyless entry module to increase the wireless range. This would likely be done by extending the antenna, which is internal to the module which lives under the dashboard.
  • With a light sensor connected and control over the headlights, I could potentially add an auto daylight sensing feature to the headlights.
  • I may also make modifications to Pin E which controls the horn. I could intercept it and repurpose the panic button to something else. I could disconnect it altogether so the car doesn't beep when you double press the lock button or panic button, or more likely, I could reroute it to a more passive beeper so that the car beeps like newer Toyota's and other vehicles do when you unlock them (I always hated the loud honk on double pressing lock).
 
Hardware

Here's an Arduino nano if you haven't seen one.
1725251732641.webp


I dug around under the dash until I found the keyless entry module. Just one screw to remove it, and removing the plug obviously. Size comparison with the nano. More later on how I plan to package the Arduino.
1725251946454.webp


The module opens easily and the PCB can be removed.
1725251818959.webp


The pins are labeled according to the FSM (so convenient!)
The gold metal piece around the PCB is the antenna (I assume).
1725251870136.webp



Hardware packaging

Since there's some room inside the module's box, I think I may try to mount the Arduino inside and cut a hole in the top by the connector so it can be reprogrammed under the dash. We'll have to see how much room I have with all of the voltage dividers though.

I will also need to have external connections for the headlight control, light sensor, and potentially an external antenna.

Mounting inside the box has the perk of being able to connect directly to the board (specifically the internal connector pins) instead of having to tap the wires on the connector on the car's harness. This makes this mod mostly reversible with a new keyless entry module if I desired down the line. And, the module would be mostly plug and play for someone else to plug into their own car, and all they would need to do would be to reprogram their fobs to the new modules. Ehh, I'm getting ahead of myself with that 😁
 
Antenna modifications

I'm certainly not an antenna expert, and as I look more into how antennas work, I am reminded of that even more. I realize that modifying this antenna might not be the best idea, and there definitely could be more to the seemingly arbitrary way it's designed that I might not want to mess with.

The antenna appears to be connected in three places. Two spots seem to be mechanical with no electrical connections - the bottom left and top. The third spot on the bottom right seems to have a connection.

1725253594258.webp


This then, might not be a loop-style antenna, meaning I could possibly just remove the antenna and connect a long wire to the solder point on the bottom right of the back of the board.

I may try to find another module and key fob at a junkyard to play with so I don't jeopardize the functionality of mine.

This really makes me want to design my own fob + module with a PCB and radio communication from scratch and with a plug and play connector for the Protege. It's absolutely possible but would take a lot of work and wouldn't really be worth it. Does make me also wonder what other cars might use this same connector with the same functions but might have better fobs with better range, etc.
 
Progress!

I soldered some test points to the connector's solder pads on the back of the keyless entry module . These wires will probably get snipped to the right length later and directly soldered to the Arduino.

1725341268249.webp


I soldered on wires for just the pins I needed at the moment. This included the GND and +12v pins, which I hooked up to my bench supply so that I could run the module at my desk for testing.

Two sets of voltage dividers have been soldered to the Arduino
  • One set is for the 5v pins which honestly don't even need voltage dividers since the Arduino can handle 5v inputs, but I wanted to be safe, so using two 1K resistors for R1/R2.
  • One set it for the 12v pins. Using 2.2K for R1 and 1K for R2, which drops 12v down to around 4v which is safe for the Arduino's GPIO pins.
20240902_185033.webp
20240902_185039.webp


Found a photoresistor and soldered it up to a long USB cable for easy mounting on the dash. All hooked up to the Arduino and it reads 0-5 based on sensor readings. Seems like it'll work.

20240902_220842.webp


Here's everything hooked up.

20240902_220837.webp


So far, this is all working decently well. If it's not already obvious though, this is not the most safety-conscious way to do this (mostly for the keyless entry module), so maybe don't try this at home kids :)

I wrote some code on the Arduino to spit out all of the raw data so I could plot it and see how things worked. Here's what it looks like.

1725340898871.webp

  1. The top graph is the light sensor, which is working great.
  2. The middle graph is the two inputs to the module for if the doors or hatch are open. These show nothing because the module is not connected to the vehicle.
  3. The last graph shows the two output pins that the module uses to signal the doors to lock. I can see blips in each line, but oddly, they seem to be linked together for some reason and both blip as many times as the buttons are pressed. Will need to dig into this more, as it's usable but not what I'd expect to see based on the FSM.
This is good progress so far. I still have no idea how to interface with the headlights, and I'm not exactly sure how I'm going to mount the Arduino, now that it's covered in resistors.

I also stumbled across this thread somehow, which gave me some more to think about when it comes to adding extra functionality.
 
Slow progress...

Progress has been slow but I haven't given up!

After I made the last post, I quickly realized that my graph was incorrectly labeled...not that it matters much. The data was taken without the module plugged into the car and I was getting some really weird measurements that didn't make tons of sense.

With the module actually plugged into the car, the measurements looked much more correct and the level of noise is very very low compared to what it was before.

1726902101803.webp


I originally thought that the hard part would be manipulating the headlights to turn on, as compared to detecting unlock signals from the keyless entry module. This turns out to have been backwards. While I thought my hijacking of the keyless entry module using voltage dividers would work perfectly, it turns out that for some reason, when I plugged the module into the car, it immediately triggered all of the doors to lock. And upon unlocking them with the fob, they would immediately re-lock. Locked my main set of keys in the car because of this and had to get the backup key on standby.

After disconnecting the voltage dividers and Arduino from the module, the keyless entry system works fine, so It's not like I damaged something. But I'm going to have to figure out what's happening here and how to resolve it. I have a theory that my voltage dividers might be pulling down the voltage outputs enough that it messes with the module. So I am going to play around with some different resistor values for the dividers.

Headlight Control
The hard part that turned out to be easy!

I started by looking at the diagram in the FSM for the headlights thinking I could trigger the relay to flip and turn the headlights on (and ideally the parking lights too somehow). What I found was a non-trivial diagram of the relays which made me immediately nope outta that. I then went looking at the headlight stalk - something I've investigated before in relation to my upgraded foglights.

Here's the FSM diagram I was looking at for the headlights. It can be found in section 09-18-13 (BODY)
1726902847224.webp


I took the steering column trim panels off and unplugged the headlight stalk connector, hoping I could probe around and get something to work. I was still confused at the diagram so I decided to do the safest thing and just start jumping pins together with a jumper (sarcasm here, I was making an educated guess). To my delight, I found a combination that worked to turn on the headlights!

As I probed, I also found a pin which will turn the parking lights on (though this will be a little quirky...more on this later). After probing for a bit, what I found is that the pin marked P is just a ground, and the other pins are logical high pins, sitting at 12v. By shorting those pins to ground (P), the headlights and other things turn on.

There seems to be a combination of things shorted to P that create the functionality we see with the stalk, but I found that jumping P to either (don't quote me on this, need to double check) O or L would turn the headlights on. I don't recall what the pin was for the parking lights but I'll get that in here shortly.

Out of curiosity, I jumped the pins with the meter to see what kind of current I was dealing with and it looks like it's only about 120mA for the headlights. That's a little high but doable.

Arduino Headlight Control
Now I needed to find a way to essentially "short" either the O or L pin to any GND to trigger the headlights to turn on. This took me a good while to figure out. The simple option would have been a relay, but I refused to deal with that. So I rigged something up with a mosfet (two, one for headlights and one for parking lights). Now this is where things get a little muddy. I have the wiring for the mosfets and they do work with the Arduino but it was a process to get the right resistor values and to get everything working.

Testing together
With all the essential components in, I figured I would do a test run to see if I could technically make the headlights turn on with the key fob, even though the module would immediately trigger a re-lock after unlocking every time. I wrote some sloppy code to detect a voltage change from the module on one of the unlock signal lines, and had it switch on the mosfet controling the headlights (and in turn, the parking lights). Annnnnd it worked! I don't have proof but I was able to turn the headlights on with the fob. So that's progress that I am very happy about.

Quirks
Now onto the quirks...this thing is so far from done. This was just the first itteration.

  • The elephant in the room is the module re-locking after any locking operation with the fob. Obviously a no go until this is resolved.
  • The quirkiness I mentioned before with the parking lights is not a deal breaker but a little annoying. I wanted to have headlights and parking lights come on during unlock. Headlights are on their own pin, but the pin that controls parking lights also controls the gauge cluster backlighting (fine) but has the effect that when the doors are open, the headlight on buzzer turns on...annoying!
    • The solutions for this as I see it are: Don't trigger the parking lights (fine), only trigger the parking lights until a door is open then detect that and immediately turn them off, leaving headlights on (ehh), or disable the headlight buzzer (ehh). Leaning towards the first option but still TBD.
  • The hardware on the module is SERIOUSLY JENKY. Don't have pictures right now but the Arduino is zip tied to the side and soldered to a bunch of the wires. It's gross. But it's a prototype for now and it'll get better later.
  • I have yet to test idle power draw. I don't want this thing killing my battery so we'll need to address that probably.

Anyways, going to keep working on this and get it wrapped up so I don't have to keep using my key 😝
 
It works!

This is a lame update but I did get the system working...mostly. I'll add more later.

I was able to fix the immediate relocking issue by changing the values of the voltage divider resistors I was using to 10k and 20k instead of 1k and 2.2k. The logic behind this is that the higher resistances means lower current draw but higher levels of noise for the Arduino. I did see higher levels of noise but nothing I felt was an issue.

The hardware is still jenky, but better (and I think fine for me for now). The arduino is still hanging outside the module box but the two mosfets and the 8 resistors for the voltage dividers are stuffed inside the module box, so the whole package is still fragile but temporarily fine for under the dash.

Two other weird things with the hardware. Firstly, for whatever reason, my light sensor setup stopped reading correctly. I just took it off for now and the car will just assume it's night all the time until I fix the light sensor. Secondly, I don't know if my hatch open sensor is just broken (the light doesn't work) or something else is off, but I don't get a signal when the hatch is open. So I am ditching that for now and I decided instead to use that pin to monitor the ignition (more on this later).

Current Functionality

Having finished the hardware (mostly) I was eager to try some software (or technically firmware) to get things running, which wasn't going to be too hard but would be a lot of signal processing.

I'll include my actual code here at some point soon, but essentially, I ended up with three classes for a timer, signal processing, and for controlling the lights. With these interfaces in place for the hardware, it was a simple set of if-statements to catch each case. Here's how it works right now:
  1. A single unlock turns on the parking lights only (for unlocking drivers door)
  2. A double press unlock turns on parking and headlights (for unlocking all doors)
  3. Opening the car door will immediately turn off the parking lights (to avoid annoying buzzer) but headlights stay on.
  4. If a door is opened, headlights will stay on until either the car is locked from the fob, the ignition is turned on, or a 60-second timer expires.
  5. If a door is not opened, the car will automatically re-lock itself after 30 seconds which turns off the headlights (this is built in behavior).
This is rudimentary so far but I will continue to iterate with time as I use the car and find quirks.

Quirks/Future improvements
  • Possibly other changes in functionality depending on how I like it now
  • Power draw is still completely unknown
  • Need more safety features in software to prevent accidentally draining the battery
  • Need to re-add light sensing
  • Proper hardware enclosure
  • Antenna modifications?
 
  • Power draw is still completely unknown

You can test for parasitic power drain by disconnecting the ground from your battery and hooking up an ammeter across the disconnect.
If the ammeter is connected before disconnecting the battery, you won't break the circuit and upset any circuits.

You can also pull fuses and measure the current across the fuse connector.

Keep in mind that most multimeters/ammeters only read up to ten amps, so you'll have to stay below that limit.

IIRC, I had 18ma of parasitic power drain that's used to keep the stereo presets, and the ECU data.

You'll get closer to 2 amps if you forgot to shut off the light in the trunk. 😂
I removed the bulb to prevent such accidents. 😂
 
Last edited:
You can test for parasitic power drain by disconnecting the ground from your battery and hooking up an ammeter across the disconnect.
If the ammeter is connected before disconnecting the battery, you won't break the circuit and upset any circuits.

You can also pull fuses and measure the current across the fuse connector.

Keep in mind that most multimeters/ammeters only read up to ten amps, so you'll have to stay below that limit.

IIRC, I had 18ma of parasitic power drain that's used to keep the stereo presets, and the ECU data.

You'll get closer to 2 amps if you forgot to shut off the light in the trunk. 😂
I removed the bulb to prevent such accidents. 😂
This is smart. I've done it before but didn't think to do it here. Might give it a try soon. My trunk light doesn't work so I'm going to have to check on that too at some point.
 
Alright so it's been over a week with the hardware installed. The key takeaway is that it works but is quirky. Below are some of the things I noticed that can be fixed, and some that are outright weird.
  • Unlocking the car from the interior unlock button on the door is the equivalent to pressing the unlock button twice - it turns the parking and headlights on.
  • The detection of a single unlock is sometimes flaky...it will turn the parking lights on then right back off. I think this comes down to a timing issue.
  • Twice I think, the system just stopped working. Both times a reset using the Arduino's reset button fixed it.
  • One real weird thing. I got into the car and the ignition was already on. The key was still in my hand. When I put it in to start the car, it started fine. When I turned the key and took it out, the car kept running. I immediately unplugged the keyless entry module and it continued to run. I could have started driving the car right there without the keys. I fiddled with everything and eventually disconnected all of it and then plugged it back in the next day and it's been fine since. I don't know how this happened, as I am only monitoring the ignition signal, not controlling it. As it felt very much like a safety issue, I was very watchful of it happening again, knowing that I would need to make changes if it did. But I have not seen it happen again.
  • One other thing I noticed was how bad the fob wireless range is. It was already bad but feels like it got worse.

Improvements

Having seen some areas over the past week where functionality could be fixed or improved, I spent some time last night trying to improve the system.

Light Sensor
I fixed and re-added the light sensor. I don't know what was wrong in the first place with it but it is reading fine now. I added some software catches where the lights won't turn on when it's light out. I set a fairly arbitrary threshold value for "darkness" which might need to be adjusted a bit.

Software
I added a 10-second timeout on the lights when locking the car or the ignition is on.
  • For the condition of getting out and locking: When you unlock the doors, the lights will turn on (for 60 seconds unless locked). When you lock from the fob, they'll stay on for 10 seconds before turning off (as you walk away).
  • For the condition of the ignition being on: As long as it's on, the lights will stay on. This essentially adds DRL functionality, which I'm not sure I want to keep, as I do have a headlight switch and I always use my headlights in the daytime anyways.
  • Also, the above functionality only works when it's dark, so this is more of an auto headlights in the dark kind of thing anyways. Still TBD on all of this.
  • I made some other small software tweaks that I don't remember
More Range!
Added an external antenna! I was waffling about how to do this properly but just decided to solder a long length of insulated single-core copper wire to the solder point on the PCB. Results below.

More permanent install
I ran both the antenna wire and light sensor up through the dashboard on the drivers side. Sadly the Arduino is still hanging out with it's mess of wires 🥴

I bunched up all the extra wire for the light sensor behind that removable panel on the side of the dashboard, and stuffed the light sensor into a crack between the drivers A-pillar and the dashboard so that it can sense daylight through the windshield. We'll see if it stays.

As for the antenna, I pulled the A-pillar trim and ran the antenna up that and tucked the end into the headliner. The difference is crazy! The previous distance was probably 10-20ft, but now I can go 50-60ft easily. I haven't tested this too much but will test more and maybe show some photos or make a how-to guide for this specifically, as it wouldn't be too hard for anyone to do and this is honestly a worth while mod in itself.


Further Improvements

There are still some things that need improvement for the future:
  • The 10-second timer on the headlights when the car gets locked applies everywhere. This makes sense for locking from the fob, but not for when the car re-locks after no doors were opened. I can add a catch for this case by keeping track of if the doors have been opened. If they haven't, just turn off the lights immediately.
  • Still TBD on whether I like it that the ignition turns the headlights on. We'll see.
  • Might need to mount light sensor a little better and adjust it's threshold for detecting darkness.
  • Still would like to measure power draw. Now I know how to though, thanks pcb.
  • Document things better. I am hoping to take some photos and possibly videos to post here, I'd like to post the code, and I'd also like to make a schematic of the wiring so that someone else could reproduce this, albeit with some work required.
 
Last edited:
I was able to fix the immediate relocking issue by changing the values of the voltage divider resistors I was using to 10k and 20k instead of 1k and 2.2k. The logic behind this is that the higher resistances means lower current draw but higher levels of noise for the Arduino. I did see higher levels of noise but nothing I felt was an issue.
A better option may be to use a 1-2K resistor in series with a suitable zener diode (5V or 3V depending on the ATmega voltage on the Arduino). Take the input from the mid-point of these and it won't load the car circuitry, but will provide a nice (noise-free) logic voltage to the Arduino.
 
A better option may be to use a 1-2K resistor in series with a suitable zener diode (5V or 3V depending on the ATmega voltage on the Arduino). Take the input from the mid-point of these and it won't load the car circuitry, but will provide a nice (noise-free) logic voltage to the Arduino.
This is a good suggestion and one I briefly stumbled across in my research, but I was hoping to do this with parts I had readily on hand, and I don't think I had the right diode. I may check again to see if I have any and if not, get some on order. I suspect that the weird issues I was seeing were possibly related to the fact that I am slightly pulling down the signals I'm listening to.
Thanks for the suggestion!
 
Back