MD80 FDCAN communication#

The easiest way to communicate with an MD80 controller is to use a CANdle device connected to a PC. Even though we are aware some customers want to integrate the MD80 controllers in their product with minimal setup to reduce the costs and the system’s complexity. This manual will guide you through the process of communicating with MD80 actuators from your custom FDCAN-capable master controller.

Hardware requirements#

The main requirement for the host system is to be equipped with an FDCAN peripheral (either a built-in one or an external one) and an FDCAN transceiver capable of speeds up to 8Mbps. Lower maximum speed transceivers can be used as well, however for the cost of limited update rates. Currently, the differential side of the transceiver (the CANH and CANL lines) is supplied with 5V. Depending on your custom setup you should be able to integrate a 120 ohm terminating resistor on both ends of your CAN bus (MD80 controllers from version 2.0 can be upgraded to software controlled termination. Please contact us for more information).

Communication Structure#

The communication stack is based on a register access using two frames - register read and register write. The list of available registers can be found at the end of this chapter. All fields are little-endian - least significant byte first, and all float fields are 4 bytes long encoded in IEEE-754 standard.

Default response#

The default response is sent by the drive in case a register write operation was successfull.

BYTE 0 BYTE 1-2 BYTE 3 BYTE 4-7 BYTE 8-11 BYTE 12-15 BYTE 16-19 BYTE 20-23
TYPE uint8_t uint16_t uint8_t [*C] float [rad] float [rad/s] float [Nm] float [rad] float [rad/s]
VALUE 0x0A 0x0000 - 0xFFFF 0 - 255 - - - - -

In case the operation initiated by a frame was unsuccessful the MD80 will not respond.

Write register frame#

Write register frame is used to modify values of the user-modifiable registers. Only registers with write access can be modified.

WRITE_REGISTER 0x40 X (64 max) 0x40 0x00 reg ID value reg ID value


  • regID (uint16_t) - first register ID (please see the end of this section)

  • value (uint8_t/uint16_t/uint32_t/float/char[]) - first register value to be written

  • regID (uint16_t) - second register ID (please see the end of this section)

  • value (uint8_t/uint16_t/uint32_t/float/char[]) - second register value to be written

  • … (up to 64 bytes total)

When all registers write operations succeed the drive will respond with default response.

Read Register Frame#

Read register command is used to retrieve certain register values. The actuator will respond with a frame consisting of the addresses and values of the registers issued in the master request. The master request should have the following form:

READ_REGISTER 0x41 X (64 max) 0x41 0x00 reg ID 0x00 reg ID 0x00

When all read operations succeed the 0x00 fields will be filled with appropriate register data when transmitted back to master by the MD80 controller. Maximum payload should not exceed 64 bytes.

Available registers#

