Monday, September 30, 2013

A simple brushless sensorless 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.

For an introduction to BLDC motors, please look at my sensored motor driver post, here:

For this project, I've implemented a simple brushless sensoreless 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.

The motor can be controlled in speed and direction (clockwise and anti-clockwise).

This project use open loop startup and bemf zero crossing detection method with ADC.
Speed change can be done only when motor is not running, ADC is used during spinning phase in zc detection so it can not be used during the motor spinning, but digital speed changing can be implemented.
ZC threshold current should be defined by user depending on the motor type.

User has to setup the port used to read the the bemf current. Also the timer interrupt and prescaler should be setup for different running frequency.
The running step for the motor are defined as default, anyway user can change it to fit any motor.

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

The same test board of sensored library post is used, reported here the schamatics, for further info look at the sensored library post.

Setup parameters are contained in bldcsensorless.h

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

  • read risk disclaimer
  • excuse my bad english


  1. I was waiting for it. Great. But I don't understand smt:

    "User has to setup the port used to read the hall sensor, <...>"

    Isn't this sensorless?

    1. thank you for you feedback.
      yes, it is for sensorless motors, i made i mistake writing description here, now i've corrected this post :)

  2. Hallo! Nice job, i like your work on those bldc's with atmega8. In your two projects, witch one had the most torque on the motor: the sensored or the sensorless one? I'm interested in making a diy rc hovercraft from scraps and junked pc components for a charity purpose. Thank you!

    1. i've not measured torque force, for shure the sensored has more force on startup stage, cause input are driven by hall sensor.

  3. Hi again Davide, i'm sorry for putting noob questions but i'm a beginner in programming avr (i'm still learning the arduino), i tried to make a hex file from your Eclipse project but i couldn't find a way to do so. I also tried in Eclipse and Avr Studio but with no result. Can you please help me with that? What do i have to do to turn your project into a hex file for burning it to the atmega8? P.S.- the programmer is not an issue, i can build it in no time. Thnx

    1. No problem, just google for "Eclipse AVR tutorial" you will find some website that teach you how to build and hex file for ATmega with Eclipse. I suggest you, at first, to try building and loading a simple project, like a blinking led, then try with this one.

  4. Thanks for your effort.
    I saw the schematic and the source code for sensorless.
    When I check the source code and the schematic, I found some difference.
    For example
    To change the direction, you use the PC5 port. But the PC5 connect to on the PD0 schematic. So I'm confusing.
    I want to know what the truth is. And I want to get the schematic of the latest version. Can you send it to me?
    Have a nice day!
    Regards HYYoo

    1. Thank you for feedback, I've never noticed i've posted the wrong schematics version.
      The one you can find now in this post has correct wiring.

    2. Thank you Davide.
      Your source code is simple and excellent. So I can understand the concept for the BLDC. Also I can know how to implement it.
      As your code, for the change a speed and a direction, first stop a motor then start it. Is right? I think that the speed is changed while spin. So I just add some part as follow. is it possible?
      if(direction != directionold) { //direction changed
      potspeed = adc_read(POTSPEED_CHANNEL); //read filtered pot speed
      if(potspeed != potspeedold) {
      potspeedold = potspeed;
      uint16_t potspeedn = (long)(potspeed - 0) * (long)(100 - 0) / (long)(1024 - 0) + 0;

      Thank you!

      Regards HYYoo.

    3. thank you.
      The sensorless version of my code check the backemf by ADC continously (BLDCSENSORLESS_ADCREADSEL), ADC is always "busy". that's the reason why i prefer to read speed changes while not spinning.
      You could free the RX pin an control the speed by uart.
      You also could use other tecnique to read the backemf. Some time ago I was implementing a version that use cumulative current check, and make less use of ADC, but I've never continue on that project. I suggest you to give a try to the Takao code from, or the wii-esc project code.