BLDC Motor control using Arduino | Speed control with potentiometer

The brushless dc motor is a three-phase dc motor which requires a controller to power its 3 phases. This controller is called an ESC (Electronic Speed Controller).
This topic shows how to drive a BLDC motor using Arduino where the speed is controlled with a potentiometer.

The brushless dc (BLDC) motor is a 3-phase motor comes in two main types: sensored and sensorless. The sensorless BLDC motor control technique is based on the BEMF (Back Electromotive Force) produced in the stator windings.

In this blog there are many topics show how to control sensored and sensorless brushless DC motors using Arduino and some other PIC microcontrollers.
One of these projects shows how to build a simple ESC using Arduino where the speed of the BLDC motor is controlled with two push buttons.
In this project I’m going to make the same controller but a potentiometer is used instead of the two push buttons.

Related Projects:
The following topic shows more details about the BEMF technique:
Sensorless BLDC motor control with Arduino – DIY ESC

Other BLDC motor project:
Brushless DC motor controller using Arduino and IR2101

In the above two projects, I used the Atmega328P (Arduino UNO microcontroller) internal analog comparator to detect the zero crossing events of the 3 phases, but it’s not a good idea (may give bad results) to use this comparator and the ADC module because they share the same multiplexer. So, I used an external chip which is LM339 quad comparator IC.

Hardware Required:

  • Arduino UNO board       —->    ATmega328P datasheet
  • Brushless DC motor (I’m using A2212/13T 1000KV)
  • 6 x 06N03LA N-type mosfet (or equivalent)      —->   datasheet
  • 3 x IR2101 (or IR2101S) gate driver IC             —->   datasheet
  • LM339 quad comparator IC                          —->    datasheet
  • 6 x 33k ohm resistor
  • 6 x 10k ohm resistor
  • 6 x 10 ohm resistor
  • 3 x IN4148 diode
  • 3 x 10uF capacitor
  • 3 x 2.2uF capacitor
  • 10k ohm potentiometer
  • 12V source
  • Breadboard
  • Jumper wires

In this project I’m using the motor shown below, it full name is A2212/13T 1000KV:

Quadcopter brushless motor A2212/13T 1000KV

Brushless dc motor control with Arduino circuit:
The following image shows project circuit schematic diagram.

Arduino brushless dc motor speed control circuit

All grounded terminals are connected together.

As mentioned above, the brushless dc motor is a 3-phase motor. In the circuit diagram above the 3 phases are named: Phase A, Phase B and Phase C.

The first three 33k (connected to motor phases) and the three 10k resistors are used as voltage dividers, the other three 33k resistors generate the virtual natural point.

In this project we need 3 comparators to compare the BEMF of each phase with respect to the virtual natural point because we need to detect the zero crossing of each phase, here I used the LM339 quad comparator chip. The virtual point is connected to the inverting input ( – ) of the three comparators as shown in the circuit diagram above. BEMF A is connected to the non-inverting pin ( + ) of comparator number 1, BEMF B is connected to the positive terminal of comparator 2 and BEMF C is connected to the positive terminal of comparator 3. Comparator 4 is not used and its input terminals should be grounded.

As known the comparator output is logic 1 if the non-inverting voltage is greater than the inverting voltage and vice versa.

The LM339 outputs are open collector which means a pull up resistor is needed for each output, for that I used three 10k ohm resistors.

The outputs of the 3 comparators are connected to Arduino pins 2, 3 and 4 respectively for BEMF A, BEMF B and BEMF C.
Arduino UNO pins 2, 3 and 4 are ATmega328P microcontroller external interrupt pins PCINT18, PCINT19 and PCINT20 respectively.

The IR2101 chips are used to control high side and low side mosfets of each phase. The switching between the high side and the low side is done according to the control lines HIN and LIN. The figure below shows input and output timing diagram:

IR2101 input output timing diagram

The HIN lines of the three IR2101 are connected to pins 11, 10 and 9 respectively for phase A, phase B and phase C. The Arduino UNO can generate PWM signals on that pins where only high side mosfets are PWMed.
The LIN lines are connected to Arduino pins 7, 6 and 5 respectively for phase A, phase B and phase C.

The 10k potentiometer is used to vary the speed of the BLDC motor, its output is connected to Arduino analog channel 0 (A0).

