Managing the speed and direction of a DC motor holds significant importance across various applications:
– In robotic applications, altering the speed and direction is crucial for controlling the movement of robots.
– Industrial scenarios require the ability to adjust the speed and direction of rotating machinery.
– Within domestic settings, regulating the speed of battery-operated portable fans is essential.
– Defense applications often necessitate rotating radar, automatic guns, or tank guns in different directions.
– Communication applications involve tasks such as adjusting dish antenna positions both vertically and horizontally.
Numerous applications demand altering the direction and/or speed of DC motors. The motor’s direction can be controlled by reversing the polarity of the supplied power. To regulate the speed, multiple methods exist, yet the most effective among them is Pulse Width Modulation (PWM). This technique involves adjusting the pulse width, which consequently modifies the average voltage applied to the motor, thereby altering its speed.
This project aims to illustrate the process of adjusting the speed and altering the direction of a simple 12V 500 RPM DC series motor using the AVR microcontroller ATmega32.
System block diagram:
The fundamental components of this system, depicted in the figure, comprise the ATmega32 and the DC motor driver chip L293D. Additionally, the setup requires push buttons for control purposes and LEDs for signaling. Here’s a concise description of each block:
Five push buttons are allocated for executing operations such as initiating, halting, modifying the speed, and altering the direction of the DC motor.
Button |
Function |
Button 1 | Run motor in clockwise direction |
Button 2 | Run motor in anticlockwise direction |
Button 3 | Stop motor |
Button 4 | Increase speed |
Button 5 | Decrease speed |
L293D chip – this chip takes input from micro controller and drives DC motor. The micro controller output current is not enough to drive DC motor directly. The chip has quad half H bridge drivers. It will provide up to 600 mA current to motor that is enough to drive it.
LED indications – six LEDs are used for different indications
LED |
colour |
indication |
LED 1 |
red |
Blinks when motor runs in clockwise direction |
LED 2 |
green |
Blinks when motor runs in anticlockwise direction |
LED 3 |
Blue |
Blinks when speed in increased |
LED 4 |
Orange |
Blinks when speed is decreased |
LED 5 |
red |
Lits ON when speed limit is maximum |
LED 6 |
red |
Lits ON when speed limit is minimum |
The ATmega32, an 8-bit microcontroller based on Advanced RISC architecture, boasts low power consumption and high performance capabilities. It encompasses 32 KB of in-system programmable FLASH memory and comes equipped with various built-in peripherals such as a 10-bit, 8-channel ADC, 4 PWM channels, 1 16-bit, and 2 8-bit timers/counters, USART, SPI, IIC, among others. In this particular system, the ATmega32 executes several functions:
– Continuously scans push buttons to gather user input
– Provides diverse indications using LEDs
– Controls the operation (start/stop) of a DC motor
– Modifies the motor’s direction or speed
The circuit comprises the ATmega32, L293D, and a few discrete components including LEDs, resistors, capacitors, and push buttons:
– Five push buttons, labeled as SW1 to SW5, are linked to PORTA pins PA0 to PA4. Additionally, all port pins are pulled high via external pull-up resistors, as illustrated.
– Four LEDs, identified as LED1 to LED4, are connected to PORTD pins PD0 to PD3 using current-limiting resistors.
– PORTC pins PC0 and PC1 are connected to the input of the L293D chip. Two LEDs, labeled as LED5 and LED6, are also linked to these pins via current-limiting resistors.
– The DC motor is connected to the output of the L293D chip.
– A 16 MHz crystal, along with two 22 pF capacitors, is connected to the crystal input pins XTAL1 and XTAL2.
– A 5V Vcc supply is connected to the necessary pins of both chips and pull-up resistors.
– An additional 12V supply is allocated to the L293D chip specifically for the motor’s operation.
Working & Programming
System working and operation:
· Initially, the motor remains stationary, and all LEDs are inactive.
· Upon a momentary press of SW1, the motor initiates rotation in a clockwise direction. Simultaneously, the green LED flashes at the frequency of the PWM.
· Subsequently, pressing SW4 or SW5 results in an increase or decrease in the motor’s speed. This adjustment is indicated by LED1 or LED2 blinking accordingly.
· Continued pressing of SW4 or SW5 causes a continuous increase or decrease in speed. Upon reaching the maximum or minimum limit, the corresponding LED3 or LED5 illuminates.
· While the motor rotates clockwise, pressing SW2 immediately prompts a switch to anticlockwise rotation, and vice versa.
· Pressing SW3 halts the motor’s operation.
Program:
AVR microcontrollers possess an integrated capability to produce PWM using internal timers. This feature allows for PWM generation, enabling the adjustment of a DC motor’s speed. However, not all microcontrollers offer this feature. In cases where it’s unavailable, PWM needs to be generated programmatically. In this scenario, PWM is generated using a program written in C language, compiled, and simulated using AVR Studio software. The comprehensive program comprises various functions:
– **Keydly() function:** This function generates a debounce delay of approximately 0.2 seconds required when a key is pressed.
– **Incspeed() function:** Responsible for increasing the width of the pulse supplied to the motor by extending the ON time and reducing the OFF time. It also monitors the maximum speed limit. Upon reaching the maximum speed, LED3 is activated.
– **Decspeed() function:** Decreases the width of the pulse supplied to the motor by reducing the ON time and increasing the OFF time. It also checks for the minimum speed limit. When the minimum speed is reached, LED4 is illuminated.
– **Clockwise() function:** Continuously delivers PWM to the motor to rotate it in a clockwise direction until any button is pressed.
– **Anticlockwise() function:** Provides continuous PWM to rotate the motor in an anticlockwise direction until any button is pressed.
– **Main() function:** Initializes ports as input or output and subsequently scans all buttons in a continuous loop.
Project Source Code
### #include <avr/io.h> #include <util/delay.h> uint16_t ton=5000,toff=5000; void keydly() // key debounce delay { uint8_t i; for(i=0;i<7;i++) _delay_loop_2(10000); // delay loop library function } void incspeed() // increase width of pulse { PORTD = (0<<PD3); // led indication if(toff>1000) // check for minimum off time { toff=toff-500; // if not then decrease off time ton=ton+500; // and increase on time } if(toff==1000) PORTD = (1<<PD2); // if max limit is reached - LED on } void decspeed() // decrease width of pulse { PORTD = (0<<PD2); // led indication if(ton>1000) // check for minimum on time { toff=toff+500; // if not then increase off time ton=ton-500; // and decrease on time } if(ton==1000) PORTD = (1<<PD3); // if min limit is reached – LED off } void clockwise() // rotate motor clockwise { while(PINA==0xFF) // till any key is not pressed { PORTC=0x01; // apply PWM to motor _delay_loop_2(ton); PORTC=0x00; _delay_loop_2(toff); } } void anticlockwise() // rotate motor anticlockwise { while(PINA==0xFF) // till any key is not pressed { PORTC=0x02; // apply PWM to motor _delay_loop_2(ton); PORTC=0x00; _delay_loop_2(toff); } } int main(void) { uint8_t r=0,d; // run and direction flag DDRC=0x03; // initialize ports as input and output DDRD=0x0F; DDRA=0x00; PORTC=0x00; PORTD=0x00; while(PINA==0xFF); //wait till any key is pressed loop:switch(PINA) { case 0xFE: // for 1st key keydly(); r=1; // set run flag d=0; clear direction flag for CLK direction clockwise(); // start rotating motor clockwise break; case 0xFD: // for 2nd key keydly(); r=1; // set run flag d=1; // set direction flag for ACLK direction anticlockwise(); // start rotating motor anticlockwise break; case 0xFB: // for 3rd key PORTC = 0x00; // stop motor PORTD = 0x00; // all indications off r = 0; // clear run flag Break; case 0xF7: // for 4th key PORTD=(1<<PD0); // blink LED1 keydly(); PORTD=(0<<PD0); incspeed(); // increase speed if(r==1) // if motor was running { if(d==0) clockwise(); // keep it running clockwise else anticlockwise(); // or anticlockwise } break; case 0xEF: // for 5th key PORTD=(1<<PD1); // blink LED2 keydly(); PORTD=(1<<PD1); decspeed(); // decrease speed if(r==1) // if motor was running { if(d==0) clockwise(); // keep it running else anticlockwise(); } break; } goto loop; } ###
Project Video