Skip to content

BLDC Modular Thing

Final version

This work was finished during the 2024 Fab Academy Instructor Bootcamp in León, Spain:

Bootcamp page

Overview

Since I've learned to control brushless DC motors so well in my final project work, I thought I might make a BLDC motor control board that you can use in your projects. BLDCs can be really tricky to use with closed loop control. Hopefully this board will simplify your development with brushless motors, because they're great!

Like Baksi the robot, this board uses the SimpleFOC Arduino library.

  • Spiral 1: First I'm just going to make the board, and you can control it with any program that can send messages to a serial port.
  • Spiral 2: Then I'd like to make the board work with Modular Things.

CAD

Ok, let's start with the shape of the board. It's square and quite small. It will be tricky to fit a Xiao module, the motor driver and associated components, and the connectors for the motor and the magnetic angle sensor on it. But it should be doable, I think.

Modular Thing footprintThe Modular Thing footprint. Dimensions are in millimeters, taken from the Modular Things - Circuits repository. I'm using mirror constraints to position the holes.

Inspiration

I'm basing this design on the SimpleFOC Mini and the DRV8313 datasheet. I'm crossing out a few things from the SimpleFOC Mini schematic:

SimpleFOC MiniThe SimpleFOC Mini schematic.

Some parts of the SimpleFOC Mini schematic are crossed outLet's get rid of all non-essential parts.

The SimpleFOC Mini board is based on the reference design in the DRV8313 datasheet:

DRV8313 layout example

Here's an initial sketch of my board:

Motor driver and sensor connections

Actually, I was using the SimpleFOC Mini board in the breadboard version of my final project. The image above shows my (unfinished) first attempt at a schematic that simplifies the SimpleFOC Mini as much as possible. A few things are still missing; I need to pull up FAULT, SLEEP and RESET on the motor driver. I'm hoping that I can connect them all together to a digital pin that I'll set to HIGH. That would get rid of a few passive components on the board. I need to go over the SimpleFOC Mini schematic and add necessary components like the bulk capacitor.

I need to reference the pin numbers on the Xiao SAMD21:

Xiao pinout

Voltage problem

I ran into a problem with my final project because the DRV8313 motor driver only works at 8V and above. So I couldn't drive it directly from the USB port as I had planned. Fortunately, I had the foresight to order a step-up/step-down voltage regulator from Pololu, in case I needed to make some last-minute voltage changes. So I put the regulator module into the base of Baksi the robot, along with a 4 port USB hub, for communication with all the joints.

Voltage fix

When browsing the SimpleFOC Community forum I came across the Mosquito BLDC driver board, which uses the MS8313 motor driver, which seems to be a knockoff of the Texas Instruments DRV8313. The MS8313 datasheet is only in Chinese, but that isn't really a problem since all its functionality is a 1:1 copy of the DRV8313.

I don't like using knockoff products because I know that developing something for the first time is at least ten times harder than copying it. However, the MS8313 driver operates between 1.8V and 36V, which is perfect for my application. I guess it doesn't take much to tempt me. Now I can get rid of the expensive step-up voltage regulator and run the BLDC motor directly from the 5V USB power supply. And the pinout is identical to DRV8313!

I may also try USB-PD at some point, like this Modular Thing. I'll probably set the voltage using jumper resistors, rather than communicating with the USB-PD IC.

Now let's try to put all this together in KiCAD.

Progress

Here's the current design. Like Baksi the robot, it doesn't have current sense. I might try to add a current sense resistor or two in the next design spiral.

Progress

Current sensing!

I looked more closely at the DRV8313 datasheet and discovered that it supports current limiting using a single low side resistor connected to all the motor phases. The motor driver uses a comparator to compare the measured voltage over the resistor to a reference voltage that needs to be supplied to the driver. It's very similar to how the Toshiba TB67H451FNG,EL H-bridge handles current limiting in Yuichi's Xiao_RP2040 Dual H-Bridge board. Nice!

This isn't the kind of current sensing that you can use to enable torque control, but at least I can protect the USB port from damage. That's all I want for this board.

DRV8313 current monitor setup

The Xiao SAMD21 module has one DAC output pin, which I I'd like to use as a voltage reference for the comparator inside the motor driver. The SAMD DAC Application Note supports this plan:

