The easiest way to control a sensorless BLDC motor is through an ESC (Electronic Speed Controller). This topic shows how to drive a BLDC motor using an ESC and PIC16F887 microcontroller.
Topics related to this post:
PIC16F887 Timers and Interrupts
The basic components of the ESC is a microcontroller and at least 6 mosfets. It also consists of other components such as voltage regulator, capacitors, resistors ..... The controlling of the ESC is similar to the controlling of servo motor, the ESC controls the speed of the BLDC motor while the servo motor controller controls the position (moving angle) of a DC motor.
To drive the ESC or servo motor we've to provide a repeated 50Hz PWM signal (20 ms period) with a duty cycle between 5 and 10% (1 ms to 2 ms pulse). The following figure shows the PWM signal needed by the ESC:
Hardware Required:
- PIC16F887 microcontroller
- ESC (Electronic Speed Controller) __ I used 30A ESC
- Brushless DC motor __ I used 2210 - 1000KV BLDC motor
- 10K ohm potentiometer
- Breadboard
- Battery (or high power 12V source)
- Jumper wires
The two thick wires black and red are the ESC input power which normally comes from a battery (11.1V, 14.8V ....). There are also 3 thick wires which are black, red and brown (in my ESC white). The black and red are 5V voltage source which can be used to supply the microcontroller circuit as what I have done, or the microcontroller circuit can be supplied from an other source and in this case the red wire will not be used. The brown wire is the PWM signal wire and this wire is used to send PWM pulses from the microcontroller to the ESC through pin RD0.
In my hardware circuit I replaced the battery with 12V 10A DC voltage source.
The potentiometer which is connected to RA0 is used to control the speed of the BLDC motor.
In this example the PIC16F887 uses its internal oscillator and MCLR pin function is disabled.
Sensorless brushless DC motor drive with an ESC and PIC16F887 CCS C code:
Timer1 module is used to measure pulses width, it's configured to increment every 1 us.
/* Sensorless brushless DC motor drive with an ESC and PIC16F887 CCS PIC C code PIC16F887 runs with 8MHz internal oscillator http://ccspicc.blogspot.com/ electronnote@gmail.com */ #include <16F887.h> #device ADC = 10 #fuses NOMCLR, NOBROWNOUT, NOLVP, INTRC_IO #use delay(clock = 8MHz) #use fast_io(D) int16 i; void main(){ setup_oscillator(OSC_8MHZ); // Set internal oscillator to 8MHz output_d(0); set_tris_d(0); // Configure PORTD pins as outputs setup_adc(ADC_CLOCK_INTERNAL); // ADC module uses its internal oscillator setup_adc_ports(sAN0); // Configure AN0 as analog input pin set_adc_channel(0); setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); // Setup Timer1 module: internal source + 2 prescaler while(TRUE){ set_timer1(0); // Set Timer1 value to 0 output_high(PIN_D0); i = read_adc(); // Read analog value from channel 0 and store it in 'i' if(i > 1000) i = 1000; i = i + 1000; while(get_timer1() < i); output_low(PIN_D0); while(get_timer1() < 19999); } }Example video: