Tuesday, November 25, 2014

Cd-Rom 3 phase Sensored BLDC Motor Arduino Controller

Sensored Cd-Rom BLDC Motor Control Using Arduino

BLDC (brushless dc) motors are three phase dc motors, unlike the simple dc motors the bldc motors are more difficult to control. These motors are used in many applications for examples rc airplans and rc cars.
cd rom bldc motor control

bldc motor

In this post we will see how to control cd-rom sensored BLDC motor using Arduino uno board. But first there are some things we should know in order to control the motor in easy way.
The bldc motor that we are going to use is sensored via hall effect sensors (position sensors) attached with the motor(3 sensors). Each sensor outputs digital high for 180 electrical degrees and low for the other 180 electrical degrees.these sensors are used to tell us where is the position of the motor, then when we know the position of the motor we will energize just tow windings (of three). The below figure shows how sensors outputs and the corresponding voltage applied to the motor:
bldc motor hall sensors phase waves

The motor is driven by a 3 phase bridge which contains 6 mosfets like the figure below:
bldc motor mosfet 3 phase bridge

And for the bridge I used to run the motor visit this post below:

Three Phase BLDC Motor Bridge

We can run the bldc motor in the cw or ccw rotaion but the sensor of the cw rotaion is different from the sensor of the ccw direction. The tow tables below show the sensor and the coils that activated at each phase:
BLDC motor commutation
Also for more information for the hall effect sensors and how to test it visit this link:

The complete circuit is shown below:
arduino bldc brushless dc motor control arduino code

Cd-Rom BLDC Motor Control Arduino code:
I used timer 2 interrupt every about 30ms to read the analog value and generate the corresponding pwm signal. For the pwm I used PWM.h library to generate 20KHz easily. Also in the code there are tow functions one for forward rotation and the other for the backward rotation.

#include <PWM.h>
int32_t frequency = 20000; //pwm frequency in Hz
unsigned int n = 0, timer2_initial_value, s = 0;
void setup(){
  InitTimersSafe();
  bool success = SetPinFrequencySafe(9, frequency);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(2, INPUT);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  // initialize timer2 interrupt for adc reading 
  noInterrupts();           // disable all interrupts
  TCCR2A = 0;
  TCCR2B = 0;
  timer2_initial_value = 0;  
  TCNT2 = timer2_initial_value;   // preload timer
  TCCR2B |= (1 << CS22) |(1 << CS21) | (1 << CS20); // 1024 prescaler 
  TIMSK2 |= (1 << TOIE2);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts
}
 ISR(TIMER2_OVF_vect)        // interrupt service routine 
 {
  TCNT2 = timer2_initial_value;   // preload timer
  n++;
  if (n>20){
    n = 0;
   if (s != analogRead(A0)){
   s = analogRead(A0); 
  pwmWrite(9,s/4);}}
 }
int fwd(){
   while(1){
if (digitalRead(2)==1){
    if (digitalRead(1)==0){
      if (digitalRead(0)==1){
        digitalWrite(8,0);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,1);digitalWrite(4,1);digitalWrite(3,0);}
      else {
        digitalWrite(8,1);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,1);digitalWrite(4,0);digitalWrite(3,0);}}
        
     if (digitalRead(1)==1){
      if (digitalRead(0)==0){
        digitalWrite(8,1);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,1);}}}
        
   
 if (digitalRead(2)==0){
    if (digitalRead(1)==1){
      if (digitalRead(0)==0){
        digitalWrite(8,0);digitalWrite(7,0);digitalWrite(6,1);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,1);}
      else {
        digitalWrite(8,0);digitalWrite(7,1);digitalWrite(6,1);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,0);}}
        
     if (digitalRead(1)==0){
      if (digitalRead(0)==1){
        digitalWrite(8,0);digitalWrite(7,1);digitalWrite(6,0);
        digitalWrite(5,0);digitalWrite(4,1);digitalWrite(3,0);}}}
   if (digitalRead(12)==0) break;}
}
 int bwd(){
   while(1){
if (digitalRead(2)==1){
    if (digitalRead(1)==0){
      if (digitalRead(0)==1){
        digitalWrite(8,0);digitalWrite(7,0);digitalWrite(6,1);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,1);}
      else {
        digitalWrite(8,0);digitalWrite(7,1);digitalWrite(6,1);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,0);}}
        
     if (digitalRead(1)==1){
      if (digitalRead(0)==0){
        digitalWrite(8,0);digitalWrite(7,1);digitalWrite(6,0);
        digitalWrite(5,0);digitalWrite(4,1);digitalWrite(3,0);}}}
        
   
 if (digitalRead(2)==0){
    if (digitalRead(1)==1){
      if (digitalRead(0)==0){
        digitalWrite(8,0);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,1);digitalWrite(4,1);digitalWrite(3,0);}
      else {
        digitalWrite(8,1);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,1);digitalWrite(4,0);digitalWrite(3,0);}}
        
     if (digitalRead(1)==0){
      if (digitalRead(0)==1){
        digitalWrite(8,1);digitalWrite(7,0);digitalWrite(6,0);
        digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,1);}}}
   if (digitalRead(12)==0) break;}
}
     
void loop(){
  digitalWrite(13, LOW);
  pwmWrite(9,s);
  digitalWrite(8,0);digitalWrite(7,0);digitalWrite(6,0);
  digitalWrite(5,0);digitalWrite(4,0);digitalWrite(3,0);
  if (digitalRead(10)==0) {digitalWrite(13, HIGH);bwd();}
  if (digitalRead(11)==0) {digitalWrite(13, HIGH);fwd();}
}


Cd-Rom BLDC Motor Control using Arduino video:
The following video shows my home made bldc motor controller using Arduino uno.