Breadboard an Arduino Controlled BLDC Motor Driver

Preview:

  • An Arduino is used to control a BLDC motor via a DIY breadboarded driver. This guide includes hardware as well as minimalist code.

  • A three-phase H-bridge is required. Variable speed is obtained via PWM of the high-side MOSFETs.

  • A trapezoidal drive is used where the commutation is dependent on the state of the motor’s Hall effects sensors.

  • The build is challenging but well worth the effort to enhance your construction and troubleshooting skills.

Introduction

The Brushless DC Motor (BLDC) is a common device featured in a wide range of products from power tools, quadcopters, servo motors, and even home appliances such as washing machines. The typical implementation consists of two parts including the motor itself and the three-phase motor drive. This article presents the DIY Arduino-based motor controller as shown in Figure 1. This minimalist breadboard design allows you to explore both the hardware and software associated with a BLDC motor.

Figure 1: The Arduino controlled three-phase H-bridge is in the foreground with a BLDC motor and Digilent Analog Discovery Pro (ADP2230) in the background.

SAFETY: Protect your PC by disconnecting the Computer’s USB port whenever 15 VDC supply is activated. This protects against an inadvertent connection between the 15 VDC supply and any Arduino pin.

Failure to heed this warning could result in the destruction of your PC’s USB port, processor, or motherboard.

Instead, power the Arduino from an independent source such as a low-cost cell phone charger. Additionally, you may also wish to purchase a USB port isolator to protect your PC.

This article describes an Arduino-based drive system to control a BLDC motor. It features a simple trapezoidal control system based on rotor position feedback derived from optical Hall sensors. This article is the seventh in a series. You are encouraged to read the introductory material especially the description of the bootstrapped Infineon (Internation Rectifier) IR2110PBF driver. Also, be sure to explore the operation of the Quadrature encoder with optical (simulated) Hall effects sensors. This prerequisite material is essential to understanding the operation of a BLDC motor.

What is a BLDC motor?

Recall that the common DC motor contains three essential components including the armature, commutator/brush assembly, and permanent magnets for the field. Torque is developed as the armature’s electro field interacts with the stator’s permanent field.

The commutator and brush assembly are key components in a DC motor as they commutate current to the armature windings. Together, the brushes and the commutator form a mechanical switch providing current of correct polarity to the armature windings.

The Brushless DC motor (BLDC) is closely related to the DC motor. At the most fundamental level, we describe a DC motor as a machine featuring electromechanically commutation the brushes and commutator. The BLDC motor is similar however, it featured electronic commutation via a drive unit featuring MOSFETs or IGBTs. In both cases, the commutation depends on knowing the precise shaft location. This is a given in the DC machine as the brushes are directly connected to the armature. The electronic for the BLDC machine senses the shaft’s rotational position.

Technically, the BLDC motor is a synchronous three-phase machine featuring a permanent magnet rotor. The motor may be designed as an inrunner with permanent magnets in the rotor or an outrunner with the permanent magnets on the external rotor. Most quadcopter motors are built as outrunner with the large exterior rotor. Most servo motors are built as innunners. The coil-on-the-outside construction provides an excellent way to dissipate heat.

Tech Tip: There are multiple ways to perform the commutation on a BLDC motor including open loop, physical Hall effect sensors, optical encoders to mimic the Hall sensor, and detection of the motor’s back EMF. Motors with physical sensing allow control at slow speeds, including holding torque when the rotor is stationary.

BLDC Motor H-bridge

A three-phase H-bridge as shown in Figure 1 is used to drive the motor coils. It consists of three bridge arms as described in the previous articles, most closely related to the full H-bridge as described in this article. Other than the commutation process described in the next section, there is little more to say about the physical circuitry that has not already been explored in the introductory articles.

BLDC motor commutation

Commutation for the featured BLDC motor begins with the etched disk as shown in Figure 2. The six states have been identified. This is a 3-bit Gray code where one, and only one, bit changes at any given time. The sequence is identified as 001, 011, 010, 110, 100, 101 repeating. This pattern is reflected in the Figure 3 Hall data (upper three traces in the logic analyzer display). It is also reflected in the code listing found later in this article.
Recall that the Hall sensors identify the rotor’s physical position. This is not an arbitrary position but one aligned with the motor’s phase coils. In a previous article we show that the Hall sensors are aligned with the motor’s phase windings. There is a Hall sensor rising edge transition coincident with the electrical zero crossing for each of the motor’s phases.

We cannot overemphasize this point: The Hall sensors identify the position of the rotor. With this knowledge we can activate the correct phase winding at the correct time.

Tech Tip: You may recognize the Gray code from your Karnnaugh maps. A single bit change occurs as we move from step to step.

Figure 2: Close up image showing the encoder’s interrupt disk. The orange lines identify the transition points for the phase slots.

Tech Tip: Proper activation (commutation) of the phase coils with respect to the armatures rotational position is essential for smooth operation. Commutation errors will result in a slipped pole causing significant mechanical and electrical stress to the system.

Commutation evaluation

In an ideal world, we would use a three-phase sinusoid signal to the motor. Unfortunately, that technique is complex and outside the scope of this introductory article. Instead, we will use the trapezoidal control for the three phases as shown in Figure 3. The technique is relatively simple as the commutation is based entirely on the motor’s three Hall sensors.

Knowing that the Hall sensors provide a repeating 001, 011, 010, 110, 100, 101 sequence for each electrical cycle, we can construct a state machine to activate the correct coils. The result is shown in Figure 3. Observe:

  • The three drive signals are shown in the upper oscilloscope representation. Observe that a phase output may be held low, floating within the bounds of the flyback diodes (high impedance), or actively controlled via a PWM. The active low portions are easily identified, as are the active PWM. The high impedance states appear as hazy trapezoidal-like ramps.

  • At any given point, one high-side MOSFET and one low-side MOSFET is active. We apply a PWM signal to the high-side MOSFET and a steady on signal to the low-side MOSFET.

  • There is a reoccurring pattern in the diagram where things move up and to the right. For example, we start on the left with PWM for Phase C (green). Moving up and to the right we PWM phase B (blue). Later we PWM phase C (Orange).

  • The bridge drive signals are shown as the lower 6 traces in the logic analyzer display. Three signals for PWM control of the high-side MOSFET, and three signal for control of the low-side MOSFET. These directly correspond, in time with the phase outputs form the upper oscilloscope display.

  • The phase outputs are associated with the hall sensors. This diagram suggests an inversion such that the falling edge of the first Hall sensor corresponds to the positive zero crossing of the A phase.

  • The program is not optimized. We can see the slight delay between a change in Hall sensor to the corresponding change in drive signals.

Figure 3: Waveforms associate with the operational BLDC driver including phase drive (top), the three Hall sensor, and the six MOSFET drive signals.

Code

The code for the demonstration circuit is shown below. It is relatively straightforward Arduino implementation with a few exceptions.

  • PWM techniques are used for the Arduino Nano Every. The PWM must be operated faster than default for smooth control of the motor speed as shown in Video 1. Note that the default Arduino PWM of approximately 1 kHz is nearly the same as motor’s electrical frequency. Way too slow.

  • The interrupts have been turned off using the cli( ) function and the code is never allowed to leave the loop( ) function. While these changes break, or otherwise impair Arduino functionality, they are necessary for the Arduino to keep up with the motor.

The core of the code is a switch on the variable hall. This follows the repeating 001, 011, 010, 110, 100, 101 sequence to activate the correct H-bridge driver.

Video 1: The BLDC motor readily responds to changes in the setpoint potentiometer.

/**** CAUTION ****  **** CAUTION ****  **** CAUTION ****  **** CAUTION ****  **** CAUTION ****
 *
 * This code is written specifically for an Arduino Nano Every. It will NOT work on other Arduino
 * microcontrollers as it depends on direct SFR manipulation to operate in a fast PWM mode.
 * For fast PWM technique refer to https://forum.digikey.com/t/fast-pwm-for-the-arduino-nano-every/40023
 *
 */

#define AL_PIN 10  // Phase A
#define AH_PIN 9   // PWM

#define BL_PIN 7  // Phase B
#define BH_PIN 6  // PWM

#define CL_PIN 4  // Phase C
#define CH_PIN 3  // PWM

#define H3_PIN 18  // Hall sensor inputs
#define H2_PIN 19
#define H1_PIN 20

#define VREF_PIN A7  // Duty cycle setpoint

#define MAX_PWM_VAL 250

void setup( ) {

TCA0.SINGLE.CTRLA = 0b00000011;  // All PWM to 32 kHz (ATMega4809 specific SFR)

  pinMode(AL_PIN, OUTPUT);
  pinMode(AH_PIN, OUTPUT);
  pinMode(BL_PIN, OUTPUT);
  pinMode(BH_PIN, OUTPUT);
  pinMode(CL_PIN, OUTPUT);
  pinMode(CH_PIN, OUTPUT);

  pinMode(H3_PIN, INPUT);
  pinMode(H2_PIN, INPUT);
  pinMode(H1_PIN, INPUT);

}

