Skip to content

Lab 1.4. BLDC motor and CAN communication

Estimated time to complete this lab: 2 hours

Objectives

At the end of this self-learning lab, you should be able to:

  • know what is brushless DC motor
  • understand the usage of CAN bus
  • control brushless DC motor via CAN bus and ESC

Brushless DC motor

At the time of writing (2021), Brushless DC motor (BLDC motor) is the most common type of motor used in our team.

DJI M3508 N5065 Tmotor AK80
m3508 n5065 ak80_front

As their name implies, brushless DC motors do not use brushes. With brushed motors, the brushes deliver current through the commutator into the coils on the rotor. So how does a brushless motor pass current to the rotor coils? It doesn’t—because the coils are not located on the rotor. Instead, the rotor is a permanent magnet; the coils do not rotate, but are instead fixed in place on the stator. Because the coils do not move, there is no need for brushes and a commutator.

BLDC motor

With the brushed motor, rotation is achieved by controlling the magnetic fields generated by the coils on the rotor, while the magnetic field generated by the stationary magnets remains fixed. To change the rotation speed, you change the voltage for the coils. With a BLDC motor, it is the permanent magnet that rotates; rotation is achieved by changing the direction of the magnetic fields generated by the surrounding stationary coils. To control the rotation, you adjust the magnitude and direction of the current into these coils.

Since the rotor is a permanent magnet, it needs no current, eliminating the need for brushes and commutator. Current to the fixed coils is controlled from the outside.

The number of windings used in a brushless motor is called the number of phases. Though brushless motors can be constructed with different numbers of phases, three phase brushless motors are the most common. With three phases, motors can be constructed with different magnetic configurations, called poles. Higher pole counts can provide higher performance, though very high speeds are better accomplished with lower pole counts.

bldc_poles

When looking for BLDC motors, usually you will see three wires extending from the motor. These three wires correspond to the three phases in the motor (you can refer to the motors shown at the top of this lab).

Brushed DC motor

You may have heard of Brushed DC motor before in your physics class or other projects.

DC motor

Brushed DC motors normally have just two leads, one positive and one negative. If you connect these two leads directly to a battery, the motor will rotate. If you switch the leads, the motor will rotate in the opposite direction.

To control these types of motors, one can use an H-bridge (e.g. L298N, user guide, tutorial) to control the speed and direction of the motor via digital and PWM signals.

Motor wiring

Brushed motors are easier to control than Brushless motors. However, brushless motors provide longer lifetime, higher speed and acceleration and higher efficiency compared to brushed motors, so we usually use brushless motors on our robot.

BLDC Controller

The control of the individual three phases of a BLDC motor is quite complicated and advanced. What most people do to control a BLDC is use a separate circuit/board called Electronic Speed Controller (ESC). The ESC receives the motor target control (e.g. position, velocity, current) signals, then controls the motor by activating the appropriate MOSFETs to create the rotating magnetic field so that the motor rotates.

At the training level, it is not needed to understand the detailed control of the phases of the BLDC. From the programmer's perspective, the main focus should be on (1) how to communicate with the ESC, and (2) what signals to pass to the ESC. How to control the phases in a BLDC is an industrial-level topic. In fact, some more expensive motors have their own dedicated ESC to go along with them (built into the motor itself), and they have their own ways to control the phases.

The ESC has several IO that you should care about:

  • Input power supply, usually two wires (positive and negative)
  • Input control signal (e.g. CAN bus, will be discussed in following section)
  • Input motor sensor feedback (e.g. motor rotor position, motor velocity, ...)
  • Output three phase for BLDC

Below shown are several ESC commonly used in M2. Can you guess which wires/ports correspond to which functionality?

DJI C620 VESC 4.12 Tmotor AK80 (inbuilt ESC)
c620 vesc ak80_back

Section Check Box:

  • What is a BLDC motor
  • Relationship between BLDC motor and ESC

CAN

A Controller Area Network (CAN bus) is a robust vehicle bus standard designed to allow microcontrollers and devices to communicate with each other's applications without a host computer. It is a message-based protocol, designed originally for multiplex electrical wiring within automobiles to save on copper, but it can also be used in many other contexts.

CAN was invented by Bosch, in Germany, in 1983 and first used in the Mercedes-Benz W140 in 1991. Modern cars may have around seventy electronic devices: sensors and actuators, an engine management unit and an automated engine start/stop system. These rely on getting readings from sensors such as accelerometers, thermometers and gas sensors, and sending commands to actuators. Obviously, great accuracy is required and the CAN bus has a great deal of cyclic redundancy checking (CRC) built in to ensure safety. The system is robust towards electric disturbances and electromagnetic interference - ideal for safety critical applications (e.g. vehicles)

Although originally designed for use in automotive situations this bus offers a simple and inexpensive system for use in hobby electronics projects. CAN is also frequently used in M2 for communication between different MCU and computers.

The fields of a standard CAN frame

Reference

A CAN frame consists mainly of an identifier field, a control field and a data field. The control field is six bits long, the data field is zero to eight bytes long and the identifier field is 11 bits long for standard frames, or 29 bits long for extended frames.

can_frame

Identifier field

CAN transmissions operate using the producer/consumer model. When data are transmitted by a CAN device, no other devices are addressed. Instead, the content of the message is designated by an identifier field. This identifier field, which must be unique within the network, not only provides content but the priority of the message as well. All other CAN devices listen to the sender and accept only those messages of interest. This filtering of the data is accomplished using an acceptance filter which is an integral component of the CAN controller chip. Data which fail the acceptance criteria are rejected. Therefore, receiving devices consume only that data of interest from the producer.

