- First Name
- Xira
- Joined
- Sep 27, 2020
- Threads
- 11
- Messages
- 911
- Reaction score
- 1,648
- Location
- Wisconsin, USA
- Vehicle(s)
- 2016 Flex EcoBoost, 2022 Silverado LT
- Your Bronco Model
- Outer Banks
- Thread starter
- #1
[Edited 11/14/2023: New method, new code, new everything]
A common complaint across the forum is that the Bronco will prompt "Return to [] mode?" instead of staying in that mode.
I decided to automate pressing [OKAY] using an Arduino -- a cheap hobbyist microcontroller. Under the right conditions, it will send the same message on the Canbus as if I pressed [OKAY] manually. For the rest of this post, I'm going to refer to the Arduino+Canbus+Code as a 'Xirabus module'
I won't be able to go into extreme detail because I don't want this to turn into a giant novel of every possible way to implement it, so please bear with me. I'll probably edit this a dozen or so times as I keep trying to decide how to phrase things. My apologies to mobile users.
In an effort to avoid cutting any factory wiring, I also used a number of tools the average person likely won't have handy, unfortunately.
---
Theory of Operation
The xirabus module constantly watches the messages on HS2-CAN. Messages consist of a 3-byte ID, followed by up to 8 bytes of data.
What I've found so far is:
Every new message xirabus reads, it increments a counter by 1.
From this point, it will wait until the following is true:
Once all these conditions are met, it will wait 3½ seconds for the instrument cluster to wake up, then send an [OKAY Button Pressed] message ten times.
The xirabus has no idea if the prompt is actually on-screen, it just blindly presses the button. This will also dismiss any other prompts such as Door Ajar or Accessory Mode Active.
Unfortunately the prompt is generated by FD1-CAN, so I can't detect when it's really happening.
I've included the option to have it automatically select between 2WD/4HI/4A by connecting a jumper wire to ground.
Similar to sending the [OKAY Pressed] message, this broadcasts the same message you'd produce manually pressing the buttons on the GOAT dial.
---
Hardware
The easiest but bulkiest combination is an Arduino Uno and Canbus shield. Almost zero soldering is required.
A little more compact but more soldering is an Arduino Nano and MCP2515 Canbus module. (Wiring diagram available here, or image search 'mcp2515 wiring')
Smaller yet, I designed a custom PCB that combines the Arduino's main IC (ATMega328p) and the MCP2515 in a single board.
This method requires a USBASP programmer (to set the CLKOUT fuse bit in the ATMega) and an FT232RL (to upload the code).
Honestly this method isn't cost-effective if you're only making a single board for yourself, considering most of the needed components are sold in groups of 10+. If you aren't already doing hobby electronics, what are the odds you have a spare 5v regulator or 22pF capacitor in the junk drawer? I also don't know where to host the GERBER file to share the pcb design.
---
Wiring
To keep things simple, only four wires are needed. Power, ground, HS2CAN+, HS2CAN-. Conveniently, all four are connected to the GOAT selector switch. Removing the power window switches gives you just enough space to reach in and disconnect the pigtail.
As mentioned above, I wanted to avoid having to cut any factory wiring. To make a Y-cable, I designed and 3D printed a pair of adapters to use Dupont terminals. It's not 100% oem-matching but close enough to work reliably. The Arduino connects in parallel to all four wires.
The pinout for the GOAT switch connector is as follows:
---
Program Code
Don't judge my methods, I'm not an expert coder. I typed half of this with the laptop sitting on my wife's lap in the passenger seat.
For posterity's sake, the command to set an ATMega's CLKOUT (Pin 8 becomes a clock output) is avrdude -p m328p -c usbasp -u lfuse:w:0xBF:m
A common complaint across the forum is that the Bronco will prompt "Return to [] mode?" instead of staying in that mode.
I decided to automate pressing [OKAY] using an Arduino -- a cheap hobbyist microcontroller. Under the right conditions, it will send the same message on the Canbus as if I pressed [OKAY] manually. For the rest of this post, I'm going to refer to the Arduino+Canbus+Code as a 'Xirabus module'
I won't be able to go into extreme detail because I don't want this to turn into a giant novel of every possible way to implement it, so please bear with me. I'll probably edit this a dozen or so times as I keep trying to decide how to phrase things. My apologies to mobile users.
In an effort to avoid cutting any factory wiring, I also used a number of tools the average person likely won't have handy, unfortunately.
---
Theory of Operation
The xirabus module constantly watches the messages on HS2-CAN. Messages consist of a 3-byte ID, followed by up to 8 bytes of data.
What I've found so far is:
- ID 167 byte 0 seems to indicate the engine state. 00: Off | 20: Cranking | 52: Remote Start | 72: Running | B0: Auto-Stop | B6/76: ASS-Restarting
- ID 167 byte 3 has something to do with the current accessory mode. It's 00 when engine off, 10 when engine on.
- Every ~300 messages, a message with an ID of 18A is produced when the car is in Accessory or Run. I don't know what it is, but it stops immediately when the car is off.
Every new message xirabus reads, it increments a counter by 1.
If the message has an ID of 167, it stores the values of bytes 0 and 3 as EngineState and AccState.
If the message has an ID of 18A, it resets the counter to zero.
If the counter reaches 1,200 it will assume the Bronco is turned off -- 18A stops being produced, but other IDs continue being broadcast for several minutes.
From this point, it will wait until the following is true:
- 18A messages are being produced again.
- EngineState is not 0x20 or 0x52. This is to make it wait during remote starts, where 18A will happen but the instrument cluster isn't ready to display 'Return to [] Mode?'
- AccState is 0x10. This is to catch a condition where you stop the engine, but then restart it without opening the door.
Once all these conditions are met, it will wait 3½ seconds for the instrument cluster to wake up, then send an [OKAY Button Pressed] message ten times.
The xirabus has no idea if the prompt is actually on-screen, it just blindly presses the button. This will also dismiss any other prompts such as Door Ajar or Accessory Mode Active.
Unfortunately the prompt is generated by FD1-CAN, so I can't detect when it's really happening.
I've included the option to have it automatically select between 2WD/4HI/4A by connecting a jumper wire to ground.
Digital Pin 5: Connect to GROUND to select 2WD
Digital Pin 6: Connect to GROUND to select 4-HI
Digital Pin 7: Connect to GROUND to select 4-A
If no jumper is installed, the car will switch to the default for the selected GOAT mode like normal.Similar to sending the [OKAY Pressed] message, this broadcasts the same message you'd produce manually pressing the buttons on the GOAT dial.
---
Hardware
The easiest but bulkiest combination is an Arduino Uno and Canbus shield. Almost zero soldering is required.
A little more compact but more soldering is an Arduino Nano and MCP2515 Canbus module. (Wiring diagram available here, or image search 'mcp2515 wiring')
Smaller yet, I designed a custom PCB that combines the Arduino's main IC (ATMega328p) and the MCP2515 in a single board.
This method requires a USBASP programmer (to set the CLKOUT fuse bit in the ATMega) and an FT232RL (to upload the code).
Honestly this method isn't cost-effective if you're only making a single board for yourself, considering most of the needed components are sold in groups of 10+. If you aren't already doing hobby electronics, what are the odds you have a spare 5v regulator or 22pF capacitor in the junk drawer? I also don't know where to host the GERBER file to share the pcb design.
---
Wiring
To keep things simple, only four wires are needed. Power, ground, HS2CAN+, HS2CAN-. Conveniently, all four are connected to the GOAT selector switch. Removing the power window switches gives you just enough space to reach in and disconnect the pigtail.
As mentioned above, I wanted to avoid having to cut any factory wiring. To make a Y-cable, I designed and 3D printed a pair of adapters to use Dupont terminals. It's not 100% oem-matching but close enough to work reliably. The Arduino connects in parallel to all four wires.
The pinout for the GOAT switch connector is as follows:
Pin 1 | White/Red | VBATT |
Pin 2 | Grey/Blue | HS2-CAN (-) |
Pin 3 | Green/Orange | HS2-CAN (+) |
Pin 4 | Black/Violet | GROUND |
Pin 5 | N/C | N/C |
Pin 6 | N/C | N/C |
---
Program Code
Don't judge my methods, I'm not an expert coder. I typed half of this with the laptop sitting on my wife's lap in the passenger seat.
For posterity's sake, the command to set an ATMega's CLKOUT (Pin 8 becomes a clock output) is avrdude -p m328p -c usbasp -u lfuse:w:0xBF:m
Sponsored
Last edited: