Shopping Cart

Posts

Advanced brushless DC motor controller

BLDC rev.0

BLDC rev.0

I got pretty tired of coding recently and had to switch my brain to something as distant from USB protocol as possible. Also, I’ve being planning a quadcopter build for which I need a motor controller less basic than PPM-driven R/C electronic speed controller AKA ESC. I needed something fast, reliable and scalable and at the same time not too hard to understand. After studying several existing open source designs I decided to make my own. This article is a status report of testing the initial prototype of sensorless brushless DC motor controller.

The prototype can be seen in the middle of the title picture (click on it to make it bigger). The green board contains a controller ( Allegro A4960 ) plus power stage – 6 N-type MOSFETS. In addition to performing typical control functions – setting speed and direction of 3-phase brushless sensorless DC motor, this controller also has a tachometer and fault indicator outputs as well as number of configuration registers available via SPI interface. The controller IC consists of 2 main functional blocks – a logical interface and power bridge driver. The former is compatible with 3.3V and 5V logic and the latter is specified in 5.5V-50V range (startup is possible from as low as 6V), making it suitable for projects ranging from 2S LiPo-powered models to electric scooter drives.

Here is a brief explanation of controller operation. First of all, both logic and motor voltages must be present. Then, a RUN bit must be set to “1″ in RUN register using SPI – this is a safety feature which prevents uncontrolled start-ups. After that, when PWM signal is present, controller initiates start-up sequence commutating motor windings in open loop. When sensorless commutation is achieved, current to the motor is supplied according to PWM duty cycle.

Open loop start-up can be tricky, especially if a motor is heavily loaded. Even though I have had no issues starting several different motors on the bench using default power-up settings, if necessary start-up hold, timing, and ramp settings can be changed. Overall, 3 config registers are allocated for start-up parameters. Other 3 config registers hold less useful blank time, dead time, as well as current limit and internal PWM values.

The RUN register contains some very interesting settings. First of all, it holds RUN, DIR and BRAKE bits used for start/stop, direction change and braking. It is also possible to route different diagnostic signals to DIAG output pin. The most useful part of this register is phase advance angle setting. Adjusting its value according to speed/load conditions can significantly increase motor power output.

In addition to all this A4960 IC provides extensive diagnostic. Loss of sync, two-level high case temperature flags, gate drive undervoltage, as well as MOSFET faults are recorded in Diagnostic register and can be used to stop the controller. Also, other situations which can be harmful for power bridge are tracked and if something bad happens controller switches to fail-safe mode.

All this plus a number of other features make this controller ideal for builders implementing advanced motor control. I had a lot of fun playing with settings while observing how they change the motor behaviour. The first prototype is performing very well, delivering good power while staying cool. At the moment, I don’t have any numbers – I learned very quickly that a propeller makes poor (and painful) bench load and is hard to make measurements. I’m now waiting for parts to make a proper load and re-routing the board to fix the errors and add features – aiming at 100A/phase.

Stay tuned!

Oleg.

No related posts.

