Project 1 - Controlling a DC motor using PWM and monitoring its Running status
AIM:
To Implement a system on the simulator for controlling a DC motor using L293 motor driver, monitor its status and print the running status of motor on the LCD Display.
Goals:
- Implement a system on simulator for Controlling the DC motor using L293 motor driver.
- Displaying the running status of DC motor on the LCD display.
Key Highlights of the Project:
- The DC motor can be controlled by using L293 motor driver.
- The speed of a DC motor can be controlled by varying its input voltage, for doing this is to use PWM (Pulse Width Modulation).
- L293D IC is a typical Motor Driver IC which allows the DC motor to drive on any direction.
Deliverables of this project:
- Implement the system for controlling DC motor.
- Controlling the speed of the DC motor using PMW.
- Displaying the present running status of DC machine on LCD display.
PROGRAM:
#include <avr/io.h> // i/0 registers //
#include "avr/interrupt.h" // external interrupt //
#define F_CPU 16000000ul // CPU frequency //
#include <util/delay.h> // delay function //
#define sw_dir (PIND & (1<<1)) // configuring d1 as switch for direction control //
#define sw_spd (PIND & (1<<2)) // configuring d2 as pushbutton for direction control //
#define pwr (PINC & (1<<3)) // configuring c3 as switch to power the motor //
#define lcd_port PORTB // configuring port b for LCD //
#define RS_high PORTD |= (1<<6) // configuring d5 as register select //
#define RS_low PORTD &= ~(1<<6)
#define EN_high PORTD |= (1<<5) // configuring d6 as enable //
#define EN_low PORTD &= ~(1<<5)
unsigned char i; // variable for changing the duty cycle //
void lcd_cmd (char cmd) // command mode //
{
lcd_port = (cmd & 0xf0); // masking 4 bits for 4 bit LCD mode //
RS_low;
EN_low;
_delay_ms(1);
EN_high;
lcd_port = ((cmd<<4) & (0xf0));
RS_low;
EN_low;
_delay_ms(1);
EN_high;
}
void lcd_data (char data) // data mode //
{
lcd_port = (data & 0xf0); // masking 4 bits for 4 bit LCD mode //
RS_high;
EN_low;
_delay_ms(1);
EN_high;
lcd_port = ((data<<4) & (0xf0));
RS_high;
EN_low;
_delay_ms(1);
EN_high;
}
void lcd_init()
{
lcd_cmd(0x02);_delay_ms(5); // return home //
lcd_cmd(0x01);_delay_ms(5); // clear screen //
lcd_cmd(0x0C);_delay_ms(5); // display ON cursor OFF //
lcd_cmd(0x06);_delay_ms(5); // increment cursor //
lcd_cmd(0x80);_delay_ms(5); // force cursor to begin in 1st line //
lcd_cmd(0x28);_delay_ms(5); // for 4 bit LCD mode //
}
void cursorpos(char x, char y) // cursor position //
{
if( (x < 1 || x > 2) || (y < 1 || y > 16) )
{
x = 1;
y = 1;
}
if(x == 1)
lcd_cmd(0x7f + y);
else
lcd_cmd(0xBF + y);
}
void lcd_print(char row, char coloumn, unsigned int value, int digits)
{
unsigned int temp;
unsigned int unit;
unsigned int tens;
unsigned int hundred;
unsigned int thousand;
unsigned int million;
unsigned char flag=0;
if(row==0||coloumn==0)
{
cursorpos(1,1);
}
else
{
cursorpos(row,coloumn);
}
if(digits==5|| flag==1)
{
million=value/10000+48;
lcd_data(million);
flag=1;
}
if(digits==4 || flag==1)
{
temp = value/1000;
thousand = temp%10 +48;
lcd_data(thousand);
flag=1;
}
if(digits==3 || flag==1)
{
temp = value/100;
hundred = temp%10 +48;
lcd_data(hundred);
flag=1;
}
if(digits==2 || flag==1)
{
temp = value/10;
tens= temp%10 +48;
lcd_data(tens);
flag=1;
}
if(digits==1 || flag==1)
{
unit = value%10 + 48;
lcd_data(unit);
}
if(digits>5)
{
lcd_data('e');
}
}
void lcd_out(char x, char y, char *str)
{
cursorpos(x,y);
while(*str)
{
lcd_data(*str);
str++;
}
}
int main(void)
{
DDRB = 0xFF; // configuring all 8 pins of port b as outputs //
DDRA |= ((1<<0)|(1<<1)); // configuring a0 and a1 as outputs //
DDRD &= ~(1<<1); // configuring d1 as input //
DDRD &= ~(1<<2); // configuring d2 as input //
DDRD |= (1<<5); // configuring d5 as output //
DDRD |= (1<<6); // configuring d6 as output //
DDRC &= ~(1<<3); // configuring c3 as input //
PORTD |= (1<<2); // enabling internal pull up resistor for d2 //
PORTC |= (1<<3); // enabling internal pull up resistor for c3 //
i = 64;
TCCR0 = 0x61; // non-inverting mode, PWM phase correct mode with no prescalar //
GICR = (1<<INT0); // using INT0 for interrupt //
MCUCR = 0x02; // configuring interrupt negative edge triggered //
sei(); // enable global interrupt //
lcd_init(); // initialization //
while (1)
{
while (pwr == 0) // while power switch remains closed //
{
if (sw_dir == 0) // if direction control switch is open //
{
PORTA = 0b00000001; // 0, 1 to 1A and 2A to rotate the motor in clockwise //
lcd_out(1,1, "Motor runs in ");
lcd_out(2,2, "Clockwise");
}
OCR0 = i; // as i increases in ISR, corresponding value is assigned to OCR0 //
}
while (sw_dir == 0)
{
if(sw_dir == 0)
{
PORTA = 0b00000010; // 1, 0 to 1A and 2A to rotate the motor in anti-clockwise //
lcd_out(1,1, "Motor runs in ");
lcd_out(2,2, "Anticlockwise");
}
}
PORTA = 0x00; // 0, 0 to 1A and 2A to stop the motor //
lcd_out (1,1, "Motor is OFF ");
lcd_out (2,2, " ");
}
}
ISR(INT0_vect) // interrupt service routine //
{
i = i + 20; // as i increases by 20 with each push, duty cycle value increases //
}
RESULT:
CASE 1:
The Motor is in OFF Condition.

CASE 2:
The Motor Runs in Clockwise Direction.

CASE 3:
The Motor Runs in Anticlockwise Direction.

Expected Outcomes:
- Implement a system on simulator to control a DC motor using PMW
- Monitoring the running status of the DC motor using L293 motor driver which allows the DC motor to drive on any direction.
- Running status i.e. on which direction the DC motor is running is to be displayed on the LCD screen.