Archive for December 15, 2013

Closing the Loop

Here is the motor that I’ll be using. I don’t know if I mentioned this already, but I’ve got a big bag of these things. I don’t know where they originally come from, and I can’t find any sort of datasheet or description on the internet.

 

But that’s okay. I can work around that. I didn’t even know what kind of motors they were until I poked around with a multimeter. Turns out they’re brushless DC motors, which is pretty cool for both accurate positioning and speed, but relatively difficult to control.

Here’s the pinout, from left to right:

BLDC Pinout

  1. Winding A
  2. Hall Effect sensor A
  3. Winding B
  4. Hall Effect sensor ground
  5. Winding C
  6. Hall Effect sensor B
  7. Hall Effect sensor power
  8. Hall Effect sensor C

Finding the windings was easy, I just checked the resistance between pins. My highly sophisticated method for finding the sensor pins, though, was putting a voltage across them and watching for smoke. I guessed wrong the first time, so, uh, make that three motors I’ve sacrificed, all told.

The output on the Hall sensors(powered by 3v) are very low, so they need to be hooked up with a differential amp to a potentiometer. The motors draw about 800mA at full load.

Because I have a whole bunch of these motors, I’ve been doing research for the absolute cheapest way of controlling these. Most of the controllers chips I’ve found are right around the $15, which is ridiculous.

So I built a quick test protoboard because it was cleaner than a breadboard, but it ended up getting a little complicated.

 BLDC protoboard

How I’ve got it right now:

Closed loop BLDC motor control
Closed loop BLDC motor control

¬†While building this, I finally found an affordable solution, the MC33035. It was about $2. But hey, at least I’m intimately familiar with these motors in a way that a one-chip solution wouldn’t give me, right?

Here’s the test-code for PIC that I wrote. I still have maybe 30 of these motors, so they definitely could come into play in future projects. So, one-chip solution aside, I’d add forward/reverse control, PWM speed, and potentially speed/position feedback so I could include a PID loop. That would be pretty cool.

#include <htc.h>
//Int osc, wdt disabled, mclr disabled, bor, fscm
__CONFIG(0x3F1B);
#ifndef _XTAL_FREQ
 #define _XTAL_FREQ 96000
#endif
//HALL EFFECT
#define PHALLA RA0
#define PHALLB RA1
#define PHALLC RA2
#define SENSEA RB5
#define SENSEB RB4
#define SENSEC RB3
void forward(void) {

    //AC', AB', B'C, A'C, A'B, BC'
    if(PHALLA == 0 && PHALLB == 0 && PHALLC == 1) { //Step 1
        PITCHA = 1;
        PITCHC = 0;
        ENB = 0;
        ENA = 1;
    } else if (PHALLA == 0 && PHALLB == 1 && PHALLC == 1) { //Step 2
        PITCHA = 1;
        PITCHB = 0;
        ENB = 1;
        ENC = 0;
    } else if (PHALLA == 0 && PHALLB == 1 && PHALLC == 0) { //Step 3
        PITCHC = 1;
        PITCHB = 0;
        ENA = 0;
        ENC = 1;
    } else if (PHALLA == 1 && PHALLB == 1 && PHALLC == 0) { //Step 4 
        PITCHC = 1;
        PITCHA = 0;
        ENB = 0;
        ENA = 0;
    } else if (PHALLA == 1 && PHALLB == 0 && PHALLC == 0) { //Step 5
        PITCHB = 1;
        PITCHA = 0;
        ENC = 0;
        ENB = 1;
    } else if (PHALLA == 1 && PHALLB == 0 && PHALLC == 1) { //Step 6 
        PITCHB = 1;
        PITCHC = 0;
        ENA = 0;
        ENC = 0;
    } 
    SENSEA = ~PHALLA;
    SENSEB = ~PHALLB;
    SENSEC = ~PHALLC;

}
void main(void){
    ADCON1 = 0x07; //disable ADC
    CMCON = 0x07;
    TRISC = 0x00; //Port C Tris output
    TRISB = 0x00; //Port B Tris output
    TRISA = 0xFF; //Port A Tris input 

    while(1){
        forward();
    }
}