Sensorless BLDC motor controller using PIC18F4550 microcontroller

With PIC18F4550 8-bit microcontroller we can easily build a simple ESC (Electronic Speed Controller) for brushless DC motors. This topic shows how did I made an ESC using the PIC18F4550 microcontroller and few other components.

First the brushless dc 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.

For more details about the sensorless BLDC motor and how to control it, see the following project:
Brushless DC motor control with PIC16F887 microcontroller

Hardware Required:

  • PIC18F4550 microcontroller   —> datasheet
  • Brushless DC motor
  • 6 x 06N03LA N-type mosfet (or equivalent)  – datasheet
  • 3 x IR2101 (or IR2101S) gate driver IC  – datasheet
  • LM339 quad comparator IC
  • 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
  • 8 MHz crystal oscillator
  • 2 x 22pF ceramic capacitor
  • 10k ohm potentiometer
  • 12V source
  • 5V source
  • Breadboard
  • Jumper wires
  • PIC MCU programmer (PICkit 3, PICkit 4 …)

Sensorless BLDC motor controller using PIC18F4550 microcontroller circuit:
Circuit schematic diagram is shown below.

Brushless motor controller using PIC18F4550 ESC

Note that all grounded terminals are connected together.

As known the brushless motors are 3-phase motors. In the circuit diagram above the 3 phases are named: Phase A, Phase B and Phase C.

In this project we need two power sources, the first one with 5V and used to power the microcontroller. The other one with 12V which is used to power the three-phase bridge and therefore the BLDC motor.

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 all its 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 resistors are needed, for that I used three 10 K ohm resistors.

The outputs of the 3 comparators are connected to PIC18F4550 external interrupt pins INT0 (RB0), INT1 (RB1) and INT2 (RB2) respectively for BEMF A, BEMF B and BEMF C.

The PIC18F4550 microcontroller has one CCP (Capture/Compare/PWM) module and one ECCP (Enhanced CCP) module. The CCP module can generate one PWM signal on pin RC1. The ECCP module can generate two PWM signals on pin RD5 (full bridge reverse mode) and pin RD7 (full bridge forward mode). So with that we have 3 PWM signals which are then connected to HIN pins of the IR2101 gate drivers (pwming high side mosfets only).

In this project the PIC18F4550 microcontroller runs with 8 MHz crystal oscillator and MCLR pin function is disabled.

C Code:
The C code was tested with CCS C compiler version 5.051. The compiler may give a warning, it is not a problem at all, just ignore it!

As mentioned above the microcontroller runs with 8 MHz crystal oscillator, in the code the PLL is enabled (PLL2) which makes the CPU runs at 48 MHz (12 MIPS).

Timer2 module is configured to give a PWM signal with frequency of 46.875 KHz and resolution of 10 bits. The configuration line is:
setup_timer_2(T2_DIV_BY_1, 255, 1);
where Timer2 prescaler = 1, preload (PR2) = 255
PWM frequency and resolution can be calculated using the functions below (Fosc = 48 MHz):
PWM_freqency = Fosc/{[(PR2) + 1] * 4 * (TMR2 Prescale Value)} = 46.875 KHz
Resolution = log[4(PR2 + 1)]/log(2) = 10 bits

All PWM signals have the same frequency since they use the same timer module (Timer2).

Full C code is below with some descriptions through comments.

Finally the small video shows a simple hardware circuit of the project:

16 thoughts on “Sensorless BLDC motor controller using PIC18F4550 microcontroller”

  1. Hi team,

    Thanks for the code. In the 1st project with arduino where no potentiometer or external comparator is used then in AH_BL, BEMF_C was rising and in the project arduino with external comparator and potentiometer when AH_BL then BEMF_C was falling. Where as in this project also when AH_BL , BEMF_C is falling. Can you please explain me this part

    1. Simple Projects

      It’s related to internal comparator input pins (inverting and non-inverting inputs), see ATmega328P and PIC18F4550 datasheets!

  2. Can you tell me how to calculate the BEMF resistors ? I have a 36V motor and I can not detect the zero crossing point. The comparator output is very noisy.

    1. Simple Projects

      Since the LM339 differential input range is from 0 to 36V you can just use the ones shown in the circuit diagram.

  3. hello,i’m azizah..can i know why i cannot run this coding..the coding become fatal error..i hope you can help..i’m very urgent to use this coding

    1. Simple Projects

      Use this code with CCS C compiler, you will get some errors if you’re using MPLAB XC8 or mikroC.

Leave a Comment

Your email address will not be published. Required fields are marked *

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

Scroll to Top