Electronic – HDD Motor Spinning

brushless-dc-motorpic

I'm trying to run a hdd motor using the following link. http://theamateurprogrammer.blogspot.hk/2014/02/revitalizing-old-hard-drive-motors.html

Instead of using Audrino I'm using PIC16F73.I tried to recreate the code in MPLAB but I couldn't convert micros() function. Therefore I am trying to create the waveform shown as in figenter image description here

But I couldn't calculate the correct time period for switching. I have included my switching code.

PORTBbits.RB0 = 1;
   PORTBbits.RB1 = 0;
   PORTBbits.RB2 = 0;
   Delay_x100uS(45);

   PORTBbits.RB0 = 1;
   PORTBbits.RB1 = 1;
   PORTBbits.RB2 = 0;
   Delay_x100uS(15);


    PORTBbits.RB0 = 0;
   PORTBbits.RB1 = 1;
   PORTBbits.RB2 = 0;
     Delay_x100uS(45);

     PORTBbits.RB0 = 0;
   PORTBbits.RB1 = 1;
   PORTBbits.RB2 = 1;
   Delay_x100uS(15);


    PORTBbits.RB0 = 0;
   PORTBbits.RB1 = 0;
   PORTBbits.RB2 = 1;
    Delay_x100uS(45);

     PORTBbits.RB0 = 1;
   PORTBbits.RB1 = 0;
   PORTBbits.RB2 = 1;
   Delay_x100uS(15);

What should be the correct switching time?

Best Answer

The base waveform can be divided into 6 points, each point with the same delay between them. The length of that delay defines the speed of the motor.

enter image description here

The 6 points, or phases are:

  1. Phase A HIGH
  2. Phase C LOW
  3. Phase B HIGH
  4. Phase A LOW
  5. Phase C HIGH
  6. Phase B LOW

You notice the sequence of phases is repeated, but the signals inverted. Basically it's 3 square waves with a 120° phase shift.

Here's another way of looking at it - as a circle split into 6 segments, each segment defining a changed signal level (the signal changes at the interfaces to each segment):

enter image description here

As you work around the circle so the motor turns.

If I were then to create concentric rings for each of the three phases you can see better how then then turn on and off and interact with each other:

enter image description here

You can see from that how three coils A B and C located A at 3:00, B at 7:30 and C at 10:30 (90°, 210° and 330°) the interaction between them forms 6 distinct locations - when A is on the magnet is pulled to A, when B is on, it's pulled to B, but when both A and B are on it's pulled to half-way between them.

In reality a motor would often have multiples of 3 coils forming multiples of 6 points around the circle, increasing the torque, smoothness of rotation, etc.

So your code would actually be much simpler as far as the switching goes:

PORTBbits.RB0 = 1;  // Phase 1
Delay_x100uS(speed);
PORTBbuts.RB2 = 0;  // Phase 2
Delay_x100uS(speed);
PORTBbuts.RB1 = 1;  // Phase 3
Delay_x100uS(speed);
PORTBbits.RB0 = 0;  // Phase 4
Delay_x100uS(speed);
PORTBbuts.RB2 = 1;  // Phase 5
Delay_x100uS(speed);
PORTBbuts.RB1 = 0;  // Phase 6
Delay_x100uS(speed);

What value should "speed" be? As I said, that defines the speed of rotation of the motor. I would suggest starting with a high value so the motor starts off slow, then gradually decreasing it, thus accelerating the motor to a higher speed. Maybe tie the value to an analogue input and use a potentiometer to set the speed?