A common use of DAC is to generate audio signals by connecting the DAC output to a speaker, or to generate a reference voltage; either for an external circuit or an internal peripheral such as the Analog Comparator.

Mirrored images in datasheet

I've run into a problem with the schematic for BLDC control with current sensing. The PCB view in KiCAD didn't make sense to me and I didn't understand why. Then I noticed that the motor driver IC is mirrored in the current sensing schematic as compared to the recommended layout schematic. This seems a bit inconsistent.

Since the recommended layout worked well in Baksi the robot, and the KiCAD footprint matches it, that is what I'm going to trust. Now I just need to mirror the current sensing schematic in order to be back on track.

Hand drawn schematic for current monitoringThat's better.

Trip current

I will assume that the BLDC Modular Thing will be connected to a USB 3.0 or 3.1 port, which allows a 900 mA current at 5V. Let's use an upper limit of 0.8 A, to be safe.

The motor driver has a comparator that can cut the power if the current goes over a certain threshold. Now to figure out what that threshold should be:

If I use the 0.25 Ω current resistor that we have at the lab, then I can calculate the necessary voltage on the motor driver's COMPN pin according to the DRV8313 datasheet:

\[V_{COMPN} = I_{trip} \cdot R_{sense} = 0.8\text{A} \cdot 0.25 \Omega = \underline{0.2 \text{V}}\]

The operating voltage of the SAMD21 chip in the Xiao module is supposed to be 3.3 V. I measured it to be 3.31 V. Then I can find the value that I put into the DAC with:

\[\frac{0.2 \text{V}}{3.31 \text{V}}\cdot 1024 = 61.8\]

I used the Xiao SAMD21 getting started guide to learn how to use the DAC. Then I modified the code to output a constant voltage level from pin A0:

#define DAC_PIN A0

void setup() {
  analogWriteResolution(10); // Set analog out resolution to max, 10-bits
  analogReadResolution(12); // Set analog input resolution to max, 12-bits

  Serial.begin(9600);
}

void loop() {
  // The measured USB supply voltage is 5.188 V and the IC operating voltage is 3.310 V.
  // 0.2V/3.31V * 1024 (or maybe 1023) = 61.8
  // OK, so to get the right reference voltage out of the DAC, measure the 3.3V Xiao pin and put into the formula above
  analogWrite(DAC_PIN, 62);

  float voltage = analogRead(A1) * 3.3 / 4096.0;
  Serial.println(voltage); // Print the voltage.
  delay(100); // Delay 1ms
}
And I got rock solid 0.201 V out of pin A0:

Xiao SAMD21 DACI can use the DAC instead of the voltage divider in the example circuit. That simplifies the PCB layout.

BOM

You need to order three things from three different places to make the BLDC Modular Thing:

You also need to have a Dupont connector kit at your lab (see bottom of this page).

Note

The 470 nF capacitor is recommended in the DRV8313 datasheet, but it's not in the Fab Lab inventory. Fortunately, it's only there to filter out noise in the little 3.3V regulator inside the motor driver. So you can safely use the next capacitor size above it, which is 1 uF. We'll replace the 470 nF capacitor in the next update of the design files.

Part Count
GM2804 Gimbal Motor w/Encoder 1
Xiao SAMD21 module 1
MS8313 motor driver 1
100 uF bulk capacitor with 6.3 mm diameter 1
470 nF capacitor 1
100 nF capacitor 2
10 nF capacitor 1
10 kOhm resistor 2
0.250 Ohm size 2010 resistor 1
0 Ohm jumper resistor 5
6 pin horizontal SMD pin header 1
3 pin horizontal SMD pin header 1

Design

The board uses a Xiao SAMD21 to receive angle readings from a magnetic sensor via SPI and send PWM and a few other signals to the motor driver. The schematic is based on the following example in the DRV8313 datasheet:

BLDC control with current monitoring

The motor driver has a comparator that measures the current going through the 0.250 Ohm resistor (R2 on the schematic below). If the current goes over a threshold, the motor driver shuts off.

To adjust the current threshold, you need to supply a constant voltage to the COMPN pin on the motor driver. In the example above, that's done with a voltage divider (resistors R1 and R2 in the example schematic above). We're using the DAC on the SAMD21 to supply that voltage instead.

BLDC Modular Thing schematic