void loop( ) {

  cli( ); // Disable interrupts

  while (1) {

    static uint8_t last_hall, last_D;

    uint16_t setpoint = analogRead(VREF_PIN);

    uint8_t D = setpoint >> 2;
    if (D > MAX_PWM_VAL) {
      D = MAX_PWM_VAL;
    }

    uint8_t hall = 0x00;
    hall = hall + digitalRead(H3_PIN);
    hall = hall << 1;
    hall = hall + digitalRead(H2_PIN);
    hall = hall << 1;
    hall = hall + digitalRead(H1_PIN);

    if ((hall != last_hall) || (D != last_D)) {

      if (hall != last_hall) {   // All off for new commutation
        analogWrite(AH_PIN, 0);  // Upper PWM drivers off
        analogWrite(BH_PIN, 0);
        analogWrite(CH_PIN, 0);
      }

      last_hall = hall;
      last_D = D;

      switch (hall) {

        case 0b001:
          digitalWrite(AL_PIN, LOW);
          digitalWrite(BL_PIN, LOW);
          digitalWrite(CL_PIN, HIGH);
          analogWrite(AH_PIN, D);
          break;

        case 0b011:
          digitalWrite(AL_PIN, LOW);
          digitalWrite(BL_PIN, LOW);
          digitalWrite(CL_PIN, HIGH);
          analogWrite(BH_PIN, D);
          break;

        case 0b010:
          digitalWrite(BL_PIN, LOW);
          digitalWrite(CL_PIN, LOW);
          digitalWrite(AL_PIN, HIGH);
          analogWrite(BH_PIN, D);
          break;

        case 0b110:
          digitalWrite(BL_PIN, LOW);
          digitalWrite(CL_PIN, LOW);
          digitalWrite(AL_PIN, HIGH);
          analogWrite(CH_PIN, D);
          break;

        case 0b100:
          digitalWrite(AL_PIN, LOW);
          digitalWrite(CL_PIN, LOW);
          digitalWrite(BL_PIN, HIGH);
          analogWrite(CH_PIN, D);
          break;

        case 0b101:
          digitalWrite(AL_PIN, LOW);
          digitalWrite(CL_PIN, LOW);
          digitalWrite(BL_PIN, HIGH);
          analogWrite(AH_PIN, D);
          break;

        default:
          while (1) ;  // should never get here
          break;
      }
    }
  }
}

Next steps

This article serves as a brief introduction to motor control. There are many ways to increase your knowledge:

  • Modify the code to allow the motor to operate in either direction.

  • Incorporate the quadrature encoder for fine position and velocity control.

  • Program the ATmega4809 using bare metal techniques for improved performance. A few examples include:

    • change the motor drive I/O by directly setting the port registers
    • use an interrupt on change technique to set the drive I/O
  • Switch to an advanced microcontroller specifically designed for three-phase motor control.

  • Incorporate a current detection mechanism to mitigate overloads and short circuits.

  • Design control algorithms for full position and velocity control including controlled acceleration via S-curves.

  • Experiment with the modern MOSFET/IGBT drivers. Recall that the featured IRF2110PBF is over 30 years old and not recommended for new designs.

  • Design your own PCB.

  • Purchase a Commercial Off the Shelf (COTS) motor drive and explore applications. As a capstone challenge, design a dancer apparatus that can quickly transfer toilet paper from one role to another. Here the term dancer implies a mechanical arm that will tension and provide feedback to the mechanism to ensure consistent tension without breaking the paper.

  • Above all, enjoy the learning journey.

Parting thoughts

We have demonstrated that a BLDC motor drive may be constructed on a breadboard. It may then be controlled using an Arduino microcontroller, while staying (mostly) within the bounds of the Arduino language.

Get ready, as this project will push your breadboarding and troubleshooting skills to the next level. It’s not yet at the Ben Eater pinnacle, but it’s getting close. Expect to burn a few MOSFETs and motor drivers ICs. Also, did you read the opening safety message? Protect your valuable equipment, as a mistake could destroy your Arduino or your PC – such is the nature of experimenting with power electronics.

Best wishes,

APDahlen

Related information

Please follow these links to related and useful information:

About this author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians. Dahlen has returned to his Northern Minnesota home and thoroughly enjoys researching and writing articles such as this.

1 Like