Project 1 - Controlling a DC motor using PWM and monitoring its Running status
OFFLINE BATCH
Project 1 - Controlling a DC motor using PWM and monitoring its Running status
Overview of the Project:
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.
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.
CODE :
/*
* GccApplication6.cpp
*
* Created: 11/26/2022 10:09:04 AM
* Author : HP
*/
#include <avr/io.h> //avr library
#define F_CPU 16000000L //CPU Frequency
#include <util/delay.h> //library to give delay
#include "avr/interrupt.h" //library to add interrupt
#define sw_dir (PIND&(1<<1)) //direction change switch to D1
#define sw_spd (PIND&(1<<2)) //speed control switch to D2
#define pw (PINC&(1<<3)) //Power switch to C3
#define RS_high PORTD |= (1<<5) //object macro for PORTD0 set
#define RS_low PORTD &=~ (1<<5) //object macro for PORTD0 reset
#define EN_high PORTD |= (1<<6) //object macro for PORTD1 set
#define EN_low PORTD &=~ (1<<6) //object macro for PORTD1 reset
#define lcdport PORTB //LCD connected PORTB
void lcd_command(unsigned char cmd);
void lcd_data(unsigned char dat);
void lcd_init();
void cursorpos(char X,char Y);
void lcd_print(char row,char coloumn,unsigned int value,int digits);
void lcd_out(char x,char y,char *str);
int adc_read(char channel);
unsigned char i;
int main(void)
{
//enable all PORTC Output pins to interface with LCD 16x2
DDRB=0xFF;
//enable A0 and A1 to interface with L293 Motor driver
DDRA|=((1<<0)|(1<<1));
//enable D1 as input for direction switch
DDRD&=~(1<<1);
//enable D2 as input for speed switch INT0
DDRD&=~(1<<2);
//enable D5 for LCD reset and D6 for LCD enable pin
DDRD|=(1<<5);
DDRD|=(1<<6);
//enable B3 as for PWM to the driver
DDRC&=~(1<<3);
//pullup PORTD2 pin for speed switch
PORTD|=(1<<2);
//pullup PORTB4 pin for power switch
PORTC|=(1<<3);
//declare the PWM as 25%
i=64;
//non inverting PWM phase correct Mode, no prescaler
TCCR0=0x61;
//enable global interrupt pin INT0
GICR=(1<<INT0);
//enable interrupt negative edge
MCUCR=0x02;
//start interrupt
sei();
lcd_init();
while (1)
{
while(pw==0)
{
if(sw_dir==0)
{
//initially motor runs in clockwise direction since the pin is pulled up
PORTA=0b00000001;
lcd_out(1,1,"MOTOR IS RUNNING");
lcd_out(2,3," clockwise ");
}
else
{
//if direction switch pushed motor rotates anticlockwise
PORTA=0b00000010;
lcd_out(1,1,"MOTOR IS RUNNING");
lcd_out(2,2," anticlockwise ");
}
OCR0=i;//sets the pin value incrementing at push using interrupt
}
//if power button is off PORTA is low motor off
PORTA=0x00;
lcd_out(1,1," MOTOR IS OFF ");
lcd_out(2,3,"caution !!!!");
}
}
//interrupt to increase motor speed every time pushed speed switch connected to INT0 PORTD2
ISR(INT0_vect)
{
i=i+20;
}
void lcd_cmd(unsigned char cmd)
{
//send command to the PORTB
lcdport= cmd;
//register low to command mode
RS_low;
//enable high to feed data
EN_high;
_delay_ms(1);
//enable low to stop transfer
EN_low;
}
void lcd_data(unsigned char dat)
{
//send data through PORTB
lcdport= data ;
//register high to data mode
RS_high;
//enable high transfer data
EN_high;
_delay_ms(1);
//enable low to stop transfer
EN_low;
}
void lcd_init()
{lcd_cmd(0x38);_delay_ms(5); //4 bit 2 Lines 5x7 matrix Input
lcd_cmd(0x02);_delay_ms(5); //to return home
lcd_cmd(0x01);_delay_ms(5); //to clear screen
lcd_cmd(0x0C);_delay_ms(5); //to display on and cursor blinking
lcd_cmd(0x06);_delay_ms(5); //to increment cursor
lcd_cmd(0x80);_delay_ms(5); //to cursor begin 1st line
}
void cursorpos(char x,char y)
{
if((x<1||x>2)||(y>16||y<1))
{
x=1;
y=1;
}
//gives value if wrong input is given
if(x==1)
lcd_cmd(0x7F+y); //position for first line
else
lcd_cmd(0xBF+y); //position for second line
}
void lcd_out(char x,char y,char *str)
{
cursorpos(x,y); // to set cursor
while(*str)
{
lcd_data(*str); // if string has value
str++;
}
}
int adc_read(char channel)
{
unsigned int a,result;
ADMUX =channel;
ADCSRA=0x80;
ADCH = 0x00;
ADCL =0x00;
ADCSRA|=(1<<6);
while((ADCSRA & 0x40)!=0);
a=ADCL;
result =ADCH;
result =result<<8;
result =result | a;
return result;
}
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/10000;
thousand =temp%10+48;
lcd_data(thousand);
flag=1;
}
}