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

65 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
  9. hi
    i need a file hex for atmega8 , because i can't compile from avr GCC .thanks

    ReplyDelete
    Replies
    1. Send me an email, i will replay with the ATmega8 hex attachment.

      Delete
    2. my mail anthony300688@gmail.com

      i need a file hex for sensorles and a file hex for sensored .
      thank o much

      Delete
  10. seem it has bug, It have to stop when Pot 5K has value = 0, I tested it , it always run when i power for circuit although i turn Pot min

    and if signal from hall sensor wrong , it don't stop , continues driver FET wrong then burn FET .

    ReplyDelete
    Replies
    1. It is not the bug, if you look at the code, that's the way it is works, when the pot is set to zero, it continues running at the lowest speed. Also, connecto sensor in the right way, or the driver may overheat mosfet. Remember that this is a basic driver, you can edit the code, and compile it again with your changes. For more advanced driver the SimonK can be your choice.

      Delete
  11. i know firmware Simonk for multicopter. But it is sensorless and have to use a circuit create signal PPM to it work.

    your firmware is simple and easy to use . You can change code to it stop when POT is zero ? i'm not a coder, i can't. Plz

    ReplyDelete
    Replies
    1. Simonk will work even attached to sensored motor, just do not attach your sensor wires.
      Regard the code change, I'm sorry but you have to do it by yourself. Here i can help you, but i can not make you work, image if i do this for you, i have to do this for all the people who ask...

      Delete
    2. Ohh , no .I need use motor have sensor,

      Plz think again , any information that you can help me , send to my mail .
      thanks

      Delete
    3. Ok.
      Check that changes http://pastebin.com/fXRP0Fdu
      Made changes to the main.c, just changed the main loop to stop the motor when the posts is under a certain threshold.
      Than compile. For compile, check some online tutorial about avrgcc compiling, i suggest you to take a look to Eclipse and the AVR plugin for Eclipse, to me it is the simpler way to compile an uploade avr code using avrgcc.

      Delete
  12. Greetings , sir. I need .hex file for simulation in Proteus. Can you help me out?
    Thank you.

    ReplyDelete
    Replies
    1. For compile, check some online tutorial about avrgcc compiling, i suggest you to take a look to Eclipse and the AVR plugin for Eclipse, to me it is the simpler way to compile an uploade avr code using avrgcc.
      If you just want the hex, i can give you a compiled hex for Atmega8 @ 8Mhz, this case, tell me your email address.

      Delete
    2. Sir, I am new to avr . I was using arduino before. The zip file that you have provided has got 4 files and out of those, which one should I use for simulation? Then what about the other files? Do I need to copy them to some other folder or so?
      Thank You

      Delete
    3. All the files are needed for the project to run. You just have to compile those files, and link them. You can use makefile or any other avrgcc compatible ide.
      As a first project on avr, i must admit that a brushless driver is pretty complex, you'd better before setup your toolchain, and play with your toolchain, blink a led, test ADC, test timers.. and so on.. then you could pass to something more complex, but this is just my opinion.

      Delete
  13. Sir, I got the program compiled in AVR studio 5.1 to get the hex file but when I used your circuit and given .hex file to simulate in proteus. I am getting the error message as timestep too small. What can I do for the same?
    Thanks

    ReplyDelete
    Replies
    1. The timestep too small is a proteus message, i suppose you have to ask proteus forum this question.

      Delete
  14. hi God bless the mans like you that help people :-)
    I live in Iran and i could't find IR2101.can i replace it whit some thing else? please tell me lot of Thanx

    ReplyDelete
    Replies
    1. There are a few way to drive MOSFET, the one i proposed here use the IR2101. But you could also use other High and Low Side Driver that could work.Something like the FAN7382 has similar characteristics. You could also change the power zone from my schematics, if you look here you will find usefull information about the power driver for bldc motors: https://code.google.com/p/qut-brushless-controller/wiki/mosfetdrive

      Delete
  15. Hi again,i cant work with WINAVR,i just tried CODEVISION.this is my E mail:
    watersez4000@gmail.com
    please send me the HEX file for both sensored and sensorless .lot of Thanx again

    ReplyDelete
    Replies
    1. thanx a lot.hope to i be useful for you too :-)in any way :-)

      i invite you to my house in Iran and your wellcome :-)

      Delete
    2. I really appriciate this. Thank you ;)

      Delete
    3. hi davide.what if i want to control the speed with an external pulse?
      to use this kind of motor in a robot?

      Delete
    4. You can do that think, just write your own input library, get the speed control, ad set the motor speed by using the set speed method provied with this library.

      Delete
    5. but the problem is here that i don't even know what i expect from the micro.please tell me what i should do with micro? what must be the out puts from micro to the IR2101 ic :-(

      Delete
    6. The IR2101 is just a high low side driver, what controls the motor, is what the microcontroller sends to it. If you would like a PWM input, you can use any free microcontroller port, and program it as PWM input port, but you have to write your own code. If you take a look to avrfreaks forum, ther you can find some posts about how to threat PWM input.

      Delete
  16. i can write my own program in CODEVISION with C, if i know the performance.what are the pulses to give to IR2101 .both HIN and LIN .lot of thanx

    ReplyDelete
    Replies
    1. The pulse to IR2101 are the 6 phase pulses (UVW), that you can see above in this post. Also, a better driver should use PWM to drive the motor. I've another driver library which works with PWM and soon i will post it.
      Keep in mind that a brushless driver is not a simple think, or at least, is not the think i will suggest someone to start with using microcontrollers.
      There are a few white papers, and tutorial that teach how a bldc motor works. At first read that ones.
      Anyway, for a much performance driver, my choice in the Atmel world, would be use the SimonK assembler driver, mounted on an ESC board. And other microcontroller to govern the ESC board and so the motor.

      Delete
    2. hi.so much thanx .i've done this before .here is the video.take a look at it: http://youtu.be/gppPOxElImY

      but as i said in video,the motor does't spin properly ,and also i want to use MOSFET.i made a simple pulses that are only different in 120 degrees and nothing similar to your pulses :-(((

      Delete
    3. the pulses i gave to motor coils are exactly the pulses in this page that you named them "H1,H2,H3"
      but i think these are for the hall efect sensors :-(

      Delete
    4. ha .......i got it.the idea is that to make a SINE wave with DC current as much as it's possible :-) right?

      Delete
    5. Nice work.
      Power stage: as you tell, it is better to use MOSFET for your power stage, you can even use a simple NPN to drive the mosfet if you can get IR2101 or other high low side driver.
      Pulse send: MOSFET has to be set on/off at correct time, so you have to read the motor position, and then power the mosfet respect that position. If you simply use a timer and do not read the motor position, that will not make the motor spin well.
      For a SINE wave, you need: a) turn the MOSFET on and off at right time respect the motor position, so get the motor position, and emit the correct phase number; b) do that in PWM, i.e. do not turn on one MOSFET and leave it on until the next phase, but use PWM even for on/off driving of the FETs.
      Said that, the driver i propose here are simple driver, that do not use PWM, so you will not get a good sine wave from my driver. The other one i've worked in, but i've not released yes, does PWM.
      Also note that i'm not an expert on bldc motor, if you are looking for a better driver, you should look at an RC community, because driver for the ESC board are developed for performance on RC, like the SimonK one, or wii-esc, or the Takao Shimizu code for arduino.

      Delete
  17. Hello,
    I am using Atmega32 to control the speed of a motor which i coded in atmel studio and simulated in proteus. I now need to drive a 3 phase motor for which I guess your driver circuit will be useful. I have used 2 buttons to increase and decrease the speed. I am somewhat confused with the coding. I need to sense the hall sensors and then drive the motor at a speed which can be altered. I have used variables in the on and off state currently to vary the speed which is working ok. I hope you could help me with some ideas to generate the PWM1 PWM2 and PWM3 so that i could drive the 3 phase motor. my load is actually a 250 W motor but i am planning to currently test on a CDrom motor. I also need to measure the rpm of the motor. I am looking forward for your help.

    ReplyDelete
    Replies
    1. Hello, for a 250W motor i would opt for a PWM motor driver, the driver i propose here are simple driver, that do not use PWM. Anyway it could work if well configured. The code indeed is a pretty simple loop. Also the power stage schematic proposed here is not able to drive a 250W motor, you have to design a more accurate power stage for that motor power. To make the code works on ATmega32 you should change some registers, TIMER etc.. but it will not be so difficult.

      Delete
    2. How can i develop a more accurate power stage motor? Can you guide me into it?
      I am thinking to first test in a CD_ROM motor. I am taking your project as a reference though. Since i have to drive a 250 watt motor and put some more fancy features like LCD and all, i chose the ATmega 32 microcontroller. Please guide me to make a more accurate power driver.

      Delete
    3. I tried to simulate the circuit, but the motor ran very slow. How can i make it run faster?

      Delete
  18. I am finding it difficult to actually determine the active mosfet h-bridge and l-bridge configurations based on the hall sensors input..
    I can see you have 10-01-00 (UVW) fet outputs for 100CW
    but i find 10-00-01 for 100CW. Is it that we could use the configurations for either of the U,V or W having the same patterns or does it has something different to do here? Thanks

    ReplyDelete
    Replies
    1. The sequence i've proposed works for my test motor. It depends on your motor type and how it is wired. Generic commutation can be found in Microchip AN857 app note, or Atmel AVR194 app note, or other app notes.

      Delete
    2. does the bldcsensored getspeed function reads the speed of the motor?
      If so, how?
      If not, how can we do that?

      Delete
    3. That function read the speed from 0 to 100 unit of the motor, not the rpm. If you need to read rpm, you have to add an hall sensor, and setup a timer to read, like it is done in this winding machine: http://davidegironi.blogspot.it/2014/05/a-pickup-winding-machine-built-on.html

      Delete