CAN Gateway - bill57p9/BMW_ZGW_emulator GitHub Wiki
Introduction
The CAN Gateway is an Arduino with one or two CAN bus shields. It performs two distinct functions:
- Forwarding selected CAN messages between the two CAN buses (if two CAN bus shields are fitted)
- Gateway for selected messages between one CAN bus and a USB serial interface
Hardware
The Arduino platform is available in many forms.
Whilst I use an Arduino Uno R3, this project could be implemented on other Arduino platforms. The main constraint is that most CAN interfaces use a transceiver which requires a 5V supply while some smaller Arduino platforms run on 3.3V.
This project could be implemented in a smaller package, however by sticking to the "standard" Arduino Uno R3 and similarly sized CAN bus modules, I kept it simple.
The parts list I used is as follows:
- Arduino Uno R3
- 2x Sunflower CAN shield
- 2x 9 way D socket, to connect both CAN buses to the shields
- Car USB power supply plus connection to Arduino
- USB A to B cable - to program Arduino
- Arduino mounting plate (plus velcro)
- 4x 8 pin DuPont housings plus pins. However you could solder instead
- 6x MQS female pins (e.g. BMW 61136931880) - For CAN bus connections
- CAN bus cable (twisted pair)
CAN Bus Shield(s)
There are various CAN bus shields available. Personally I used 2x Sunflower CAN shield v3 only because I could source them relatively cheaply and quickly. Mine came as a solder kit, which was convenient because the shield included a terminal block which would be too big for the middle card.
CAN shields are available with either 8MHz or 16MHz oscillators.
Out of the box, the firmware (CAN_gateway_arduino/CAN_gateway_arduino.ino
) is configured for 8MHz. However it is trivial to adjust the following line as appropriate:
const CAN_CLOCK MCP_OSC = MCP_8MHZ;
To provide the required separate interrupt (INT) and chip select (CS) for the two shields, if fitted the upper shield must be modified in the following way:
- Cut the legs of pins D2 and D10
- Connect pin D2 to pin D3. This could be done by soldering, however I made up a DuPont plug to connect the two pins together. I found that a 2 pin plug just fell off, so I made up a plug for the entire pin bank with unused pins fitted.
- Connect pin D9 to pin D10. Again, this could be done by soldering however I made up a plug.
CAN Connectivity
Connect the CAN shields as follows:
- Upper (if fitted) -> KCAN2
- Lower -> KCAN4 / CAN Bus with target ECU connected
KCAN4 CAN Gateway KCAN2
Terminator Terminator
+--+ +----------------+ +--+
| | | | | |
| | | CAN Shield |XXXXXXXXXX| |
| | | | | |
| | +----------------+ | |
| | | | | |
| |XXXXXXXXXX| CAN Shield | | |
| | | | | |
| | +----------------+ | |
| | | | | |
| | | Arduino Uno R3 | | |
| | | | | |
| | +----------------+ | |
| | | |
| | +------+ | |
| |XXXXXXXXXXXXXXX| ICAM | | |
+--+ +------+ +--+
Fixed Installation
There are 3 ways to power an Arduino Uno:
- 7-12V on the barrel socket. The power regulator on the Arduino isn't the most efficient and isn't designed to work above 12V.
- USB-B (5V)
- 5V directly into the top shield header. For the fixed installation I used the header with a car 5V supply (populating all pins to improve adhesion), however in hindsight I would recommend using a car USB supply and a USB-A to USB-B cable.
The ICAM should be powered when the ignition is on. The retrofit kit includes a snap lock connector and instructions to power the ICAM from the PDC/PMA power feed. I used this to power the CAN Gateway too.
I used a mounting plate attached to the carpet with velcro. The F46 has a convenient space under the third seat row to put the gateway.
Installing CAN Gateway Firmware
Although the development environment also supports MacOS, Linux and ChromeOS, the links/detail below is for Windows as Windows is required for the BMW diagnostics/coding/programming tools.
- Download the Arduino MCP2515 Library
- Install the Arduino IDE
- Start the Arduino IDE
- Install the Arduino MCP2515 Library: Select Sketch > Include Library > Add .ZIP Library and then select the library ZIP file downloaded in step 1.
- Open the firmware: Select File > Open and select the firmware file
CAN_gateway_arduino/CAN_gateway_arduino.ino
- Connect the Arduino to your computer with a USB cable
- Configure the connection to the Arduino: Select Tools > Port and select the Arduino connection
- Upload the firmware: Select Sketch > Upload
USB Interface
This section is for information for development purposes.
The USB interface on an Arduino looks like a serial port to a computer.
The emulated serial port is set to run at 1 million baud. This speed is deliberately double the CAN bus speed of 500kbps.
The messages are passed in ASCII in the form nnn#aabbcc... Where nnn is the CAN ID, aa the first payload byte, bb the second and so on.
The CAN bus uses 11 bit CAN IDs, so range 000 - 0x7FF. The payloads are variable length up to 8 bytes.
Filtered CAN messages are echoed by the gateway over the serial interface, and vice-versa. The CAN gateway also echos the messages forwarded to the other CAN bus (KCAN2 for an ICAM).