Home

FSAE Electric Car Dashboard Display and Interface

I created a dashboard display for the UC Davis 2014 electric formula car to provide the driver with critical information, such as battery state of charge, and the rest of the team with the state of the system for debugging and maintenance of the battery. The unit was completed in 2 to 3 months during an active school year. The car competed in the international 2014 FSAE Electric in Nebraska, Lincoln competition and achieved third place.

The dashboard display features a 128x64 LCD Screen (controlled by the popular KS108), an LED bar graph, a piezo buzzer, and a rotary encoder with an integrated button. Rotating the rotary encoder switched between several preconfigured screens of information about the battery's condition. The battery information was received via serial communication with another board connected to the car's CAN bus.

Initially, development began on the Arduino Uno (an ATmega328P) and a simple breadboard. Since FSAE is intended as an education opportunity, I wrote a graphical library for the KS108 from scratch, including extras such as text printing and rectangle drawing functions, and tried to avoid Arduino environment libraries to create portable code. I also wrote program for the PC to convert PNG images into C constants that I can simply copy and paste into the program source files to complement the graphical library. The converter program requires libpng.

Here are the available functions from the lcd.h to interact with the LCD.

typedef struct
{
  uint8_t di, rw, db, cs_one, cs_two;
} LcdInputs;

void lcd_input(LcdInputs* Inputs);
void lcd_clear();
void lcd_init();
void lcd_onoff();
void lcd_draw(uint8_t lcdBuffer[2][8][64]);

Here are the available functions from the graphics.h to manipulate a graphics buffer in memory before writing to the LCD.

void graphics_blit(uint8_t lcdBuffer[2][8][64],
  uint8_t dstX, uint8_t dstY, const uint8_t *bitmap,
  uint16_t srcX, uint16_t srcY, uint8_t width,
  uint8_t height, uint16_t rowLen, uint8_t mode);

void graphics_clear_buffer(uint8_t lcdBuffer[2][8][64]);

void graphics_print(uint8_t lcdBuffer[2][8][64], uint8_t dstX, uint8_t dstY,
  char* string);

void graphics_num(uint8_t lcdBuffer[2][8][64], uint8_t dstX, uint8_t dstY,
  char* string);

void graphics_rect(uint8_t lcdBuffer[2][8][64], uint8_t dstX, uint8_t dstY,
  uint8_t width, uint8_t height, uint8_t mode);

The PC program would convert black and white PNG images into hexadecimal constants, where every bit represents a pixel, and every hex number represents 8 pixels horizontally.

PROGMEM const uint8_t bitmapCharacters[480] =
{
  0x01, 0x14, 0xA2, ...
};

Testing KS108 LCD functions

Figure 1. Testing KS108 LCD functions. Note the interesting result of not initializing the graphics buffer to 1 on the right side of the screen.

Initial development on a breadboard and an Arduino Uno

Figure 2. Initial development on a breadboard and an Arduino Uno

Bare printed circuit board

Figure 3. Bare printed circuit board

After developing the graphics driver, I realized that the Arduino Uno had insufficient memory to hold the pixels states and collect data comfortably. The Teensy++ 2.0 by PJRC, an AT90USB1286 chip, was chosen as a replacement. The graphics driver was written with AVR macros and no arduino libraries, so the program was easily reconfigured for the new platform.

The initial breadboard was bulky and fragile, so I used free-hanging wire-wrap (30 AWG) to make all the connections. Since the wire was solid core and the project flexed from the lack of structural support, it eventually deteriorated from simply moving the project around.

Wire-wrap prototyping

Figure 4. Wire-wrap prototyping

Internal wear and tear of solid core wiring

Figure 5. Internal wear and tear of solid core wiring. Note the distinct boundary from glitching on the CS1 side of the KS108.

Fully populated board without the
micro-controller

Figure 6. Fully populated board without the micro-controller

Originally, a menu system was implemented, which required the integrated push button to traverse. Scrapped features of the car, including a very large sensor network, led to a great simplification of the virtual user interface.

Light hitting the top of the LED caused the LEDs to "glow" as they diffused the light. A piece of masking tape covering the top was surprisingly effective in raising the contrast.

Powered on! Note the single led to test the bar
graph on the left

Figure 7. Powered on! Note the single led to test the bar graph on the left

For a very long time, the display was developed without the real information to debug from, since the other systems were not completed yet. The first real connection and debugging happened in a hotel room at competition. In the following pictures, a hidden CAN enabled micro-controller is attached to the back of the unit to provide CAN communication with the battery. A test box and CAN bus terminating resistor was needed to successfully activate the battery pack for testing.

Voltage display while testing with the battery pack

Figure 8. Voltage display while testing with the battery pack

A somewhat fuzzy picture of the entire battery.

Figure 9. A somewhat fuzzy picture of the entire battery

Battery debug screen with actual information

Figure 10. Battery debug screen with actual information

Super secret flappy bird easter egg

Figure 11. Super secret flappy bird easter egg

Due to the lack of time for development for both this project and projects this depended on, the display unit's packaging was rushed. For example, the CAN micro-controller that provided compatibility was simply zip-tied to the back of the display unit, which eventually led to corrosion through moisture and death of the part. Another example is the mechanical positioning of the unit too high up the dashboard, which rendered the LED bar graph invisible to the driver. The PCB design itself could have been slimmed down with permanent mounting of the LCD without tall header sockets and use of the microcontroller without the dev board.

Installed display

Figure 12. Installed display

Installed display with the entire car, sans the nose cone

Figure 13. The full dashboard panel. Note the complete technical inspection certification stickers.

Installed display with the entire car, sans the nose cone

Figure 14. Installed display with the entire car, sans the nose cone

A driver preparing for race inspection

Figure 15. A driver preparing for race inspection

The third place cup

Figure 16. The third place cup

The students of Unicamp (Universidade Estadual de Campinas) took first place at the end. Their dashboard display was interestingly spartan, with only a small dip style LED bar and a seven-segment display. Perhaps there is virtue in simplicity.

The car of our Brazilian friends who took first place

Figure 15. The car of our Brazilian friends who took first place

Notes

1/21/16: added figures 12 and 13.

Written on the 10th of October in 2014