CAN Bus Steering Wheel

Computers are ubiquitous in the modern world we live in, and in the automobile there is no exception. Modern cars are controlled by a complex interconnection of microcontrollers, and at the core of this is a communication backbone called Control Area Network (CAN). CAN enables robust and scalable peer to peer communication among microcontrollers.

Problem

On UBC Supermileage student team, we build highly efficent ICE, battery electric, and hydrogen electric vehicles. We are using SPI for communication within the vehicles, but we are facing reliability, scalability, and debuggability issues.

SPI is a great protocol for short distance host/peripheral communication, but it is not up to the task of what we are typing to accomplish. Every new node (sensor or actuator) we put into the vehicle means another chip select (SS) wire must be run, and another GPIO slot must be taken up on the host device. One can quickly see the scalability issues here.

SPI Protocol

In terms of reliability, SPI is susceptible to motor noise which can cause communications to fail. Furthermore, SPI is a wiring and debugging nightmare when there are many long distance peripheral device connections.

As we continue to incorporate more complex sensors, actuators and compute into our cars, it is clear another communication solution is necessary, and moving to CAN is the obvious choice. Furthermore, I am also working on designing a new steering wheel for Supermileage ElectricUrban concept vehicle. Thus, this was a good opportunity to incorporate these projects and implement a CAN node in the steering wheel to send driver input and receive vehicle information which will be displayed on a screen for the driver.

CAN Background
CAN is a peer to peer, asynchronous, message based, differential, scalable communication protocol. This is a mouthful so lets break that down:
  • Peer to peer: unlike SPI, there is no host or peripheral device in a CAN bus, every device has equal right to send and receive messages onto the bus.
  • Asynchronous: This means that the data is transmitted without the use of an external clock. This is great for long distance protocols as clock skew won't hinder or break the communication.
  • Message based: Data is sent in packets over the CAN bus, these packets have a specific dataframe structure to comply to the CAN standard. Lets break down the most important parts of the dataframe:
    • 11 bit identifier: This is the CAN ID, which is used to determine which message is meant for which devices. All devices on the bus have access to all the messages, but a device will only read messages with CAN ID's which it is programmed to look for. Note that if there are multiple messages waiting to go on the bus the one with the lowest CAN ID gets priority.
    • Data: This is 8 bytes which is the content of the message that is being sent
    • Cyclic redundancy check (CRC): This is an error checking code to determine if the communication was successful or indicate if there were any corrupt bits. This guarantees that the message received was the ones that was sent.
    • Differential: CAN uses differential signaling to transmit messages over a twisted pair of wires. Meaning that each bit of data is encoded into complementary bits and each is sent over their own wire. These wires are called CAN high, and CAN low, and form the CAN bus backbone. Differential signaling is highly immune to electromagnetic interference (EMI), making CAN very reliable.
  • Scalable: CAN is a flat protocol, only requiring CAN high and CAN low wires. A new node can be added to the bus without difficulty, you just need to tap into the bus lines.
Now that we have covered some of the basic theory, we can examine what hardware is required for implementation.

Inside each node on the CAN bus there is a microcontroller, CAN controller and CAN transceiver. The microcontroller talks to the CAN controller which talks to the CAN transceiver which then communicates with the CAN bus sending and receiver data from other nodes. A bit confusing, but luckily the CAN controller is typically built into the microcontroller, which makes our lives easier. We just need to make sure to add a transceiver converting CAN RX (receiver) and CAN TX (transmit) which are exposed on the microcontrollers GPIO to CAN high and CAN low lines of the CAN bus. You may have also noticed that on either end of the CAN bus, there are 120 Ohm resistors bridging CAN high and CAN low. The purpose of these terminal resistors is to impedance match the characteristic impedance of the transmission lines, minimizing reflections which could cause signal interference.

Thus to summarize, to implement the CAN bus we need:
  • 2 lines, CAN high and CAN low which are terminated by 120 Ohm resistors
  • CAN nodes, which consist of:
    • A microcontroller that has a CAN controller
    • A CAN transceiver
Solution
The goal of this project is to implement CAN into Supermileage vehicles, along with a new steering wheel which is itself a CAN node. Once this first node is implemented it can be replicated for other devices within the cars, so this will also be used as a reference design. This project requires mechanical, electrical and software design.

The first thing I considered is the steering wheel requirements:

  • Typical button functions: lights, horn, blinkers, whippers and hazards
  • Dead man switch: this is a driver monitoring device which will kill the propulsion system when the drivers hands come off the steering wheel. To achieve this I decided to go with an IR sensor so this was non-intrusive to the driver
  • Brake and throttle inputs
  • Send all the driver input data over the CAN bus to be used by other nodes to achieve the desired functions (ex. motorcontroller receives throttle data and sets speed accordingly)
  • Screen to display speed, power and lap time information to the driver
  • Quickly able to detach: to achieve this I used a quick release system
  • Easy programming and debugging, expose the USB port

Here is a first draft of button placement and general overview of what the wheel is going to look like. The general idea is a four component mechanical system which consists:

  1. Water jet aluminum plate which will take transfer loads from the driver twisting the wheel to the quick release
  2. Quick release which allows quick detaching (mechanically and electrically) of the wheel, and when attached will transfer load to the steering column
  3. Back 3D printed piece which will house the PCB
  4. Front 3D printed piece which is what forms the handles and houses the buttons

The mechanical and PCB design were done in parallel as they were highly interdependent. The final mechanical CAD can be seen below.

The electrical design was a PCB with included an STM32L432KC MBED enabled microcontroller, as well as a CAN transceiver, a TFT 2.2" display and all appropriate input connections.

The software can be found here, note that I used MBED libraries to implement CAN in C++ as described in the CAN Background section.

Here is the final prototype
[S]