74 comments to Advanced brushless DC motor controller

  • Kevin Groce

    Awesome project Oleg!

  • Markus

    That looks like a really cool project Oleg. I’d love to try the A4960 myself – would you be interested in sharing your prototype board (design or physical prototype if you have spares)?

  • hhanff

    Hi! We are using the a4960 and I have observed an undocumented behaviour. To ensure that the problem does not lie within I my code, I would like to know if you too had do the following to change the direction of the BLDC motor:
    (i) Transmit RUN register with disabled RUN bit
    (ii) Transmit RUN register with toggled DIR bit
    (iii) Transmit RUN register with ENabled RUN bit

    • I haven’t tried to switch directions on the running motor. Maybe the start sequence times out too fast? Try to disable the timeout (don’t remember the bit name).

  • uhallgeo

    Oleg-

    I am playing with the A4960 too. It is driving me crazy. It will not reliably start my motor. Sometimes it runs my motor, sometimes it doesn’t. When it doesn’t, the DIAG register reports a 0xC000, a POR (power on reset). When it does run the motor, the DIAG reports a 0x823F.

    I am driving the A4960 with a C8051F310 with a 3.3vDC VDD, but running the A4960 at 5vDC does make things better.

    I feel as if I’m doing something fundamentally wrong. However I have followed the reference design.

    Do you have any suggestions???

  • uhallgeo

    Oleg-

    Running the A4960 at 5vDC does NOT make things better. (Sorry about my typing.)

    • IIRC you need to set RSC bit so controller would keep trying to open-loop after timeout (or any other loss of BEMF sync. I can stop the motor by hand and it will start in open-loop ). POR is always set after power-on, you need to read the register once to clear it.

  • uhallgeo

    Oleg-

    Spot on! Thanks!!

    Are you running your A4960 VDD at 5vDC or 3.3vDC??

    • I only tried logic part at 5V. Motor should be 6 or more to function. Also, the A4960 is quite sensitive to voltage sags on motor power rail. I was unable to reliably start even small motor off of 6A bench supply and had to run 3S LiPo in parallel to it.

  • Vitalii

    Hi!
    I develop new controller for brushless BLDC motor (the same as you use).
    But my goal is to manage motors on low rotation speeds with microstepping.
    So, I want use this kind of motors as stepper.
    It’s interesting for different goals because while I use BLDC instead of stepper, I have effect like magnetic levitation, which make movements smoother.

    If you interested in, we can start work together.
    If not, please, give me a help with it.
    because now my biggest issue is to chouse right controller for motor.

    Thanks!

  • paolo_s46

    hello! this is a request for help/suggestions. I have an arduino usb shield and its library. What I want to do is to collect the data from the meteo station oregon wmrs200. I know the protocol to decode the data, what I want to know is how to get the stream of reports of 8 bytes from which extract the info. I do not need descriptors and other conplex things. I started with the example USBHID_desc and I get just a page, and stop. I am quite an usb novice !!
    is this the right place to post this request ??

  • yarden

    hey oleg, how did you know which values of parameters to send the driver in order to start up the motor?
    did you use any considerations?

  • Awesome project Oleg,

    I’m wondering if you could offer sharing for arduino code and the A4960 schematic? I’m building an opensource electric bicycle. Currently I work for the battery protection and charger, but I would love to include, in a near futur, the motor controller ;)

    Cheers,
    Olivier

  • Ed Beamon

    I need help finding a simple circuit i can build out of old electronics to run a hard drive motor with a battery

  • Hello. I’m working in a project of a brushless using the same controller, A4960, but I’m having problems to make it work. Please, can you send the arduino code to me?

    Thanks and congratulations for the project

    • #include <SPI.h>
       
      const int slaveSelectPin = 9;
       
      uint8_t pwm = 20;
       
      #define PWM 3
      #define STATUS_DLY 2000
       
      void setup(){
       
        pinMode ( 10, OUTPUT);
        pinMode (slaveSelectPin, OUTPUT);
       
        TCCR2B = TCCR2B & 0b11111000 | 0x01;
       
        pinMode( PWM, OUTPUT );
        analogWrite( PWM, pwm );
        digitalWrite(10,HIGH);
       
        SPI.begin();
        SPI.setClockDivider(SPI_CLOCK_DIV4);
       
       
        Serial.begin(115200);
        Serial.println(F("Start"));
       
          // take the SS pin low to select the chip:
        digitalWrite(10,LOW);
        //  send in the address and value via SPI:
        SPI.transfer(0xf0);
        SPI.transfer(0x39);
        // take the SS pin high to de-select the chip:
        digitalWrite(10,HIGH); 
      }
       
      void loop() {
       
       
        uint8_t tmp;
        static uint32_t dly;
       
        if( Serial.available() > 0 ) {
          tmp = Serial.read();
       
          switch( tmp ) {
            case 'u':
              analogWrite( PWM, ++pwm );
              Serial.println( pwm );
              break;
       
            case 'd':
               analogWrite( PWM, --pwm );
               Serial.println( pwm );
               break;
          }
        } 
       
        if(dly < millis()) {
          dly = millis() + STATUS_DLY;
          Serial.print(F("Status: "));
           digitalWrite(10,LOW);
          Serial.print(SPI.transfer(0xf0), HEX);
          Serial.print(F(" "));
          Serial.print(SPI.transfer(0x39), HEX);
          Serial.println(F(""));
          digitalWrite(10,HIGH);
        }
      /*  
        uint8_t tmp;
       
        delay(5000);
        Serial.println(F(""));
       
            // take the SS pin low to select the chip:
        digitalWrite(10,LOW);
        //  send in the address and value via SPI:
        tmp = SPI.transfer(0xf0);
        Serial.print(tmp, HEX);
        Serial.print(F(" "));
        tmp = SPI.transfer(0x39);
        Serial.print(tmp, HEX);
          // take the SS pin high to de-select the chip:
        digitalWrite(10,HIGH); 
       
      */
       
      }
  • Hey, thanks for the code. It’s very simple.
    And, I’d like to as for one more thing.
    Could you sent the schematic to my email? I’m having problems to make my board works, and have already tryed everything in the code. Maybe I have a hardware problem.

  • Y.S.

    Hello Oleg:

    Could you share us the complete circuit diagram? Please and thanks.

  • Y.S.

    Hmmm, I read the datasheet by myself before, but I just cannot really understand it. (http://www.allegromicro.com/Products/Motor-Driver-And-Interface-ICs/Brushless-DC-Motor-Drivers/~/media/Files/Datasheets/A4960-Datasheet.ashx)

    I am not good at electronics X_X

    Anyway, thanks for your replying.

  • Niklas

    Hi Oleg!

    Im wondering if it’s possible to look at your schematic on your BLDC controller, im currently working on the same chip for a quadcopter ESC.

    Regards

  • Niklas

    Ok, but cant you drive a less Amp motor(10A) with your setup or is it only for 100A motors?

    Do you think theese N-Fet’s will work ?
    http://www.st.com/internet/analog/product/219669.jsp

    • You can but it’s going to be too expensive. Any MOSFET will work as long as specs are not exceeded. At this time, I don’t understand this controller well enough to offer any advice on components.

  • Niklas

    Ok Oleg, thank you anyway for your time on this.

    Regards Niklas

  • markP

    Oleg, Quick question. What value caps did you end up using for Cboot and Creg?

  • Thomas

    Hello Oleg,
    What frequency do you use for the PWM-input of A4960?
    Regards, Thomas

  • Thomas

    And what’s about the config register? In your code, you’ve posted above you only set the DG1, DG0, RSC and RUN bits. Do you initialize the other registers somewhere else?

  • Thomas

    Feel free to copy my header-file for A4960:

    http://pastebin.com/dQA79wxf

    Regards, Thomas

  • Thomas

    Hysteresis was wrong. heres the new one:
    http://pastebin.com/Ac8RbhAD

  • Augusto

    Hi !

    I’m working on a project that involves the A4960 and it’s giving me a lot of trouble. The brushless is having problems to start runing. First I thougt it was the program, by the way, I’m using a PIC 18F1220, I saw your code and mine is no diffrent (in the main code) so I think It could be the schematic that is wrong.I did use the one shown in the datasheet but i steel don’t see what is wrong. Would you please send your schematic file to me ? So I can see if/what is wrong with my project.

    Thanks a lot !

  • Hi Oleg,

    i am going to build my own A4960 Application, also aiming for up to 100A. I wonder what R sense Value you’ve chosen for the CSP/CSM resistor. My calculations result in a tremendous small Value, about 0.01OHM and lower.

    Regards,
    Michael

  • Thomas

    Hello Oleg!

    At the motor-start – what do you get from A4960 on SDO?

    Because my motor is running, but if I set the run-reg I get 0xC000 on the SDO, what means a power-on-reset.
    One reason for a POR could be, that the Vdd voltage drops under Vdduv. But since I’ve decoupled it with 100nF to Ground this can’t be the reason. I’ve also measured Vdd and it’s stable on 3V3.

    Do you (or anybody else) have an idea?

    Regards,
    Thomas

  • Hi Oleg. Very good project. I will tried to do It. What N-Mosfets have used?

    Regards,
    Jaume Nogues

  • nathaya

    hai oleg sir,
    I am working on a project with brushless dc motor control using arduino … and i am having some problem to drive the motor…sir can u suggest a program including that sensor positon(reference papper AN00857, microchip)

  • khs

    hi
    I just want to run bldc motor in open loop mode. Does controller is required for open loop operation and if yes which controller should I prefer

  • Damian

    Hello Oleg
    Can you give me complette code and schematic of your project ? ;)
    J can try build bldc driver to quadrocopter based on A4960 and J can’t find any practical materials of this topic :<
    Sorry for my bad english (I come from Poland :) )

  • Al B

    Oleg,

    You should try to build your prototype as an Arduino shield since so far I have not been able to find one that can control BLDC motors.

  • Mehrshd

    Nice info.
    I was thinking to designe an ESC with 4960 and IMO there is not enough and detiled informtion about it.
    Now I am turning to dspic33fj based controller with reluctance startup.
    I have finished the dsp based and 4960 based pcbs but after reading this topic I will consentrate on dsp based.

  • Mehrshad

    Dear Oleg,

    What will happen if we START the chip when motor is turning?
    In RC ESCs when brake is off, they can run the motor on the fly.Can this chip do that?or motor should be stopped before starting?
    Did you ever test this?

    • The controller senses back EMF to time energizing of the windings. I tried to start the controller while the motor was spinning – it seems that in this case a startup open-loop swithching is skipped. It also initiates the startup when I stop the spinning motor, e.g., by hand.

  • Mehrshd

    Thanks a lot Oleg,

    It was very helpful for me.
    My target application is a 200A/34V ESC for large scale RC car.(PCBs are ready)
    The start up quality and time is very important for me. do you think it will do the job by tuning the startup parameters?
    Thanks in advance,
    Ali

  • Mehrshad

    You are right but large inrunner motors for RC car applications are sensorless.(Like one I have)
    I am designing a dsp based controller at the same time and I think the reluctance method will do the job better.
    A custom design is more flexible and of course more difficult!
    The dealer says that the moq of 4960 is 5pcs and 25$ each!!!!(Unfortunately there is no official distributor for electronic parts in Iran )
    Thats why I am going to be sure about the performance of the chip before my order.
    Finally thanks for helping me to find out the best solution.
    Ali

  • JoãoF

    Hello, Oleg!

    Thanks for this amazing job.
    I’m trying to make my project work with your code, but my motor doesn’t move at all. All I keep getting at the Serial Monitor is “Status: 80 0″, even when I don’t power the circuit with the 11.8V Battery.
    How did you connect your Arduino with the A4960 interface?

    On my Arduino Mega 2560, I’m using MOSI pin (51) as SDI; MISO (50) as SDO; SCK (52) as SCK; Pin 10 as STRN; and Pin 3 as the PWM signal output.

    Thanks in advance.

  • JoãoF

    Thanks! But just another thing:
    Did you connect the TACHO (pin 7) from A4960 to any pin on your Arduino?
    Thanks in advance.

  • cuukee

    I made same A4960 module with same UNO board.
    but motor doesn’t work.
    I receive serial like this,

    Status: 80 0

    I cann’t find my faults.. How can I make like Oleg’s one..
    Oleg god, do you guess something?
    I always start RESETN to low during 4us for reset faults, then high. else source is same with commented Oleg’s.
    DIAG and TACHO pins is not connected.
    I connected only SPI(4wires) and PWM and RESETN.

  • cuukee

    Oleg, I made it. It works. I love you. thanks so.

  • claytoncn

    Hi Oleg, thanks for your great work on the A4960 bldc driver, how did you deal with the exposed pad, shoul we tie it to GND or just make it float(not connected), this just made me confused. Thanks for your reply :)

Leave a Reply

  

  

  



You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">