FW15 Motor Controller Interface
We are using WaveSculptor22 for motor controller, see TritiumWaveSculptor22_Manual.pdf (tritiumcharging.com) for docs.
Motivation
The motor controllers (MC) are a third-party board with a custom CAN communication protocol. The MC must send and receive messages to the driver controls (DC), however because the MC protocol is strict and thorough it requires abstraction from the rest of the system. The motor controller interface (MCI) handles this abstraction.
Components
Moter Controller (MC)
MCI must transmit to MC every 250ms or else the MC will shut down. This will be a periodic (200ms) task.
MCI will receive updates on measurements of voltage and current, these will be transmitted to DC.
(Try to see if it’s possible to use can.h to control two can controllers simultaneously, if not, use mcp2515
needs to be migrated to fwxv)
Driver Controls (DC)
MCI will receive can msgs from DC requesting to set the car’s drive state. MCI then sends the message to MC.
MCI will transmit voltage and current updates to the main CAN line.
CAN
There are two can lines, one communicates only to MC referred to as MC-CAN, and the other communicates to the rest of the car referred to as CAN. MC-CAN is through CAN FD, which has 5x the speed of regular CAN! This is needed to keep up with wave-sculptor timing requirements.
Task
CAN rx, MC-CAN rx
process msgs sent by CAN rx, update any states
process msgs sent by MC-CAN, update any states
build messages for MC-CAN and CAN
CAN tx, MC-CAN tx
Can Messages
WaveSculptor’s broadcast messages can be found TritiumWaveSculptor22_Manual.pdf (tritiumcharging.com) section 18.4
18.4.2: Status: Error Flags uses bits 1-8 instead of 0-7,
this was parsed incorrectly on firmware_xiv
WaveScultpor drive command message can be found in section 18.2
Drive commands to the MCI:
// drive state from center console
data:
target_vel: float m/s
state: enum(off, drive, reverse, cruise)
regen_breaking: uint8_t (boolean) if regen breaking is enabled
cruise_control: uint8_t (boolean) if cruise control is enabled
// pedal state from pedal
data:
throttle: float (0.0 - 1.0)
brake: float (0.0 - 1.0)
Also takes CAN messages from pedal board to determine motor current percent (torque). This only happend when MCI is in the drive/reverse state
MCI status messages, groups by motor controller:
id:
target:
data:
// these are updated every 200ms
velocity: float
rpm: float
bus_voltage_v: float
bus_current_a: float
mc_limit_bitset: uint8_t
mc_error_bitset: uint8_t
// these are updated every second
motor_temp_c: float
heatsink_temp_c: float
dsp_temp_c: float
Messages to center console
1:
- velocity left: int16 (cm/s)
- velocity right: int16 (cm/s)
2:
- voltage left: uint16 (cV)
- current left: uint16 (cA)
- voltage right: uint16 (cV)
- current right: uint16 (cA)
3:
- limit_bitset left: uint8_t
- error_bitset left: uint8_t
- limit_bitset right: uint8_t
- error_bitset right: uint8_t
- board_fault bitset: uint8_t
- overtemp bitset: uint8_t
- precharge_state: uint8_t
4:
- motor_temp left: uint16_t (C/100)
- heatsink_temp left: uint16_t (C/100)
- motor_temp right: uint16_t (C/100)
- heatsink_temp right: uint16_t (C/100)
5:
- dsp_temp left: uint16_t (C/100)
- dsp_temp right: uint16_t (C/100)
Precharge:
In the firmware precharge is a monitor pin which gets toggled LOW when precharge is complete. We use a falling_edge interrupt to verify that precharge has occurred. Once it has happened we toggle the MCI_RELAY, closing the connection with the motor controller and the pack.
Precharge Monitor (FALLING EDGE) → Close MCI_RELAY
Electrically (IMPORTANT TO KNOW!), the precharge circuit charges up all capacitors in the wavesculptor22. Initially, all capacitors act as short circuits, meaning a large in-rush current will flow in once connected to the pack. This can severely damage our motor controllers. We can limit inrush current by having a 5W resistor in series with MOTOR_GND and ISO_GND.
During start-up, precharge equalizes MOTOR_GND and ISO_GND, achieving 0 potential difference. Initially, the current will flow between MOTOR_GND and ISO_GND, holding our monitor pin HIGH (Optocoupler). When precharge is complete no more current will flow, and our monitor pin will be LOW.