RW 2.X Driver Display


Overview

The rider display is a user interface to the CAN system for our electric motorcycle RW-2x.

Rider Display, showing splash screen

It’s based off of the Magic CAN Node, although the board layout is unique to accommodate the LCD and buttons.

Introduction

The data acquisition system on the motorcycle is available by plugging in a laptop, or from the onboard wi-fi, but sometimes you need access to information, and can't use an external computer. One example would be accessing the battery state while riding. To fill this need, the rider display was made to be able to monitor any value on the CAN bus and display it on the screen.

Hardware

The processor and CAN interface are the same as the Magic CAN Node. However there is also a 128x64 graphical LCD, two tri-color leds, and 5 buttons with red/green backlights.

LCD

The LCD is from SparkFun gLCD, and the graphical code is a modified version of my SerialgLCD library. If I ever get around to it, I'll post the modified code as a branch, since it has beed decoupled from the original AVR to work with a generic processor. The LCD is a transreflective model with backlight, so it is readable in direct sunlight, as well as at night. The graphical ability allows for large fonts while riding, and smaller fonts for packing lots of information on the screen while in the paddock. There are also some icons and other eye candy, which while not strictly necessary were a lot of fun to add.

Rider Display w/menu Rider Display in test mode Rider Display in race mode

Buttons & Lights

The user interface is made up of illuminated pushbuttons 5GTH9358222. These have the cool feature that they can be illuminated either red or green depending on which way current flows. There are also some tri-color LEDs (red,yellow,green). All in all there are 16 different LED chips used for indication. This was too many pins to drive directly from the microcontroller, so a pair of 8-bit shift registers and a 16-channel buffer were combined to drive them. The lights in the buttons are used primarily to indicate which buttons are active for the current display mode, and the tri-colors indicate the status of the motor controller and GPS/datalogging. This gives an indicator of when everything is up and running before sending the bike out on the track.

Software

The software for the rider display is written in C, and based on the Magic CAN Node template.

User interface

The user interface of the rider display is menu driven. There are five buttons, and although they are not labeled on the housing they have the following functions from left to right: Back,Up,Down,Select,Menu. On power-on the display defaults to "Race Mode" where a single value is displayed on the screen in a large font. The default value is the battery amp-hours used, since this is the most useful feedback to the rider during a race. While in race mode, the up and down buttons cycle through other possible values, and the back button toggles the backlight. The menu button enters the main menu.
The main menu allows the user to choose the various display modes, "Race", "Test", "4 Variable", and also to change what CAN values are monitored. There are four monitoring slots, and they can be assigned to any of the values present on the CAN bus. There is a built in list that is set at compile time, or the CAN ID, offset, and variable type can be entered manually.

CAN parsing

One of the challenges in dealing with can is efficiently extracting a value from the CAN message. The message data is received as an array of bytes, and the value you are interested in may be offset, and may span multiple bytes. To accomplish the data translation efficiently, the code implements a simple database, which stores the CAN ID, variable name, variable type, and bit offset for each value to be monitored. When a CAN message is received, its ID is matched to the database. Then the 8-bytes of can data is copied to a union-type variable. The union is accessed as a uint64, and shifted by the bit offset. Then the union is accessed as the appropriate data type and the value stored in a global data structure.