Sunday, July 17, 2016

CD-ROM Spindle motor (BLDC) control with PIC18F4550 microcontroller


CD-ROM Sensored brushless (BLDC) motor control using PIC18F4550 microcontroller
CD DVD-ROM Spindle BLDC motor rotor removed 
This topic shows an easy way for controlling cd-rom drive (or dvd-rom) spindle motor using PIC18F4550 microcontroller.
There are different spindle motor types used in the cd-rom drives and the one used here is sensored brushless DC motor (BLDC motor), so be careful with your BLDC motor type and if it has less than 11 pins that means your motor is not concerned.
This motor is three phase motor, it has three stator phases that are excited two at a time to create arotating electric field. This method is fairly easy to implement, but to prevent the permanent magnet rotor from getting locked with the stator, the excitation on the stator must be sequenced in a specific manner while knowing the exact position of the rotor magnets.
3 Phase BLDC motor winding PIC18F4550
The sensored BLDC motor has 3 hall effect sensors (Sensor A, Sensor B and Sensor C) to sense rotor position, this sensors are placed as shown in the following picture with pinout configuration:
CD-ROM DVD-ROM Brushless DC motor (BLDC) pinout PIC18F4550
Each sensor outputs a digital high for 180 electrical degrees and outputs a digital low for the other 180 electrical degrees. The following figure shows the relationship between the sensors outputs and the required motor drive voltages for phases A, B and C.
Brushless DC motor (BLDC) hall effect sensors timing PIC18F4550
A three phase bridge is used to energize the BLDC motor windings.
Brushless DC motor (BLDC) 3 phase bridge PIC18F4550
Each phase driver requires 2 pins one for the high side and the other one for the low side which means a total of 6 pins are required to drive the three phase bridge. In this project 6 pins of PORTD will be used.
The 3 hall effect sensors needs 3 pins and for that RB4, RB5 and RB6 are used.
Two lookup tables are used for motor driver commutation according to the following two tables where table1 for direction 1 and table 2 for direction 2:
Table 1
Brushless DC motor (BLDC) direction 1 table PIC18F4550 
Rotation direction2 is accomplished by driving current through the motor coils in the direction opposite of that for rotation direction1.
 Table 2
Brushless DC motor (BLDC) direction 2 table PIC18F4550
CD-ROM sensored brushless DC (BLDC) motor speed and direction control using PIC18F4550 microcontroller:
The following image shows project circuit schematic diagram.
CD-ROM Sensored spindle Brushless DC motor (BLDC) control circuit using PIC18F4550 CCS PIC C 
In the circuit there are 3 pushbuttons connected to RB0, RB1 and RB2. The buttons connected to RB1 and RB2 are for starting the BLDC motor direction1 or direction2, and RB0 button stops the BLDC motor.
Each hall effect sensor has 4 pins:
H+ and H- : sensor power supply pins
OUT+ and OUT- : sensor output pins.
For the system power supply there is +5V and +12V. The +12V supplies the 3 phase bridge circuit which is the same as the motor supply voltage.
LM339 consists of four independent precision voltage comparators. 3 camparators are needed for the 3 hall effect sensors as shown in the circuit schematic above. LM339 needs +5V power supply voltage  which is connected as shown below:
BLDC motor with LM339 comparator PIC18F4550
74LS08 contains four independent 2-input AND gates. 3 AND gates are needed to make 3 PWM signals. The 74LS08 must be supplied with +5V as shown below:
BLDC motor with 74LS08 AND gates for PWM PIC18F4550
CD-ROM sensored brushless DC (BLDC) motor control with PIC18F4550 microcontroller CCS PIC C compiler code:
This is the full code of this project. The code is small and not complicated.
RB interrupt on change (IOC) is used to interrupt when the rotor changes its position.
A potentiometer connected to analog channel 0 is used to control the BLDC motor speed in both directions.
// CD-ROM Sensored BLDC motor control with PIC18F4550 CCS C code
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

#include <18F4550.h>
#device ADC = 10
#fuses NOMCLR HSPLL PLL2 CPUDIV1
#use delay(clock = 48000000)
#use fast_io(B)
#use fast_io(D)

int8 hall, Direction = 0;
const int8 MoveTable1[8] = {0, 33, 6, 36, 24, 9, 18, 0};
const int8 MoveTable2[8] = {0, 18, 9, 24, 36, 6, 33, 0};
#INT_EXT                                      // External interrupt ISR
void ext_isr(void){
  disable_interrupts(INT_RB);
  output_d(0);
  setup_ccp1(CCP_OFF);                        // CCP1 OFF
  Direction = 0;
  clear_interrupt(INT_EXT);
}
#INT_RB                                       // RB port interrupt on change ISR
void rb_isr(void){
  hall = (input_b() >> 4) & 7;
  if(Direction == 1)
    output_d(MoveTable1[hall]);
  else
    output_d(MoveTable2[hall]);
  clear_interrupt(INT_RB);
}
void main(){
  setup_adc_ports(AN0);                       // Configure RA0 (AN0) pin as analog
  output_b(0);                                // PORTB initial state
  set_tris_b(0xF7);                           // TRISB configurartion
  port_b_pullups(TRUE);                       // Enable PORTB internal pull-ups
  output_d(0);                                // PORTD initial state
  set_tris_d(0);                              // Configure PORTD pins as outputs
  setup_adc(ADC_CLOCK_DIV_64);                // Set ADC conversion time to 64Tosc
  set_adc_channel(0);                         // Select channel 0 input
  setup_timer_2(T2_DIV_BY_16, 250, 1);        // Timer2 configuration for PWM
  setup_ccp1(CCP_OFF);
  enable_interrupts(GLOBAL);                  // Enable global interrupts
  enable_interrupts(INT_EXT);                 // Enable external interrupt
  delay_ms(100);                              // Wait 100ms
  while(TRUE){
    if(!input(PIN_B1)){                       // If RB1 button pressed
      if(Direction == 0){
        Direction = 1;
        setup_ccp1(CCP_PWM);                  // Configure CCP1 as a PWM
        clear_interrupt(INT_RB);              // Clear RB IOC flag bit
        enable_interrupts(INT_RB);            // Enable PORTB IOC
        hall = (input_b() >> 4) & 7;
        output_d(MoveTable1[hall]);
      }
    }
    if(!input(PIN_B2)){                       // If RB1 button pressed
      if(Direction == 0){
        Direction = 2;
        setup_ccp1(CCP_PWM);                  // Configure CCP1 as a PWM
        clear_interrupt(INT_RB);              // Clear RB IOC flag bit
        enable_interrupts(INT_RB);            // Enable PORTB IOC
        hall = (input_b() >> 4) & 7;
        output_d(MoveTable2[hall]);
      }
    }
   while(Direction != 0){
     set_pwm1_duty(read_adc());
   }
  }
}

CD-ROM BLDC motor control with PIC18F4550 microcontroller:
The following video shows a hardware circuit for this project.

References:
Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957).
Microchip: Brushless DC Motor Control Made Easy (AN857).