IM6014 Motor Use Manual
IM6014 Motor Use Manual
Add content here

1. Motor Overview
A permanent magnet synchronous motor mainly consists of two parts: the stator and the rotor. The stator is rigidly connected to the motor housing, while the rotor is rotatable and has permanent magnets attached to it.
We know that when an external magnetic field of constant direction is applied to a permanent magnet from a certain direction, the permanent magnet experiences both attractive and repulsive forces due to the external field, generating a rotational torque. Ultimately, the permanent magnet will be attracted, rotate, and come to rest in a direction parallel to the applied external magnetic field. A typical example is a compass needle in the Earth's magnetic field β the compass needle rotates until it points toward the Earth's North and South Poles (i.e., the magnetic needle aligns parallel to the geomagnetic field direction). Similarly, if this fixed magnetic field begins to rotate, the permanent magnet will rotate along with it, trying to follow the direction that minimizes the angle between the external field and its own magnetic field.
In this way, we can rotate the permanent magnet to a desired angle by rotating the magnetic field. At the same time, the torque generated by the permanent magnet in the applied external magnetic field depends on the angle between the permanent magnet's field direction and the external field direction. Therefore, we can also control the torque produced by the permanent magnet by controlling the angle between the external magnetic field and the permanent magnet's magnetic field.
From the motor perspective, this means that by controlling the magnitude and direction of the currents in the three windings of the stator, we can control the direction and magnitude of the stator's magnetic field, thereby controlling the output torque of the rotor. This control method is known as Field-Oriented Control (FOC) for permanent magnet synchronous motors.
2. Introduction to Field-Oriented Control (FOC)
FOC control has many unique advantages. It allows us to achieve "pixel-level" control of permanent magnet synchronous motors, enabling results that are unattainable with traditional motor control methods:
- Precise control can be maintained at low speeds;
- Motor reversal (forward/reverse rotation) can be achieved smoothly;
- Three closed-loop controls of the motor β torque, speed, and position β can be realized;
- Permanent magnet synchronous motors with FOC control have lower noise.
As described in the overview of permanent magnet synchronous motors, the foundation of FOC control is the rotating magnetic field. In the magnetic field vector diagram below, we can see that the three coils a, b, c of the motor stator can generate magnetic fields Ba, Bb, Bc in three directions, which together synthesize the resultant magnetic field B within the motor. Based on the current angle and angular velocity of the permanent magnet rotor, the desired output torque, and the sampled/measured currents of the three coils a, b, c, the FOC controller calculates the on/off states and durations of the voltages applied to the three coils. It then controls the on/off states of the voltages across the three coils via MOSFETs. In this way, the desired magnetic field B is synthesized, thereby driving the motor rotor to move in the desired manner.

Figure 1: Magnetic Field Vector of FOC
3. Overview of Motor Hardware and Encoder
The core components of the motor include the motor driver board, stator, rotor, and planetary gear reducer. Since the motor is suitable for high-speed, low-torque operating conditions, while our robot requires low-speed, high-torque output, the motor rotor must be decelerated through the reducer before outputting torque. The N6014B-12.6 motor adopts a dual-encoder design, with single-turn absolute position encoders installed on both the rotor side and the output side. The system outputs the rotor-side position data via a communication protocol, and the output-side position information can be obtained through calculation.
An encoder is a sensor used to measure rotational angle. Encoders come in various types, including incremental encoders, multi-turn absolute position encoders, and single-turn absolute position encoders. Here, we will only discuss in detail the single-turn absolute position encoder as used in joint motors.
The single-turn absolute position encoder of a joint motor is mounted on the motor rotor. For a single-turn absolute position encoder (hereinafter referred to simply as "encoder"), we can think of it as a "clock dial". Every time we look at a clock, we can read the current date and time, for example, April 1st, 23:00. If two hours pass, the clock passes 24:00 on April 1st, the date increases by one day to April 2nd, and the time restarts from 0:00, becoming April 2nd, 01:00. For the convenience of calculating elapsed time, we could also say it is April 1st, 25:00. Although 25:00 exceeds the 24-hour range of a day, this is effectively because the date has increased by one day.
The same principle applies to a single-turn absolute position encoder. Each time the system is powered on, our rotor may be at an arbitrary position, and the encoder tells us the angular position of the rotor (a value between 0 and 2π). If the rotor rotates past the 2π angular position, the encoder can also record that the number of rotations has increased by one, thus outputting an angular position that exceeds the range of 0 to 2π. It seems that the encoder can output angular positions beyond a single turn, so why is it called a "single-turn" absolute position encoder? The reason is that this type of encoder cannot store the previous number of rotations after power-off, as illustrated by the following example.
Suppose the current angle value output by the encoder is 2.3π. This means that after power-on, the encoder has passed 2π, the rotation count has changed from 0 to 1, and the encoder is currently at a position of 0.3π. Now, if we power off the encoder without rotating it at all, and then power it on again, the angle value output by the encoder will become 0.3π. This is because the rotation count resets to 0 after power-off, so the encoder will only output the current position of 0.3π.
4. Hybrid Control of Motors
As a highly integrated power unit, the joint motor has built-in low-level motor control algorithms. Users only need to send relevant commands to the joint motor, and the motor will complete the entire process from receiving commands to outputting joint torque.
The sole control objective of the low-level motor control algorithm is to output torque. However, robots typically need to set position, velocity, and torque parameters for the joints, thus requiring hybrid control of the joint motors.
The joint motor from Unitree includes the following five control commands:
- Feedforward torque: πππ ;
- Desired angular position: ππππ ;
- Desired angular velocity: ππππ ;
- Position stiffness: ππ;
- Damping coefficient: ππ;
In the hybrid control of joint motors, a PD controller is used to feed back the deviation of the motor's output position into the torque output:
where π is the output torque of the motor rotor of the joint motor, π is the current angular position of the motor rotor, and π is the angular velocity of the motor rotor. In practical use of the joint motor, care should be taken to convert between the control target quantities at the motor output end and the commands sent to the motor rotor.
5. Motor Wiring Connection
We use RS-485 as the physical layer. The so-called physical layer refers to the physical phenomena used to represent and transmit information. In fact, RS-485 can be considered equivalent to a half-duplex serial port (UART).
RS-485 uses the potential difference between two wires to transmit digital levels. Typically, both wires are twisted pairs of equal length. When external interference exists, it generates noise on both wires simultaneously. After the differential signal is transmitted to the motor, it is processed by a differential operational amplifier, which subtracts the input differential levels to recover the original signal before sending it to the serial port. This gives the communication high immunity to interference.
RS-485 signal states | ||
Signal | Mark (logic 1) | Space (logic 0) |
A | Low | High |
B | High | Low |
Table: Relationship Between Differential Levels and Logic Levels
Because RS-485 data lines consist of only two wires for transmitting two differential signals representing a single level, only one direction of communication can occur on the line at any given time. This is why RS-485 is a half-duplex communication protocol. In contrast, RS-422 uses four data lines for full-duplex differential transmission. However, using RS-485 greatly simplifies cabling, improves hardware communication reliability, and reduces costs.
Typically, half-duplex communication requires a master device (host computer) to control the communication rhythm. The motion control commands sent by the host contain the target motor ID information. When each motor receives a motion control command, it checks whether the ID information matches. The motor with the matching ID will send its internal data back to the host, thus completing one communication cycle.
The N6014B-12.6 motor supports a maximum of 15 motors on a single bus (IDs 0 to 14). Motors with the same ID are not allowed on the bus; otherwise, communication on the entire bus will be abnormal. Please refer to section 6.2 for motor ID configuration.
To send motion control commands to the joint motors manufactured by Yushu Technology, the commands need to be transmitted via the serial port. The motors communicate with the host computer through the RS-485 interface, with a baud rate of 6 Mbps or 4 Mbps.