Brushless dc motor control with Arduino code:
Arduino pins 9, 10 and 11 can generate PWM signals where pin 9 and pin 10 are related to Timer1 module (OC1A and OC1B) and pin 11 is related to Timer2 module (OC2A). Both Timer modules are configured to generate a PWM signal with a frequency of about 31KHz and a resolution of 8 bits. The duty cycles of the PWM signals are updated when the ADC module completes its conversion by writing to registers OCR1A, OCR1B and OCR2A.

Rest of code is described through comments!

The following video shows my simple hardware circuit result:

16 comments

  1. Hola. Estuve viendo el circuito y me anima a hacerlo. Tengo arduino nano. Crees que puedo hacerlo igual?. Gracias por compartir Dios te bendiga.

  2. Are you sure this code is working properly?
    My notices:
    I think in CH_BL() function the TCCR1A should be 0x21;
    Why DDRD is 0x38? I think it should be 0XE0
    If you use external pullup resistor why use it internal in code?
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    pinMode(4, INPUT_PULLUP);
    You use also the PORB pullup but I think is not necessary (PORTB = 0x00; //because of internal pullup disabled)
    Can you please check it again this is the right and working code?

    1. Yes you’re right the value of DDRD which has to be 0xE0 instead of 0x38 and now it is corrected, thank you.
      Secondly, you can disable the internal pull-ups of pins: 2, 3 and 4 since they’ve external ones.
      The other thing:
      pins 9, 10 and 11 are the high side PWM signals, every time there is only 1 active, register TCCR1A controls pin 9 and pin 10 as follows:
      TCCR1A = 0; makes both of them work as any other I/O pin.
      TCCR1A = 0x21; enables PWM on pin 10 which is related to OC1B.
      TCCR1A = 0x81; enables PWM on pin 9 which is related to OC1A.

      The control line of the high side mosfet (HIN) of phase C is connected to Arduino pin 9 and its PWM is enabled when TCCR1A = 0x81.

  3. Instead of using IR2101 driver chip,can I use IR2104S.
    I have completed the project from your tutorial (https://simple-circuit.com/arduino-sensorless-bldc-motor-controller-esc/)
    As you said it gave a bad result.
    I have that IR2104S Driver IC,
    If I use that driver IC in this external comparator project,can I get a good output?
    please explain this project deatails in details.I have so many problems and questions about this project.I am doing this as my final year project.
    Please reply as soon as possible…
    thanks in advance

    1. Yes you can use the IR2104S but you’ve to do few modifications to the Arduino code, you’ll get a ‘good’ result (with external comparator IC and potentiometer).

  4. Sir…please don’t mistake me..I am weak in programming language…would you please explain me ,what are the modifications has to be done in my program to get result from IR2104 Driver IC and external comparator?…
    If you don’t have time to explain me about the code..please give me a corrected code for external comparator and IR2104 ICs…. You have much more knowledge in this topic…our staffs also doesn’t know about it…your small help in this project must make it work and help me a lot in my UG grades …..please think about my situation….thanks for every knowledge you put in my mind…you are doing really really great job…..

  5. Dear Sir, have you ever read this paper:
    IEEE TRANSACTIONS ON POWER ELECTRONICS, VOL. 22, NO. 2, MARCH 2007
    A New Cost Effective Sensorless Commutation Method for Brushless DC Motors Without
    Phase Shift Circuit and Neutral Voltage,
    Cheng-Hu Chen and Ming-Yang Cheng, Member, IEEE ?
    A more simple sensorless commutation circuit is proposed that not use the motor neutral voltage and can be easily interfaced with hall sensor based commutation circuit.

  6. Dear Simple Projects,
    Firstly, I must say that you’ve done a great work. Coincidentally, I’m working on a similar project right now and I found your work very helpful. Please, can you upload a Proteus simulation of this work? I’ve been struggling with getting the simulation right for weeks now. Thank you.

  7. Hi sir. Im trying to run this project using a bldc motor i made from a car alternator. The motor turns for about 10° and then it starts vibrating. Any idea what the problem might be ??? m using a 12v12ah for the motor drive and 15v lab power supply for the gate drivers and irf540 fets. Thanks in advance

  8. Hello I am using l6234 instead of Ir2021 I also modified the code but motor is only working when I initialize a 3ms delay in ISR. Without that delay my motor start making noise which is not good so could you please help me out what would be the issue and how it could be resolved,

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.