CAN-Based In-Vehicle Network, Sunswift 7

8+ nodes · zero downtime across the World Solar Challenge

Overview

This is the nervous system of Sunswift 7: a custom CAN network connecting 8+ sensor and actuator nodes across the car, which carried 1,900+ messages with zero downtime incidents across the 3,200 km World Solar Challenge.

From V1 to V2

The car's original embedded system spread its logic across the nodes themselves. The drive node handled driver controls, the rear node handled taillights and sensors. Nobody could quite say which node was responsible for what, and worse, the system wasn't extendable, which is a real problem on a prototype vehicle where new features show up constantly. Its custom CAN protocol layer had also gone unmaintained since the student who wrote it graduated, a classic student-team trap the redesign had to avoid falling into again.

Embedded V2, which I helped design and build, centralizes everything. An internet-connected ADLink ROSCube (an NVIDIA Jetson-based robotics controller running Ubuntu and ROS2) makes every decision, while the 8+ CAN nodes (STM32G4 microcontrollers on custom Sunswift-designed PCBs) carry no logic at all. Sensor nodes stream raw readings to the central computer; actuator nodes do what they're told. Want to add a capability to the car? Add a dumb node and write its logic centrally.

Network and message design

Rather than invent yet another bespoke protocol destined to rot like the protocol used in the previous car, V2 went with a standard. We compared the major higher-layer CAN protocols (SAE J1939, CANopen, DeviceNet, CANKingdom), and CANopen won on its fit with the car's centralized master/slave philosophy. The open-source CANopenNode stack runs on each node on top of the STM32 HAL. Every node gets a 7-bit CANopen node ID (0x01–0x7F), and message IDs follow the CANopen scheme. The pedal box controller, for instance, publishes pedal position at CAN ID 0x185. Here's the neat part: since lower CAN IDs win bus arbitration, ID allocation is priority allocation. Auxiliary traffic like firmware updates got deliberately parked in the 0x800+ range where it can never outrank a control frame. The car also runs up to six separate CAN buses at 500 kbps, which keeps traffic domains isolated and spreads the bandwidth load.

What broke: the RTOS itself

The nodes originally ran Arm's Mbed OS, which we picked for its ease of use and community drivers. Then, during pre-race testing at the 2023 World Solar Challenge, the steering wheel controller started failing at random. The node would just hang until someone gave it a hardware reset. We narrowed it down to Mbed OS itself crashing, plausibly a side effect of an RTOS built for IoT gadgets being asked to run safety-critical car electronics. That was disqualifying for nodes where a hang actually matters, so the stack moved to the lower-level but more robust STM32 HAL. Working with Mbed OS is also what pushed me to contribute upstream to mbed-os along the way, but the lesson stuck: for safety-critical embedded work, boring and close to the metal beats convenient.

Testing

A race is a terrible place to discover a bug, so everything got proven on the bench first. Sunswift designed a testbench node for exactly this: the same STM32G4 as every node in the car, with an onboard ST-LINK programmer, hooked up to a test computer over a PCAN-USB adapter. New firmware and protocol changes ran there first, with candump watching the actual frames on the bus, before anything got near the vehicle. The same rig carried the firmware-update system's development too. I could flash a node over CAN hundreds of times without ever touching the car.

Result

1st place at the 2023 Bridgestone World Solar Challenge, Darwin to Adelaide, against 10+ international teams, with zero network downtime incidents across five days of racing through the desert. The network just quietly did its job the whole way, which is exactly what you want from a network.

Read the UNSW news report ← Back to all projects