A DC motor is a mechanically commutated electric motor powered from direct current (DC). The stator is stationary in space by definition and therefore so is its current. The current in the rotor is switched by the commutator to also be stationary in space. This is how the relative angle between the stator and rotor magnetic flux is maintained near 90 degrees, which generates the maximum torque.
Here you can find three libraries to control DC Motor using Atmega micro.
The first one (lib_dcmotor) allow you to synchronously control motor in direction.
The second one (lib_dcmotorpwm) implements a way to control motor direction and speed asynchronously, using timers, by hardware PWM capabilities of Atmega micro. The average value of voltage (and current) fed to the load is controlled by turning the switch between supply and load on and off at a fast pace. The longer the switch is on compared to the off periods, the higher the power supplied to the load is, and the more the motor spin.
The third one (lib_dcmotorpwmsoft) does exactly the things of the library above, but implements a software PWM, leaving free the hardware PWM resource for other device, or for micro that does not have PWM hardware embedded.
All libraries can control up to 2 motors, more motors can be controlled with the third one libraries using output port expander.
All libraries was developed on Eclipse, built with avr-gcc on Atmega8 @ 1MHz.
Code
Notes
- read risk disclaimer
- excuse my bad english
Thank you very much..
ReplyDeletegreat article..thank you very much :))
ReplyDelete- Flexible Shaft Couple
happy to ear this :)
Deletetks!
Your Tutorial is very instructive. It helps me a lot. Can you please post the wiring connection of the Atmega16 interfacing with the L293D?
ReplyDeletehello and thank you,
Deleteuse the schematics as above, but connect RA2 and RA3 from L293D to two port of your ATmega, then you have to change ports in the config file (.h) or the library you are using.
Thank you, i really appreciate your help.
DeleteMay God bless you.
your are welcome.
Deleteyou can find a more advanced solution (with slow start / stop for example) here: http://davidegironi.blogspot.it/2013/11/driving-dc-motor-using-software-pwm.html
This comment has been removed by the author.
ReplyDeleteTo me, the most simple way to compile, is Eclipse, with AVR plugin installed, and avrgcc as compiler.
DeleteSearch for a tutorial, you can find a lot.
i done compiling.....now sir i want to use atmega 16,,,,the diagrm is not clear...will u please upload the circuit with proper connections
ReplyDeleteHello, you just have to select two free port of your microcontroller, for each motor, setup that ports in the header file of the library. Then connect the two port stright in your motor driver (note: check your motor driver to be shure you can connect that type of input, as example: sn754410 support this type of input). You may also search online for that type of connection.
DeleteAdditional note: please do not remove your comment with my reply, or my reply to comments are useless for other users.
in this diagram i can't understand the connections,,,,,please upload the protious diagram
ReplyDeleteyour comment dosen't helping me in making the circuit....:(
ReplyDeleteYou have got an email with a schematics i've just found googling. It may be what you are looking for.
Deletehow can i control speed and direction of 2 DC Motors using atmega328 and L298N Driver by Tx and Rx??
ReplyDeleteHello have to write your own protocol, that reads byte from UART, then interpreter those byte and use a DC motor library like this http://davidegironi.blogspot.it/2013/11/driving-dc-motor-using-software-pwm.html to drive the motors.
Deletei have got 6 channel 2.4ghz flight controller of flysky which sends PPM signal..and i think L298 is a PWM based ic...how to control now??
Deletei have got 6 channel 2.4ghz flight controller of flysky which sends PPM signal..how can i control speed and direction of 2 dc motor?
ReplyDeleteYou can use the ICP of avr, or the external interrupt input. There are a few posts on avrfreaks forum about reading PPM.
DeleteThis comment has been removed by a blog administrator.
ReplyDeleteHello Davide,
ReplyDeleteGood to see your post. Its quite helpful. I have some doubt, please help me to get clear this..
In the case of Forward/Reverse motion of motor, how can I set the duty to achieve 4ms pulse.
Also I didnt understand this formula:
orctop = ((ICR1 - top_min) * (speed - 1)) / ((100 - 1) + top_min);
Is the speed means"duty" ?
Please suggest. Thanks.
Hello, thank you for your feedback. About the duty cicle question, it depends on which driver are you using, for the PWM (non bitbang version) you have to setup the timer registers, you can find settings explanation in the header file. You have to consider the duty part and the pwm frequency.
DeleteThe ocrtop settings formula is a mapping. You are basically mapping orc from min to max, given a speed from 1 to 100. Take a look here for furhter info: https://www.arduino.cc/en/Reference/Map
Hello Davide,
DeleteThanks for your reply. I configured the timer registers. My requirement is to control the bidirectional DC motor connected at Atmega8.
The initial pwm pulse is of 20KHz (50us) and later I have to set it to 4ms pulse. I can change the duty and check the pulse period (its close to 4ms) but not accurate. How can I set the condition to get the pulse of exact 4ms.
plz suggest. Thanks.
Hello, frequency is setted up by the timer definitions definitions DCMOTORPWM_ICR1 DCMOTORPWM_PRESCALER.
DeleteLook at the dcmotorpwm.h file comments on that macro. I can't understand if you have to change the duty period of the PWM frequency. Anyway, you can perform a precise frequancy and duty cycle rewriting the set speed function (dcmotorpwm_backward and dcmotorpwm_forward). You will have to set OCR1B or OCR1A to a calculated number.
Hello Davide..
DeleteLet me explain in detail:
Issue: At Atmega8(Clk: 4MHz), Using timer1, generate two PWM signals (OC1A(Fw)/OC1B(Rv)) of 20KHz(50us).
Later, external interrupt is generating while motor is running in parallel. Need to change the PWM signals of 4ms while changing its duty.
So, I defined timer in this way...
(calculated using prescalar = 1, Fast PWM mode14)
TCCR1A=(1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (0<<WGM10);
TCCR1B=(1<<WGM13) | (1<<WGM12) | (1<<CS10);
ICR1 = 199;
OCR1A = 0;
OCR1B = 0;
TIMSK = 0;
TIFR = 0;
Please suggest me, how can i set the condition to increase/decrease the duty to set the pulse of 4ms.
Thanks.
Again it's not clear to me why it will be usefull. Consider the the "standard" PWM frequancy for a motor is 20Mhz, Anyway, what you can do, is set the PWM at 250Hz. In order to change the PWM, set the ICR1 according to this. With a 4Mhz crystal you have got an ICR1 a little low to me. I will set it to 8Mhz at least, and use ICR1 = 400, with a prescaler of 1 for 20Mhz, ICR1 = 500 with a prescaler of 64 for 250Hz. Consider that 250Hz is not a good PWM for a motor.
Delete