Friday, January 30, 2015

Remote Controlled DC Motor

Control your DC motor with PIC16F877A from remote control
In this project we are going to see how to control 12V DC motor from a remote control. This controller allows us to control the speed and direction of our motor.
Related Topics:
DC Motor Speed and Direction Controller 
Remote Controlled LED
As we have seen in the previous examples we can control the speed and direction of dc motor, the speed is controlled by a potentiometer which vary the duty cycle of the pwm signal. Also we have controlled an led brightness using remote control.
Now, we are going to mix the previous topics to make our remote controlled dc motor.
The remote used here in Philips RC5 remote control, the following picture shows this remote and the working keys:
RC5 protocol remote control
If the button indicated by ccw is pressed, the motor will rotate in ccw direction, and so on for the other buttons.
Remote controlled DC motor circuit:
The schematic diagram of the circuit is shown by the following picture:

remote controlled dc motor speed direction pic16f877a mikroc code

The 1602 LCD display displays the direction rotation and speed level of our motor, also it dispalys Motor is OFF when the motor is at off state.
Remote controlled DC motor mikroc Code:

//Remote Controlled DC Motor
//Used microcontroller: PIC16F877A @ 12MHz
//Written by: BENCHEROUDA Okba
//http://www.elecnote.blogspot.com
//electronnote@gmail.com
//Use at your own risk
 
  // LCD module connections
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RD1_bit;
sbit LCD_D4 at RD2_bit;
sbit LCD_D5 at RD3_bit;
sbit LCD_D6 at RD4_bit;
sbit LCD_D7 at RD5_bit;
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD4_bit;
sbit LCD_D7_Direction at TRISD5_bit;
  // End LCD module connections
 
unsigned short ir_read, j, command=0;
short i = 0;
bit dr;
unsigned   dt, dt0;
unsigned char  *text, mytext[4];
void Interrupt(){               //External interrupt occured
 //Check if the received signal is RC5 protocol
  delay_us(370);
  if(PORTB.F0==0){
  delay_us(889);
  if(PORTB.F0==1){
  delay_us(889);
  if(PORTB.F0==0){
   ir_read = 1;
  INTCON  = 0;                //Disabe the external interrupt
 }}}
 INTF_bit = 0;                //Clear Interrupt flag
}
void display_results (){
   Lcd_Cmd(_LCD_CLEAR);            //Clear LCD
   text = "Direction:   " ;
   Lcd_Out(1, 2, text);
   if(dr == 0){
   text = "CW" ;
   Lcd_Out(1, 12, text);}
   else {
   text = "CCW" ;
   Lcd_Out(1, 12, text);}
   text = "Speed(%)=" ;
   Lcd_Out(2, 3, text);
   ByteToStr(i, mytext);  Lcd_Out(2, 12, Ltrim(mytext));
  }
void main() {
 OPTION_REG = 0;
 PORTB = 0; 
 TRISB = 1;
 PORTC = 0;
 TRISC = 0;
 PORTD = 0;
 TRISD = 0;
 PWM1_Init(10000);
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
 Lcd_Cmd(_LCD_CLEAR);             // clear LCD
 text = "Remote" ;
 Lcd_Out(1, 6, text);
 text = "Controlled DCM" ;
 Lcd_Out(2, 2, text);
 delay_ms(1000);
 while(1){
ret:
INTCON         = 0x90;   //External Interrupt enabled
while(!ir_read);         //Wait until IR RC5 protocl received
ir_read = 0;
delay_us(12446);
for(j = 0; j < 6; j++){
if (PORTB.F0 == 0) command|= (1<<( 5 - j));//Set bit (11-j)
else               command&=~(1<<(5 - j)); //Clear bit (11-j)
  delay_us(1778);}
 if (command == 12) {
  PORTC = 0;
  PWM1_Stop();
  Lcd_Cmd(_LCD_CLEAR);
  text = "Motor is OFF" ;
  Lcd_Out(1, 3, text);
  goto ret;   }
  if (command == 16){ dr = 1;
   display_results();
   PORTC = 1;
   PWM1_Start();
   goto ret;     }
  if (command == 17){ dr = 0;
   display_results();
   PORTC = 2;
   PWM1_Start();
   goto ret;    }
  if (command == 32){ i++;
     if(i > 100) i = 100;}
     if (command == 33) {i--;
  if(i < 1) i = 0;}
  PWM1_Set_Duty(i * 255 / 100);
  PWM1_Start();
  display_results();
 }
}