Related topics:
To see how to interface DC motor with PIC16F877A microcontroller and L293D visit the following topic:
DC motor interfacing with PIC16F877A and L293D
And the following topic shows how to decode IR RC5 remote control using PIC16F877A microcontroller:
RC5 remote control protocol decoder using PIC16F877A and CCS PIC C
The RC5 has 14 bits per 1 code transmission, the 14 bits can be divided into 4 parts:
The first 2 bits are start bits and they are always logic 1.
The third bit called toggle bit, it can be logic 1 or logic 0.
The next 5 bits are address bits, each device type has its address number for example TV address number is 0, CD player address = 20 ............
And the last 6 bits are command bits, each button has its command number.
For the same device for example TV all the remote control buttons has the same address but each button has its command.
The toggle bit changes whenever a button is pressed.
The remote control used in this project is a TV remote control which has an address = 0.
In this project toggle bit is not used which means only address and command quantities are used. The following image shows the used buttons with the corresponding address and command numbers for each button.
Remote controlled DC motor using PIC16F877A microcontroller circuit:
Project circuit schematic is shown below.
The
IR receiver is used to receive the IR signals transmitted from the
remote control and convert this signals to a digital data (logic 0,
logic 1). The microcontroller PIC16F877A
reads digital data from the IR receiver. LED1 blinks when RC5 IR protocol is received.Project circuit schematic is shown below.
LED2 indicates maximum speed.
LED3 and LED4 are used to indicate motor rotation direction, if LED3 is ON that means direction 1 has been chosen and the same thing for LED4. If both LEDs are OFF that means the motor has been stopped.
The nominal voltage of the motor is 12V as well as L293D VS input voltage. Always L293D VS voltage is the same as the DC motor voltage and L293D VSS voltage is +5V.
PIC16F877A CCP1 and CCP2 modules are used as PWM which allows us to control motor speed as well as direction of rotation. PWM frequency is 500Hz.
Remote controlled DC motor using PIC16F877A CCS C code:
PIC16F877A Timer2 is configured to generate a PWM frequency of 488Hz and the microcontroller runs with 8MHz crystal oscillator.
// Remote controlled DC motor with PIC16F877A CCS PIC C code
// RC5 IR remote control used
// http://ccspicc.blogspot.com/
// electronnote@gmail.com
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#use fast_io(B)
#use fast_io(C)
short toggle;
unsigned int8 count, i, j, address, command;
short remote_read(){
count = 0;
// Check if the received signal uses RC5 protocol
while((input(PIN_B0) == 0) && (count < 20)){
count++;
delay_us(50);}
if( (count > 20) || (count < 14)) // Signal doesn't use RC5 protocol
return false; // Return
count = 0;
while((input(PIN_B0)) && (count < 20)){
count++;
delay_us(50);}
if( (count > 20) || (count < 14)) // Signal doesn't use RC5 protocol
return false ; // Return
count = 0;
while((input(PIN_B0) == 0) && (count < 40)){
count++;
delay_us(50);}
if( (count > 40) || (count < 14)) // Signal doesn't use RC5 protocol
return false ; // Return
// End check (The received signal uses RC5 protocol)
if(count > 30)
delay_us(400);
else
delay_us(1300);
output_high(PIN_B1); // Turn RB1 LED ON
for(i = 0; i < 12; i++){
if(i == 0){
if(input(PIN_B0) == 1) toggle = 0;
else toggle = 1;
}
else {
if(i < 6){ //Read address bits
if(input(PIN_B0) == 1)
bit_clear(address, (5 - i)); //Clear bit (5-i)
else
bit_set(address, (5 - i)); //Set bit (5-i)
}
else { //Read command bits
if(input(PIN_B0) == 1)
bit_clear(command, (11 - i)); //Clear bit (11-i)
else
bit_set(command, (11 - i)); //Set bit (11-i)
}
}
delay_us(1778);
}
address &= 0x1F;
command &= 0x3F;
return true;
}
void main(){
setup_adc_ports(NO_ANALOGS); // Configure AN pins as digital
port_b_pullups(TRUE); // Enable PORTB pull-ups
output_b(0); // PORTB initial state
set_tris_b(1); // Configure RB0 pin as input
output_c(0); // PORTC initial state
set_tris_c(0); // Configure PORTC pins as outputs
setup_timer_2(T2_DIV_BY_16, 250, 1); // Set PWM frequency to 500Hz
delay_ms(100); // Wait 100ms
while(TRUE){
output_low(PIN_B1);
while(input(PIN_B0)); // Wait until RB0 pin falls
if(remote_read()){
if((address == 0) && (command == 16) && (input(PIN_B3) == 0)){
output_b(0); // Both LEDs OFF
setup_ccp1(CCP_OFF); // CCP1 OFF
setup_ccp2(CCP_OFF); // CCP2 OFF
output_c(0); // PORTC pins low
delay_ms(100); // Wait 100ms
setup_ccp1(CCP_PWM); // Configure CCP1 as PWM
set_pwm1_duty(j); // Set pwm1 duty cycle
output_high(PIN_B3); // RB3 LED ON
if(j > 250)
output_high(PIN_B2); // RB2 LED ON (speed is max)
}
if((address == 0) && (command == 17) && (input(PIN_B4) == 0)){
output_b(0); // Both LEDs OFF
setup_ccp1(CCP_OFF); // CCP1 OFF
setup_ccp2(CCP_OFF); // CCP2 OFF
output_c(0); // PORTC pins low
delay_ms(100); // Wait 100ms
setup_ccp2(CCP_PWM); // Configure CCP2 as PWM
set_pwm2_duty(j); // Set pwm1 duty cycle
output_high(PIN_B4); // RB4 LED ON
if(j > 250)
output_high(PIN_B2); // RB2 LED ON (speed is max)
}
if((address == 0) && (command == 32) && (j < 251)){
j++;
if(j > 250)
output_high(PIN_B2); // RB2 LED ON
if(input(PIN_B3))
set_pwm1_duty(j); // Set pwm1 duty cycle
if(input(PIN_B4))
set_pwm2_duty(j); // Set pwm2 duty cycle
}
if((address == 0) && (command == 33) && (j > 0)){
j--;
output_low(PIN_B2); // RB2 LED OFF
if(input(PIN_B3))
set_pwm1_duty(j); // Set pwm1 duty cycle
if(input(PIN_B4))
set_pwm2_duty(j); // Set pwm2 duty cycle
}
if((address == 0) && (command == 59)){
setup_ccp1(CCP_OFF); // CCP1 OFF
setup_ccp2(CCP_OFF); // CCP2 OFF
output_b(0); // Both LEDs OFF
output_c(0); // PORTC pins low
}
}
}
}
Remote controlled DC motor using PIC16F877A video:
The following video shows a hardware circuit of this project.