Small data frames are used with a maximum of 8 bytes of data in each data packet. Each node has an ID number and transmission clashes on the network are dealt with by the lower priority frame backing off. Priority depends on the allocated ID given to the device. Lower ID numbers have higher priority.

Control field

  • DLC is used to specify the data length (number of bytes) in the data field.
  • IDE is used to specify the CAN standard (Standard vs Extended)
  • R0 is reserve

Data field

  • Stores the user data to be sent over the bus, can be 0-8 bytes long.

It is important to understand how to use the CAN interface in order to communicate with the ESC and other MCU used on the robot. Usually the documentation of the ESC will provide some information on how the programmer should package the CAN message to send certain commands.

Section Check Box:

  • What is CAN bus, advantages of using CAN bus
  • Important fields in a CAN frame

Implementation

Let's use an Arduino to read and write from the C620+M3508.

Things you need

  • MCP2515 CAN Controller module (MCP2515 CAN Controller IC and TJA1050 CAN Transceiver IC)
    • MCP2515 CAN Controller: Due to hardware limitations, Arduino alone does not support CAN. However, it does support SPI. The MCP2515 IC is a standalone CAN Controller and has integrated SPI Interface for communication with microcontrollers.
    • TJA1050 CAN Transceiver: A CAN transceiver is the interface between the controller and the CAN bus. The transceiver translates the logic level messages from the controller into the CAN differential scheme on the CANH and CANL pins of the CAN transceiver. The controller can be thought of as an MCU, the part of the CAN node that processes all the information to and from the CAN bus.
    • The two IC combined form the whole module. You can treat it as an "SPI to CAN converter".
  • M3508 motor
  • C620 controller
  • Suitable wires

Wiring

Please wire the components as follows:

[TODO: insert images]

Danger

You MUST notify our team members and let them check your connection circuit before turning on the power supply and proceeding with this lab. Otherwise, if there are mistakes in your wiring (e.g. short circuit, inverting positive and negative), accidents such as fire and explosion may occur and you may be injured.

Turn on the power supply. Adjust the voltage and current such that it shows "24V, 0.1A".

If the power connection is fine, you should see that a green light is flashing on the C620 controller, and some buzzing sound is emitted from the M3508 motor.

You might have to restart the power supply (perform power cycle) after adjusting the voltage and current.

Library installation

We need a library to use the MCP2515 with Arduino. Similar to the sensor library installation in the previous section, we should git clone the library into the lib directory.

You can use this library: https://github.com/autowp/arduino-mcp2515

$ cd lib
$ https://github.com/autowp/arduino-mcp2515.git

Have a look at the example code of the library under examples. You should note what important fields/functions there are and how to use them, such as setBitrate(), can_id, can_dlc, data, sendMessage().

Read data from C620

Try to modify the example code to read data from the C620. In particular, note that:

  • the CAN bitrate should be 1MHz when communicating with the C620 (you can refer to the C620 datasheet here). You can refer to mcp2515.h inside the library to check how to change the bitrate.
  • the oscillator on the MCP2515 module is 8MHz. You should specify it in setBitrate() along with the CAN bitrate. Refer to mcp2515.h on how to do this.

Note that you can only communicate with the C620 when the power supply is turned on (i.e. flashing green light).

You can consider the communication successful if you can print the bytes on your serial monitor, and that the reading changes only when the motor is moved (you can try turning the back of the M3508 motor with your hand!).

Try it yourself 1.4.1

The bytes printed on the screen can be considered as the "raw frame data". We need to extract information from it for it to become useful.

Refer to the "CAN Communication Protocol" of the C620, and look for "2. Speed Controller Sending Message Format".

  • Notice that the rotor position (the angle of the motor) is stored in the first two bytes of the data frame.
    • Try to use C++ bitwise operators to extract the rotor position. You should obtain a number from 0 to 8191. Output this number to the serial monitor. When turning the rotor with your hand, the number should be increasing/decreasing and wraparound after 8191 or below 0.
  • Notice that the motor velocity (rpm) is stored in the next two bytes of the data frame.
    • Try to use C++ bitwise operators to extract the signed rotor velocity. You need to do some special handling for the negative direction. Output the RPM to the serial monitor along with the rotor position.

Please approach our team members after you have completed the task. In your training repository, save the code into a new file named tiy-1-4-1.cpp. Commit and push the code.

Write data to C620

Try to modify the example code to write data to the C620 and move the motor. In particular, note that:

  • the CAN bitrate should be 1MHz when communicating with the C620 (you can refer to the C620 datasheet here). You can refer to mcp2515.h inside the library to check how to change the bitrate.
  • the oscillator on the MCP2515 module is 8MHz. You should specify it in setBitrate() along with the CAN bitrate. Refer to mcp2515.h on how to do this.
  • The can_id should be 0x200.

Note that you can only communicate with the C620 when the power supply is turned on (i.e. flashing green light).

Warning

If everything is right (the write communication is successful), the motor will begin to move. As the motor is quite strong and can spin quite fast, you are advised to take caution.

Try it yourself 1.4.2

Referring to the communication protocol, the first two bytes of the CAN frame refer to the motor current.

You can treat motor current as the "acceleration" of the motor.

Try to change the first two bytes of the CAN frame being written. How is the behavior of the motor different after power cycle?

While the motor is in motion, try to adjust the current (A) of the power supply. What happens?

Please approach our team members after you have completed the task. In your training repository, save the code into a new file named tiy-1-4-2.cpp. Commit and push the code.