Figure 2 Motor Wiring Connection
As shown in Figure 2. The interface provided to the user uses a C (XT30(2+2) cable) connected to B (XT30(2+2) adapter board), and is connected to A (RS-485 to USB module) via D (GH1.25-3 cable), which is then connected to the computer.
When controlling the motor with your own computer, in order to send commands from the host computer to the motor, the RS-485 interface needs to be connected to the host computer via a USB-to-RS-485 adapter. After connecting the 24V DC power supply, the motorβs green indicator light will start blinking, indicating that the motor is powered on.
6.Motor Parameters
Parameter | Value |
Communication Method | 485 |
Baud Rate | 6Mbps / 4Mbps |
Data Bits | 8 |
Parity | None |
Stop Bits | 1 |
Bus Communication Polling Frequency | 10000Hz |
Supply Voltage | 24V ~ 75V |
Maximum Phase Current | 40A |
Overvoltage Protection Threshold | 85V |
Undervoltage Protection Threshold | 16V |
Minimum Operating Temperature | -20β |
Winding Overtemperature | 130β |
Driver Overtemperature Threshold | 90β |
Motor Weight | 535g |
Peak Torque (Reverse Direction) | 34.4Nm |
Peak Torque (Same Direction) | 31.7Nm |
Encoder Type | Dual Absolute Encoder |
Encoder Resolution | 15bit |
Maximum No-Load Speed | 54.2rad/s |
Reduction Ratio | 3:38 |
7.Motor Protocol
Considering that some users may use special platforms to control the motor, here we will explain how to write custom motor control programs.
Using the method described in this section, readers can send control commands to the motor and receive motor status feedback on any platform that meets the hardware requirements.
All parameters in the protocol are rotor-side data. The reduction ratio is 38/3. To convert rotor data to output-side data, it needs to be multiplied or divided by this reduction ratio.
The N6014B-12.6 motor uses serial communication with the RS-485 standard. The baud rate supports 6.0 Mbps / 4.0 Mbps. The serial port is configured as 8 data bits, no parity bit, and 1 stop bit. It should be noted that to increase the motor communication frequency, we use a high baud rate of 6.0 Mbps / 4.0 Mbps. Users need to confirm whether their own hardware supports this baud rate. If the hardware does not support it, the Unitree USB to RS-485 bus module can be used.
When controlling the motor, we send a 20-byte command to the motor via the serial port, after which the motor returns a 26-byte status message. If no command is sent to the motor, the motor will not return any status. The command format and return format are shown in the following structures, which detail the meaning of each byte. Below we explain some of the details.
First, in the command sent to the motor, the 5th and 6th bytes represent the motor feedforward torque π_ff, where 2560 corresponds to 1 NΒ·m. This means we multiply the feedforward torque value by 2560 and then assign it to a 2-byte signed short integer variable. During this assignment, rounding is forced, allowing us to transmit the feedforward torque π_ff data using only two bytes. When the motor receives this data, it simply divides it by 2560 to restore the actual value of the feedforward torque π_ff. Although this method loses some precision, it fully meets the requirements of practical applications.
Furthermore, it is important to note that for a 2-byte (16-bit) variable, 1 bit is used as the sign bit to indicate positive or negative, so only 15 bits are available to represent the magnitude of the value. This means that the value of π_ff in the command cannot exceed a certain upper limit, given that it is represented in 15 bits. Considering that we have multiplied the original data π_ff by 2560, there is a corresponding upper limit on its absolute value.
At the same time, it is important to note that due to the forced rounding operation during the assignment process, the larger the value of π_ff, the lower the decimal precision that is preserved. The phrase β2560 represents 1β mentioned in the structure variable comments actually refers to the multiplication by 2560 described above. Similar descriptions such as βxx represents 1β in other variables follow the same principle.
Furthermore, for the 2-byte π variable, the low byte comes first (i.e., byte 5), and the high byte comes after (i.e., byte 6). At the end of both the command transmission and the status reception, we see a 4-byte CRC32 checksum. Before sending the command, we calculate the pre-transmission CRC checksum of these command bytes and send it together with the command to the motor. When the motor receives the command, it also calculates the post-transmission CRC checksum based on the received command.
If no error occurs during data transmission, the pre-transmission CRC checksum equals the post-transmission CRC checksum. If a data error occurs during transmission, the calculated post-transmission CRC checksum will not match the pre-transmission CRC checksum. The motor can then detect that the data has been corrupted, thereby helping us avoid erroneous data.
Applicable Model | Reduction Ratio | Factor_Tor | Factor_Spd | Factor_Pos | Factor_Kp | Factor_Kd |
N6014B-12.6 | 38/3 | 2560 | 64/(2Ο) | 32768/(2Ο) | 12800 | 51200 |
Output-side Data and Rotor-side Data ConversionοΌ
Data Type | Conversion Relationship |
Torque (Tor) | Output = Rotor * Reduction Ratio |
Speed (Spd) | Output = Rotor / Reduction Ratio |
Position (Pos) | Output = Rotor / Reduction Ratio |
Position Stiffness (Kp) | Output = Rotor * Reduction Ratio * Reduction Ratio |
Velocity Stiffness (Kd) | Output = Rotor * Reduction Ratio * Reduction Ratio |
// Motor control command packet 20 bytes
typedef struct {
// Control command data total 20 bytes
uint8_t head[2]; // Packet header 0xFE 0xEE, participates in CRC
uint8_t id : 4; // Motor ID 0~14, 15 indicates broadcast to all motors (no response at this time)
uint8_t status : 3; // Operating mode 0: Stop 1: FOC 2~7: Reserved
uint8_t timeout : 1; // Timeout protection 0: Disabled 1: Enabled (if enabled, enters operating mode if no command received for more than 1s)
uint8_t res; // Reserved
int16_t tor_des; // Rotor feedforward torque -32768~32767 Factor_Tor indicates: 1Nm
int16_t spd_des; // Rotor target speed -32768~32767 Factor_Spd indicates: 1rad/s
int32_t pos_des; // Rotor target position -2147483648~2147483647 Factor_Pos indicates: 1 rad
int16_t k_pos; // Rotor position stiffness 0~32767 (-32768~-1 reserved) Factor_Kp indicates: 1 Nm/rad
int16_t k_spd; // Rotor speed stiffness 0~32767 (-32768~-1 reserved) Factor_Kd indicates: 1 Nm/(rad/s)
int16_t k_rcr32; // CRC32-MPEG2 note: includes packet header
} ControlData_t;
// 2-Motor return data 26 bytes
typedef struct {
uint8_t head[2]; // Packet header 0xFC 0xEE does not participate in CRC
uint8_t id:4; // Motor ID 0~14 15 reserved
uint8_t status:3; // Operating mode 0: Stop (power-on default) 1: FOC 2~7: reserved
uint8_t timeout:1; // Timeout protection 0: No timeout 1: Timeout protection triggered (needs to be cleared by control bit set to 0)
int8_t temp1; // Driver temperature -100~127 (-128~101 reserved) 1 indicates 1Β°C
int8_t temp2; // Winding temperature 0~255 1 indicates 1Β°C
uint8_t vol; // Motor terminal voltage 0~255 2 indicates 1V
int16_t torque; // Current rotor torque -32768~32767 Factor_Tor indicates: 1Nm
int16_t speed; // Current rotor speed -32768~32767 Factor_Spd indicates: 1rad/s
int32_t pos; // Current rotor position -2147483648~2147483647 Factor_Pos indicates: 1rad
uint32_t MError; // MError: 0: Normal, bitwise representation, see Table 1, status=0 (Stop) after error triggered
uint16_t RES1:13; // Reserved
uint16_t MWarning:3; // MWarning: 0: Normal, bitwise representation, see Table 2
uint16_t RES2; // Reserved
uint32_t CRC32; // CRC32-MPEG2 note: does not include packet header
} MotorData_t;
// CRC32 calculation
uint32_t CRC32_MPEG2(uint32_t *ptr, uint32_t len){
uint32_t xbit = 0;
uint32_t data = 0;
uint32_t CRC32 = 0xFFFFFFFF;
const uint32_t dwPolynomial = 0x04c11db7;
for (uint32_t i = 0; i < len; i++){
xbit = 1 << 31;
data = ptr[i];
for (uint32_t bits = 0; bits < 32; bits++){
if (CRC32 & 0x80000000){
CRC32 <<= 1;
CRC32 ^= dwPolynomial;
}
else
CRC32 <<= 1;
if (data & xbit)
CRC32 ^= dwPolynomial;
xbit >>= 1;
}
}
return CRC32;
}
8. Motor Fault Code Table
When a motor fault occurs, the corresponding error status flag will be triggered. Multiple error states can exist simultaneously. After troubleshooting and resolving the fault, the motor can be restored to normal operation by power-cycling (turning the power off and on again).
Fault Code | Bit | Description | Fault Code | Bit | Description |
0x01 | 0 | Overcurrent | 0x02 | 1 | Transient overvoltage |
0x04 | 2 | Continuous overvoltage | 0x08 | 3 | Transient undervoltage |
0x10 | 4 | Chip overheating | 0x20 | 5 | MOS overheating/undercooling |
0x40 | 6 | MOS temperature abnormal | 0x80 | 7 | Housing overheating/undercooling |
0x100 | 8 | Housing temperature abnormal | 0x200 | 9 | Winding overheating |
0x400 | 10 | Rotor encoder 1 error | 0x800 | 11 | Rotor encoder 2 error |
0x1000 | 12 | Output encoder error | 0x2000 | 13 | Stored data error |
0x4000 | 14 | Abnormal reset | 0x8000 | 15 | Main control authentication error |
0x10000 | 16 | Chip verification error | 0x20000 | 17 | Calibration mode |
0x40000 | 18 | Communication checksum error | 0x80000 | 19 | Driver version too low |
0x100000 | 20 | Firmware model error | 0x200000 | 21 | Encoder angle abnormal / Bus communication abnormal |
0x400000 | 22 | Reserved | 0x⦠| ⦠| Unknown error |
Table 1. Motor Fault Code Table
9.Warning Code Table
Warning Code | Bit | Description | Warning Code | Bit | Description |
0x01 | 0 | Low voltage power supply abnormal | 0x⦠| ⦠| Unknown warning |
Table 2. Motor Warning Code Table
β Previous
Add link here
Next β
Add link here