Long story short. FoDiMoCo is easy-to-build DIY controller for your Ford USA vehicle that enables top dash display to show some useful information when stock head unit is removed. Initial name of the project was can-clock, as all I wanted is to have clock on dash display. Later it evolved, but name is still in the code.
This README is yet unfinished, nearest plans are to give more details on configuration and finalize messages description.
If you’re too far away from the subject, there is introductory presentation I made on one of DIY meetups
Or enjoy video presentation of the project
If you don’t want to read this long text but just want to get info on building your own FDIM controller, there are steps you need to build your own FoDiMoCo:
If you like this project and want to support it, here is PayPal donate button. Project is non-profit, but I still need to buy parts to improve it and continue RnD.
When this controller is plugged in, your dash display looks like that
Module itself looks like that (one of hardware variants)
FoDiMoCo is tested on Ford Escapes (including Hybrid) and Mercury Mariners 2008-2012. Should work on other Fords of the same generation, including Mustang, Fiesta, F-150, but it’s not yet verified due to lack of test vehicles.
FoDiMoCo is built on Arduino and components that could be found on AliExpress and/or your local DIY electronics store, so it should be easy to reproduce. PCB is available for order at Dirt Cheap PCBs.
Arduino Pro Micro with non-soldered pins</summary> <p>
Search AliExpress </p> </details>
![](/fdim-controller/doc/images/components/mcp-can.jpg) [Search AliExpress](https://aliexpress.com/wholesale?SearchText=mcp2515+controller)
![](/fdim-controller/doc/images/components/ds3231.jpg) [Search AliExpress](https://aliexpress.com/wholesale?SearchText=ds3231+raspberry)
![](/fdim-controller/doc/images/components/7805.jpg) 7805 or similar with wide temperature range and thick heatsink. [Search AliExpress](https://aliexpress.com/wholesale?SearchText=7805)
![](/fdim-controller/doc/images/components/pin-headers-straight.jpg) You will need the following pieces: one 7 pins, one 4 pins, two 3 pins, two 2 pins, one 1 pin [Search AliExpress](https://aliexpress.com/wholesale?SearchText=male+pin+headers+straight+2.54)
![](/fdim-controller/doc/images/components/pin-headers-angled.jpg) You will need the following pieces: one 5 pins, one 2 pins [Search AliExpress](https://aliexpress.com/wholesale?SearchText=male+pin+headers+angled+2.54)
Take [Gerber files](pcb/gerber) and order on [DirtCheap PCB](http://dirtypcbs.com). Or make your own board
And depending on mount type, choose one of the following options
![](/fdim-controller/doc/images/components/elm327-case.jpg) [Search on AliExpress](https://aliexpress.com/wholesale?SearchText=elm327+enclosure)
![](/fdim-controller/doc/images/components/pin-headers-long-2x7.jpg) Can be cut from 2x7 if no 2x6 are available. [Search on AliExpress](https://aliexpress.com/wholesale?SearchText=pin+headers+long+2.54+2x6)
Schematics are more or less self-explanatory. Per components:
SPI protocol is used to control CAN interface. SPI CS line is wired to Arduino pin 10. CAN messages received trigger interrupt bound to Arduino pin 7.
I2C protocol is used to interact with Real-Time Clock module.
Voltage regulator is used despite the fact that Arduino Pro Micro can handle power voltage up to 12 volts. Real vehicle voltage with engine running can be up to 14 volts, so usage of separate voltage regulator gives more guarantees.
PCB is 2-layered with 3 inter-layer drills. DirtCheap PCB make them for you, other manufacturers may require extra wires soldering. Exact components placement is shown below in Soldering section.
There are 2 possible options to mount the module in the car:
If you do care on your battery current, it’s also possible to get power for the module from ACC power line, which powers down the module when vehicle is off and powers it up when it’s on and running. This installation option can be done easier when installed behind FDIM display, as additional wires can be hidded inside your dash.
TBD
Take PCB
Place pin headers on breadboard to simplify soldering
Put PCB over pins and solder it
Solder angled pins for RTC as shown if needed
Rotate PCB and solder angled pins for power connection
Bend power regulator pins and solder it as follows
Rotate PCB and solder Arduino Pro Micro. Check that proper PCB pins are soldered to proper Arduino in/outs
Solder MCP2515 CAN board - start with side pins, then solder others. Soldering is better than socket here to improve vibration stability
Plug RTC module if needed. Fully assembled module looks like that
Solder CAN and power wires to pass-through connection as follows
Other side of connector
Fully assembled unit with pass-through connector
If ELM327 enclosure option is preferred, solder to ELM327 pins as per section above
By design Ford vehicles use two CAN buses - more standard HS CAN (high speed, 500 kbit/s) and Ford-specific MS CAN (medium speed, 125 kbit/s). Newer Fords have even more buses, but since I don’t own one - I can’t tell anything on this subject.
FDIM display and most of less critical devices resides on MS CAN. It is possible to get access to MS CAN even from standard cheap ELM327 scanner by adding simple switch (modified ELM327 scanners with switch are already available on eBay or AliExpress). For more info refer to FORScan forum.
On the image below one can see OBD2 socket pinout for MS CAN bus.
This section contains brief description of MS CAN messages used for FDIM display control and/or getting basic vehicle telemetry data to display on FDIM. All the information is obtained from open sources or by reverse engineering of MS CAN protocol using vehicles available for the author. No Ford official documentation was used in the process, so exact meaning of message formats may be slightly inaccurate, incomplete or inapplicable for specific vehicle models. Information listed below is used to control FDIM modules on Ford Escapes 2008-2010 and Mercury Mariners 2009-2010, both hybrid and non-hybrid. It is theoretically possible to use those messages on Ford Mustangs 2008-2010, F-150s 2009-2010 and Fiestas 2010.
Description: Indicates the presence of ACM (Accessory Control Module) or headunit of the vehicle. FDIM display becomes inactive in the absence of the messages.
Rate: 10 Hz
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x50c | 3 | 0x01 | 0x02 | 0x00 | - | - | - | - | - |
Description: Sets sound source and indicates the presence of ACM (Accessory Control Module) together with 0x50c. FDIM display becomes inactive in the absence of the messages.
Rate: 1 Hz
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3e8 | 8 | source | 0x00 | volume | clock length? | 0x00 | 0x00 | 0x00 | 0x00 |
source can have the following values:
0x01 - AM
0x02 - FM1
0x03 - FM2
0x04 - PHON
0x05 - SYNC
0x06 - DVD
0x07 - AUX
0x08 - CD
0x09 - EMPTY
0x0A - SAT1
0x0B - SAT2
0x0C - SAT3
0x0D - PHON
0x0E - LINE
0x0F - 2 clocks if no text is printed, or one clock if text is present
volume value change displays volume bar
clock length have values only 0x00 or 0x04, possibly sets number of digits in current clock display
Description: Unknown. Sent on FDIM initialization and then with rate 1Hz with slightly different data
Rate: 1 Hz
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3ef | 8 | 0x32 | 0x32 | 0x32 | 0x32 | 0x03 | 0x00 | 0x00 | init |
init value is 0x00 on 1st message sent and then 0x20 when module is activated
Description: Current time displayed. Time is given in binary-coded decimal format.
Rate: 20 Hz. Maybe possible to send less frequently.
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3f2 | 8 | hour | minute | day | month | year | flags | 0x00 | 0x00 |
flags: 0x80 - time is adjusting (blink) 0xA0 - AM 0xC0 - PM 0xE0 - 24 hours 0xC0 - clock off
Special cases
Empty clock
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3f2 | 8 | 0xFF | 0xFF | 0xFF | 0xFF | 0xFF | 0x00 | 0x00 | 0x00 |
Examples
13:02
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3f2 | 8 | 0x13 | 0x02 | 0xFF | 0xFF | 0xFF | 0xF0 | 0x00 | 0x00 |
Description: Unknown. Sent only once in FDIM start-up message sequence.
Rate: Not repeated
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3f1 | 8 | 0xF5 | 0x90 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 |
Description: Current tires pressure value given in psi. Present on newer vehicles (possibly 2010+), not present on hybrids. TPMS request-response protocol is more widely used to get tire pressure, but TPMS broadcast is easier to implement. Minimal pressure level is 25 psi, all values below are still shown as 25.
Rate: 1 Hz.
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3b5 | 8 | front left | front right | rear left | rear right | 0x00 | 0x00 | 0x00 | 0x00 |
Example
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x3b5 | 8 | 0x25 | 0x19 | 0x22 | 0x23 | 0x00 | 0x00 | 0x00 | 0x00 |
Description: Speed in km/h, RPMs and engine temperature. Also indicates when vehicle is in off position.
Rate: Varies
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x423 | 8 | speed1 | speed2 | rpm1 | rpm2 | temperature | 0x00 | 0x00 | 0x00 |
Speed (in km/h) = (speed1 * 256 + speed2) / 100 - 100
RPM = rpm1 * 256 + rpm2
Special cases
Vehicle off
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x423 | 8 | 0xFF | 0xFE | 0xFF | 0xFE | 0xFE | 0x00 | 0x00 | 0x00 |
Description: Current time obtained from GPS satellites, in GMT time zone
Rate: 1 Hz
Format
Header | Length | data byte 0 | data byte 1 | data byte 2 | data byte 3 | data byte 4 | data byte 5 | data byte 6 | data byte 7 |
---|---|---|---|---|---|---|---|---|---|
0x466 | 8 | h | min | s | - | d | mon | y | 0x00 |
Hour = ( h » 3 ) & 0x1F
Minute = ( min » 2 ) & 0x3F
Second = ( s » 2 ) & 0x3F
Day = ( d » 2 ) & 0x3F
Month = ( mon » 4 ) & 0x0F
Year = ( y » 3 ) & 0x1F
platformio run --target upload
Since USB support for Arduino Leonardo/Spark Fun Pro Micro on Catalina is broken, I’ve prepared Vagrantfile to use VirtualBox to flash
vagrant up
- everything should be downloaded and then uploaded to Arduino, ending with messagesdefault: avrdude done. Thank you.
default: ========================= [SUCCESS] Took XXX seconds =========================