Note that the MS8313 motor driver that we're using is a clone of the Texas Instruments DRV8313. The MS8313 datasheet is only available in Chinese, but that driver is functionally identical to the DRV8313, so we can use the DRV8313 datasheet instead. Why are we using a clone? Because the original DRV8313 only starts operating at 8V. So to use that we need to add a step-up regulator (This one has been used successfully). The MS8313 can operate at 5V, so we can power the motor directly from USB.

Here's the pinout of the Xiao SAMD21:

Xiao pinout

On the PCB below, all the motor driver connections are on the left side of the Xiao and all the SPI pins are on the right side. We're using socket connectors so that we can route the wires around the pads.

BLDC Modular Thing PCB

Here are more details about the development of this Thing.

Programming

Arduino code

The Arduino code is mostly based on SimpleFOC examples, with DAC and a SLEEP pin added.

Magnetic angle sensor

The AS5048 magnetic angle sensor has 14 bits of resolution. TThe SPI chip select pin on the AS5048 is connected to pin 7 on the Xiao, so the sensor is defined like this:

MagneticSensorSPI sensor = MagneticSensorSPI(7, 14);

Be careful with the SPI wires for the sensors. They should be like in the image at the top of this page. When the wires overlap, the signal sometimes gets messed up and the angle stops updating in the serial terminal. It took a little while to debug this mysterious problem. Plugging the board into a breadboard also messes with the SPI signal integrity.

This is working code that reads the magnetic angle sensor and outputs the angle in radians to the serial monitor / serial plotter:

#include <SimpleFOC.h>

// MagneticSensorSPI(chip_select_pin, bit_resolution)
MagneticSensorSPI sensor = MagneticSensorSPI(7, 14);

void setup() {
  // monitoring port
  Serial.begin(115200);

  // initialise magnetic sensor hardware
  sensor.init();

  Serial.println("Sensor ready");
  _delay(1000);
}

void loop() {
  // iterative function updating the sensor internal variables
  // this function reads the sensor hardware and 
  // has to be called before getAngle
  sensor.update();
  // display the angle and the angular velocity to the terminal
  Serial.println(sensor.getAngle());
}

Motor driver

The motor driver is connected to the Xiao like this:

IN1 on the motor driver connects to pin 3 on the Xiao
IN2 on the motor driver connects to pin 4 on the Xiao
IN3 on the motor driver connects to pin 6 on the Xiao
EN on the motor driver connects to pin 5 on the Xiao (enable)

So the BLDC motor is defined in the Arduino code like this:

BLDCMotor motor = BLDCMotor(7); // (This BLDC motor has seven pole pairs)
BLDCDriver3PWM driver = BLDCDriver3PWM(3, 4, 6, 5);

Trip current

We assume that the BLDC Modular Thing will be connected to a USB 3.0 or 3.1 port, which allows a 900 mA current at 5V. Let's use an upper limit of 0.8 A, to be safe.

The motor driver has a comparator that can cut the power if the current goes over a certain threshold. Now to figure out what that threshold should be:

If we use the 0.25 Ω current resistor that we have at the lab, then we can calculate the necessary voltage on the motor driver's COMPN pin according to the DRV8313 datasheet:

\[V_{COMPN} = I_{trip} \cdot R_{sense} = 0.8\text{A} \cdot 0.25 \Omega = \underline{0.2 \text{V}}\]

The operating voltage of the SAMD21 chip in the Xiao module is supposed to be 3.3 V. We measured it to be 3.31 V. Then we can find a value between 0 and 1023 to put into the DAC:

\[\frac{0.2 \text{V}}{3.31 \text{V}}\cdot 1024 = 61.8\]

We used the Xiao SAMD21 getting started guide to learn how to use the DAC. Here's the code.

#define DAC_PIN A0
void setup() {
  analogWriteResolution(10);
  analogWrite(DAC_PIN, 62);
}

That's all you need to send a rock solid voltage of 0.2V to the COMPN pin on the motor driver.

SLEEP pin

Inside the void setup() loop, we set the SLEEP pin on the motor driver to HIGH to wake it up:

  pinMode(1, OUTPUT);
  digitalWrite(1, HIGH);

The rest of the code is built from examples in the SimpleFOC library.

Setting up the sensor

Setting up the motor (contains info on zeroing)

JavaScript code

Jake and Quentin explained the Javascript needed to make a new Modular Thing in a video call. Jake has recently updated Modular Things to make it easier to make new modules.