reg name address read/write size limits description
canId 0x001 RW uint32_t [10-2000] FDCAN bus id number
canBaudrate 0x002 RW uint32_t [1e6;2e6;5e6;8e6] FDCAN bus baudrate
canWatchdog 0x003 RW uint16_t [0-2500] FDCAN bus watchdog period in ms
canTermination 0x004 RW uint8_t [0-1] CAN termination (available upon request)
motorName 0x010 RW char[24] - motor name
motorPolePairs 0x011 RW uint32_t [2;225] motor pole pair count
motorKt 0x012 RW float >0 motor torque constant
motorIMax 0x016 RW float [1 - peak controller current] maximum phase current
motorGearRatio 0x017 RW float - actuator gear ratio (ex 2:1 should be 0.5) <1 - reductors >1 - multiplicators
motorTorgueBandwidth 0x018 RW uint16_t [50-2500] torque bandwidth in Hz
motorResistance 0x01B RO float [5mOhm-20Ohm] motor resistance in d axis
motorInductance 0x01C RO float [5nH-100mH] motor inductance in d axis
motorKV 0x01D RW uint16_t - motor KV rating [RPM/V]
motorCalibrationMode 0x01E RW uint8_t [0;1] FULL = 0, NOPPDET = 1
outputEncoder 0x020 RW uint8_t [0;1;2;3] NONE = 0, AS5047_CENTER = 1, AS5047_OFFAXIS = 2, MB053SFA17BENT00 = 3, CM_OFFAXIS = 4, M24B_CENTER = 5, M24B_OFFAXIS = 6
outputEncoderDefaultBaud 0x022 RW uint32_t - output encoder default baudrate
outputEncoderVelocity 0x023 RO float - output encoder velocity in rad/s (calculated in a 5kHz loop)
outputEncoderPosition 0x024 RO float - output encoder position in rad (read in 5kHz loop)
outputEncoderMode 0x025 RW uint8_t [0;1;2;3;4] NONE = 0, STARTUP = 1, MOTION = 2, REPORT = 3, MAIN = 4
outputEncoderCalibrationMode 0x026 RW uint8_t [0;1] FULL = 0, DIRONLY = 1
motorPosPidKp 0x030 RW float - position PID proportional gain
motorPosPidKi 0x031 RW float - position PID integral gain
motorPosPidKd 0x032 RW float - position PID derivative gain
motorPosPidWindup 0x034 RW float - position PID integral windup limit
motorVelPidKp 0x040 RW float - velocity PID proportional gain
motorVelPidKi 0x041 RW float - velocity PID integral gain
motorVelPidKd 0x042 RW float - velocity PID derivative gain
motorVelPidWindup 0x044 RW float - velocity PID integral windup limit
motorImpPidKp 0x050 RW float - impedance PD proportional gain
motorImpPidKd 0x051 RW float - impedance PD derivative gain
mainEncoderVelocity 0x062 RO float - main encoder velocity in rad/s (calculated in a 40kHz loop)
mainEncoderPosition 0x063 RO float - main encoder position in rad (read in 40kHz loop)
motorTorque 0x064 RO float - motor output shaft torque in Nm (read in 40kHz loop)
homingMode 0x070 RW uint8_t [0;1] 0 - OFF, 1 - SENSORLESS
homingMaxTravel 0x071 RW float - max allowable movmement in rad during homing
homingVelocity 0x072 RW float - velocity in rad/s during homing movement
homingTorque 0x073 RW float - maximum and threshold torque for sensorless homing in Nm
runSaveCmd 0x080 WO uint8_t other than 0 to run save non-volatle memory
runTestMainEncoderCmd 0x081 WO uint8_t other than 0 to run runs main encoder test routine
runTestOutputEncoderCmd 0x082 WO uint8_t other than 0 to run runs output encoder test routine
runCalibrateCmd 0x083 WO uint8_t other than 0 to run runs main calibration routine
runCalibrateOutpuEncoderCmd 0x084 WO uint8_t other than 0 to run runs output encoder calibration routine
runCalibratePiGains 0x085 WO uint8_t other than 0 to run runs current PI loop calibration routine
runHoming 0x086 WO uint8_t other than 0 to run runs homing
runRestoreFactoryConfig 0x087 WO uint8_t other than 0 to run reverts config to factory state
runReset 0x088 WO uint8_t other than 0 to run resets the controller
runClearWarnings 0x089 WO uint8_t other than 0 to run clears all warnings
runClearErrors 0x08A WO uint8_t other than 0 to run clears non-critical errors
runBlink 0x08B WO uint8_t other than 0 to run blinks onboard leds
runZero 0x08C WO uint8_t other than 0 to run sets new zero position
runCanReinit 0x08D WO uint8_t other than 0 to run reinits can peripheral
calOutputEncoderStdDev 0x100 RO float - output encoder test result (standard deviation)
calOutputEncoderMinE 0x101 RO float - output encoder test result (min error)
calOutputEncoderMaxE 0x102 RO float - output encoder test result (max error)
calMainEncoderStdDev 0x103 RO float - main encoder test result (standard deviation)
calMainEncoderMinE 0x104 RO float - main encoder test result (min error)
calMainEncoderMaxE 0x105 RO float - main encoder test result (max error)
positionLimitMax 0x110 RW float - minimum valid position
positionLimitMin 0x111 RW float - maximum valid position
maxTorque 0x112 RW float - maximum torque
maxVelocity 0x113 RW float - maximum velocity
maxAcceleration 0x114 RW float - maximum acceleration
maxDeceleration 0x115 RW float - maximum deceleration
profileVelocity 0x120 RW float - profile velocity
profileAcceleration 0x121 RW float - profile acceleration
profileDeceleration 0x122 RW float - profile deceleration
quickStopDeceleration 0x123 RW float - quick stop deceleration in case of a non-critical error
positionWindow 0x124 RW float - position window within position is considered to be reached
velocityWindow 0x125 RW float - velocity window within velocity is considered to be reached
motionModeCommand 0x140 WO uint8_t - commans a motion mode change: IDLE = 0x00, POSITION_PID = 0x01, VELOCITY_PID = 0x02, RAW_TORQUE = 0x03, IMPEDANCE = 0x04, POSITION_PROFILE = 0x07, VELOCITY_PROFILE = 0x08
motionModeStatus 0x141 RO uint8_t - shows the currently set motion mode
state 0x142 RW uint16_t - returns the internal state machine state of the controller
targetPosition 0x150 RW float - sets target position in rad
targetVelocity 0x151 RW float - sets target velocity in rad/s
targetTorque 0x152 RW float - sets target torque in Nm
reverseDirection 0x600 RW uint8_t - used to change the direction of the main encoder when using other encoders than the onboard one. Always recalibrate after changing this setting
shuntResistance 0x700 RO float [0.001 - 0.01] Current sense resistor value. Setting this register to a value that is not coherent with the hardware may damage the controller. In this cases warranty is not respected.
buildDate 0x800 RO uint32_t - software build date
commitHash 0x801 RO char[8] - commit hash
firmwareVersion 0x802 RO uint32_t - -
hardwareVersion 0x803 RO uint8_t - -
bridgeType 0x804 RO uint8_t - type of the mosfet driver
quickStatus 0x805 RO uint16_t - quick status vector
mosfetTemperature 0x806 RO float - power stage temperature
motorTemperature 0x807 RO float - motor temperature (if thermistor is mounted)
motorShutdownTemp 0x808 RW uint8_t - temperature at which the md80 will enter IDLE mode
mainEncoderErrors 0x809 RO uint32_t - main encoder errors
outputEncoderErrors 0x80A RO uint32_t - output encoder errors
calibrationErrors 0x80B RO uint32_t - calibration errors
bridgeErrors 0x80C RO uint32_t - bridge errors
hardwareErrors 0x80D RO uint32_t - hardware errors
communicationErrors 0x80E RO uint32_t - communication errors
homingErrors 0x80F RO uint32_t - homing errors
motionErrors 0x810 RO uint32_t - motion errors