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:

  1. Forwarding selected CAN messages between the two CAN buses (if two CAN bus shields are fitted)
  2. 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:

  1. Cut the legs of pins D2 and D10
  2. 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.
  3. 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:

  1. 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.
  2. USB-B (5V)
  3. 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.

  1. Download the Arduino MCP2515 Library
  2. Install the Arduino IDE
  3. Start the Arduino IDE
  4. Install the Arduino MCP2515 Library: Select Sketch > Include Library > Add .ZIP Library and then select the library ZIP file downloaded in step 1.
  5. Open the firmware: Select File > Open and select the firmware file CAN_gateway_arduino/CAN_gateway_arduino.ino
  6. Connect the Arduino to your computer with a USB cable
  7. Configure the connection to the Arduino: Select Tools > Port and select the Arduino connection
  8. 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).