Note: This post was published 4 Feb 2024, but was based off of research and work completed back in May 2023.
Back in 2020, I removed the analog instrument cluster from my 2015 Mustang GT Premium to upgrade it to a 2018 Digital Cluster (see here for more info on that: 2018+ Mustang Technology Retrofit – { Eric’s Blog } (ericturner.it)). I kept the old cluster laying around, no idea what I wanted to do with it.
Fast forward to 2023, I had just recently purchased a 2016 Mustang GT350. I used a usb to OBD reader and performed some CANbus data logging while I interacted with buttons in the car multiple times in a row (turn signals, brights, arrow keys on the steering wheel, opening the doors). Then went for a short drive while data logging.
I had a subscription to Ford’s Service Manual & Wiring Diagrams from awhile back so I already had the pin out to the connector on the back of the cluster
With the data saved to files, and the cluster hooked up and ready for interface with my computer, I wrote some python code so I could replay my saved files in real time and monitor the console output whenever I saw lights or messages appear on the cluster. Through hours of brute-force trial and error, I was able to get a lot of information to be able to reproduce. Here was an example of how just one message ID can display a bunch of different information just from a few byte changes:
I could then hook up python code with some IF statements to map exactly what bytes would be sent for different lights or messages. Example excerpt below from the main s550_cluster.py file.
def send_misc_2(clusterdata):
'''
ABS, Traction Control Off, Traction Control Loss Icons, Airbag
Byte 1 -
0x2_ - Check Brake System warning
0x4_ - AdvanceTrac System Warning
Byte 5 has to do with a solid traction control or a flashing icon
0x00 - Off
0x02 - Solid
0x0F - Flashing
Byte 6 -
0x0_ - ABS light off
0x4_ - ABS Solid
0x8_ - ABS Flash Slow
0xD_ - ABS Flash Fast
'''
if(clusterdata.icon_traction_control == 2):
traction_control = 0x0F # flashing
elif(clusterdata.icon_traction_control == 1):
traction_control = 0x02 # solid on
else:
traction_control = 0x00 # off
if(clusterdata.icon_abs == 2):
abs_icon = 0xD0 # flashing
elif(clusterdata.icon_abs == 1):
abs_icon = 0x40 # solid on
else:
abs_icon = 0x00 # off
data = [00, 00, 00, 00, 00, traction_control, abs_icon, 00]
return send_msg(MISC_2, start, data)
What Works
All of the below indicators can be modified by game data, such as telemetry out from Euro Truck Simulator 2 or Forza Horizon 5 and re-mapped into the cluster for display
- Turn Signal Indicator
- High Beam / Headlight Indicator
- Seatbelt Indicator / Chime
- Airbag Indicator
- Parking Brake Indicator
- ABS Indicator
- Traction Control Indicator
- Hill Start Assist Warning Message (Suppressed)
- Launch Control Indicator
- Door Ajar Indicator / Warning
- Speedometer
- RPM
- Engine Temp / Overheat Warning
- Cluster Navigation (Arrow Keys + Enter key to interact with the on screen display)
Future Enhancements
At the time of writing in Feb 2024, I no longer have a mustang so data logging to find further functionality is not available to me. Things I would love to have work though:
- Check Engine Indicator
- Control Fuel Gauge (would require use of pins 9 & 10 on cluster)
- TPMS Indicator
- Fix the plethora of warnings when the cluster boots up
- Blind Spot Assist Not available
- Low Engine Oil pressure
- Steering Assist Fault Service Required
- Cross Traffic System Fault
- Fuel Level Low
- See Manual
- Door Ajar
- Tire Pressure Monitor Fault
- Gauges
- Air/Fuel Ratio
- Boost/Vaccuum
- Oil Pressure
- Inlet Air Temp
- Miles to E
- Odometer
If any one else has a mustang and can perform data-logging or reverse engineering, feel free to make pull requests to my github with more functionality!