Sunday, September 15, 2013

A simple brushless sensored motor driver for AVR Atmega


Brushless electric motor (BLDC motors) are synchronous motors that are powered by a DC electric source via an integrated inverter/switching power supply, which produces an AC electric signal to drive the motor. Additional electronics control the inverter output amplitude and waveform (and therefore percent of DC bus usage/efficiency) and frequency (i.e. rotor speed). Because the controller must direct the rotor rotation, the controller requires some means of determining the rotor's orientation/position (relative to the stator coils). Some designs use Hall effect sensors or a rotary encoder to directly measure the rotor's position, others measure the back EMF in the undriven coils to infer the rotor position, eliminating the need for separate Hall effect sensors, and therefore are often called sensorless controllers.


The following explanation is taken from "AVR443: Sensor-based control of three phase Brushless DC motor" sheet.
Theory of operation: A three phase BLDC consists of a Stator with a number of coils. The fundamental three phase BLDC motor has three coils. Usually the three coils are referred to as U, V and W. In many motors the fundamental number of coils are replicated to have smaller rotation steps and smaller torque ripple. The rotor in a BLDC motor consists of an even number of permanent magnets. To simplify the explanation of how to operate a three-phase BLDC motor a fundamental BLDC with only three coils is considered. To make the motor rotate the coils are energized (or “activated”) in a predefined sequence, making the motor turn in one direction, say clockwise. Running the sequence in reverse order the motor run in the opposite direction. The direction of the current determines the orientation of the magnetic field generated by the coil. The magnetic field attracts and rejects the permanent magnets of the rotor. By changing the current flow in the coils and thereby the polarity of the magnetic fields at the right moment – and in the right sequence – the motor rotates. Alternation of the current flow through the coils to make the rotor turn is referred to as commutation. A three-phase BLDC motor has six states of commutation. When all six states in the commutation sequence have been performed the sequence is repeated to continue the rotation. The sequence represents a full electrical rotation. For motors with multiple poles the electrical rotation does not correspond to a mechanical rotation. A four-pole BLDC motor uses two electrical rotation cycles to per mechanical rotation. When specifying the number of Rotations Per Minute subsequently, the number of
electrical rotations is referred to unless otherwise mentioned. The most elementary commutation driving method used for BLDC motors is an on-off scheme: A coil is either conducting (in one or the other direction) or not conducting. The strength of the magnetic field determines the torque and speed of the motor. For BLDC motors the commutation control is handled by electronics. The simplest way to control the commutation is to commutate according the outputs from a set of position sensors inside the motor. Usually Hall sensors are used, but even back EMF can be used to detect the stator position. A common commutation is the one represented by the image below.


For this project, I've implemented a simple brushless sensored motor driver for AVR Atmega. The code i propose it's not perfect, and can be improved, but for the needs i had it works.

Using this library, the motor can be controlled in speed and direction (clockwise and anti-clockwise).
The running step for the motor are defined as default, anyway user can change it to fit any motor. Below you can find the commutation sequence (for clockwise and anti-clockwise rotation) i've used:


User has to setup the port used to read the hall sensor, and the port to control the FET status. Also the timer interrupt and prescaler should be setup for different running frequency.

A sample main routine is provided to help you understand how the library works.

To test this project i've used a brushless motor taken from a cd-rom, it is connected to a LM339 voltage compartor to build an encloder. You can find connection circuit below.



The power drive stage for the brushless motor is build using IRF640 mosfet and IR2101 high and low side driver. The complete schematics below:


Note that even a back EMF wiring are present there, if you just want to use hall sensor you can skip those connections. Also an external crystal is connected just to test the circuit at 16Mhz, even if tests are done at 8Mhz.

Setup parameters are contained in bldcsensored.h

This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 8MHz.

Code
Notes
  • read risk disclaimer
  • excuse my bad english

23 comments:

  1. Great! I wonder about motors without hall effect sensors - you can measure bemf using PC0-PC2 of mega in your schematics, but what is the purpose of PC5?

    ReplyDelete
    Replies
    1. the schematics above is for bemf readings too, wait two weeks and i will post a sensorless version ;)
      for sensored one you can skip PC0..2 + PC5 and resistors attached.

      Delete
  2. Great job! I'm studying Mechatronics, but in fact I haven't made any project yet. Do you think BLDCM is good for start-up? I've had it in mind before, but with your help I think, I could eventually do this.

    ReplyDelete
    Replies
    1. a bldc motor, and driver is not so simple to build, it will be a good project, but i do not know if could be a startup project due to it's difficulties.
      anyway if you start this, let me know about your progress ;)

      Delete
  3. how did you done via's in the PCB?

    ReplyDelete
    Replies
    1. i'm using matrix protorype board, just board with may holes.
      using solder, or components legs, i build perpendicular via.

      Delete
  4. Hi man, can you tell me the spec of brushless motor that you used?

    Thanks man

    ReplyDelete
    Replies
    1. it's an old floppy driver brushelss motor, i've not specs,
      i've also try it with other brushless motors for a friend of mine, but i've no specs even for those motors, no serial, no model, they are all recovered.

      Delete
    2. ok got it, my BLDC is about 24V (0,9A continous ampere, and 4A starting ampere). Can i use it to my BLDC?

      Thanks a lot

      Delete
    3. this should works, as you can see, the power stage is built on IRF640, which has +-20V Vgs maxm and 18A of continuos drain current. but i'm not expert in power stage, so, control heat temperature of the mosfets during your test, to prevent damages.

      Delete
    4. Sorry for late replying.
      Happy new year man.

      Ok got it, thanks.
      Can i change the IR2101 with another component?
      because so hard for me to find it in my country.

      Thanks a lot

      Delete
    5. yes, just use other high and low side driver.
      if you google around you can find other design for brushless power stage you can use.

      Delete
  5. Man, tell me about the type of Atmega 8 too.

    Thanks

    ReplyDelete
    Replies
    1. Mine was a standard ATmega8 PDIP, but every ATmega8 should work, it should work event on other atmega or AVR micro, but somethings needs to be ported to make it use with other micro.

      Delete
  6. Davide,
    I tried to compile this project, Using WinAVR-20100110 and eclipse kepler SR2, I got this error "bdlc.elf section .text will not fit in region text" any ideas, otherwise, awesome project!

    ReplyDelete
    Replies
    1. Hello,
      the complied hex does not fit your microcontroller memory.
      Check that libmath is linked. (add -m to avr c linker), it should fit on ATmega8, with libmath linked.

      Delete
  7. Hi Davide,

    I built the circuit, programmed the Atmega8, hooked up the motor, but no go. Where can I find the code for the sensorless version?

    ReplyDelete
    Replies
    1. this is the sensorless version: http://davidegironi.blogspot.it/2013/09/a-simple-brushless-sensorless-motor.html
      for the sensored one, at first my suggestion is to debug your hardware, the power stage, and the connection, maybe with other firmware.
      then, if the hardware works, debug your software.

      Delete
  8. hello Sir, thanks for the good offer :)
    I have a question please.
    why did you use these two function acd_getrealvref() and adc_getresistence ??
    i think you need to measure the current!!
    Thanks in advance.

    ReplyDelete
    Replies
    1. Hello, thank you for your feedback.
      I do not use the two function you write here. Those two function are part of the adc library i use. But for this project i never call none of them.

      Delete