/*Your word is a lamp to my feet and a light to my path-- psalms 119:105
Remote Ir Decode + Motor control Code
*/
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB4_bit;
sbit ir_rx at RC0_bit; //Remote ir input
sbit RIGHT_A at RD0_bit;
sbit RIGHT_B at RD1_bit;
sbit LEFT_A at RD2_bit; //motor pins
sbit LEFT_B at RD3_bit;
sbit MOTOR_EN at RD4_bit;
sbit LED at RC1_bit; // Indication LED pin
//****************************
void get_mark_time(void); // get Sony IR mark time
void right_dir();
void left_dir();
void fwd_dir(); //motor directions
void back_dir();
void stop_motor();
// global variables
unsigned char counter = 0;
unsigned char bitcount;
unsigned char ir_address;
unsigned char ir_command;
unsigned int mark_time;
char str[5];
/////////
void interrupt() {
if (INTCON.T0IF) {
counter++;
INTCON.T0IF = 0;
}
}
void main() {
OPTION_REG = 0x03; //1:16 prescalar
TRISB=0;
PORTD =0;
TRISC=0b00000001;
TRISD=0;
INTCON.GIE = 1;
INTCON.T0IE = 1;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,"Press any Key:");
while(1){
ir_command = 0; // initialise to prevent false trigger
ir_address = 0; // initialise to prevent false trigger
get_mark_time(); // get Sony leader - 2.4mS Mark, 1.2mS space
if ((mark_time > 0x80) && (mark_time < 0xB0)){ // ignore anything but 2.4mS mark
for(bitcount = 0 ; bitcount < 7 ; bitcount++){ // 7 bit command
get_mark_time(); // get a Sony IR bit
ir_command >>= 1; // shift
ir_command &= 0x7f; // top bit zero
if (mark_time > 0x40){ // > 40 is assumed to be a 1
ir_command ^= 0x80; // top bit 1
}
}
ir_command >>= 1; // shift 1 unused bit
ir_command &= 0x7F; // clear top bit
for(bitcount = 0 ; bitcount < 5 ; bitcount++){ // 5 bit address
get_mark_time(); // get a Sony IR bit
ir_address >>= 1; // shift
ir_address &= 0x7f; // top bit zero
if (mark_time > 0x40){
ir_address ^= 0x80; // top bit 1
}
}
ir_address >>= 3; // shift 3 unused bits
ir_address &= 0x1F;
}
if(ir_address == 1){ // address of tv remote
//*********clear lcd*****
LED = 1;
//*****motor
if(ir_command == 116){
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(2,1,"Fwd");
fwd_dir(); //motor contorl
}
if(ir_command == 117){
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(2,1,"Back");
back_dir();
}
if(ir_command == 52){
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(2,1,"Left");
left_dir();
}
if(ir_command == 51){
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(2,1,"Right");
right_dir();
}
if(ir_command == 101){
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(2,1,"Stop");
stop_motor();
}
//***********
ByteToStr(ir_command,str);
Lcd_Out(1,1,"Cd:"); //display key code
Lcd_Out_Cp(str);
}
Delay_ms(190);
LED = 0;
}
}
void get_mark_time(void){
while(ir_rx); // wait for a mark
counter=0;
TMR0 = 0;
while(!ir_rx); // wait for space
mark_time = (counter << 8) + TMR0;
}
void fwd_dir(){
RIGHT_A = 0;
RIGHT_B = 1; //move motor fwd direction
LEFT_A = 0;
LEFT_B = 1 ;
MOTOR_EN = 1;
}
void back_dir(){
RIGHT_A = 1;
RIGHT_B = 0; //move motor back direction
LEFT_A = 1;
LEFT_B = 0;
MOTOR_EN = 1;
}
void right_dir(){
RIGHT_A = 0;
RIGHT_B = 0; //move motor right direction
LEFT_A = 0;
LEFT_B = 1 ;
MOTOR_EN = 1;
}
void left_dir(){
RIGHT_A = 0;
RIGHT_B = 1; //move motor lefft direction
LEFT_A = 0;
LEFT_B = 0 ;
MOTOR_EN = 1;
}
void stop_motor(){
RIGHT_A = 0;
RIGHT_B = 0;
LEFT_A = 0;
LEFT_B = 0 ;
MOTOR_EN = 0;
}