ขอคำแนะนำ การเขียนโปรแกรมรับค่าจาก IR Remote Control Kit หน่อยครับ

Started by BumbleT, August 22, 2013, 10:01:49 PM

Previous topic - Next topic

BumbleT

ขอคำแนะนำหรือตัวอย่าง การเขียนโปรแกรมรับค่า IR Remote Control Kit ตัวนี้ โดยใช้ PIC16F877 หน่อยครับ


Infrared Receiver Module เบอร์ 1838B
NEC Protocol

ขอบคุณล่วงหน้าครับ

JENG

สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

BumbleT

ขอบคุณครับ
แต่พอจะมีตัวอย่าง ให้ศึกษาบ้างไหมครับ


JENG

ของ pic เจอแต่ sony-protocol ครับ  :P

//--------------------------------------------------
// Program  :IR Receiver (SIRC Protocol)
// Author   :Somlak Mangnimit
// Date     :21/03/2012
// Device   :PIC16F676 @int clock 4Mhz
//--------------------------------------------------
#include    <htc.h>
#define     _XTAL_FREQ 4000000
__CONFIG(FOSC_INTRCIO&WDTE_ON&MCLRE_OFF);

#define     LED1            PORTCbits.RC0
#define     LED2            PORTCbits.RC1
#define     LED3            PORTCbits.RC2
#define     LED4            PORTCbits.RC3
#define     LED5            PORTCbits.RC4
#define     LED6            PORTCbits.RC5
#define     LED7            PORTAbits.RA4
#define     LED8            PORTAbits.RA5

#define     ClrWDT();       asm("CLRWDT");

volatile unsigned char
Current_state,Counter,Got_data,bit_count,Command_code,
Device_code,WaitRelease
;

volatile unsigned int
input_data
;

enum{
Idle,Start_bit,Capture_bit
};

//------------------------------------------------
// Interrupt Service
//------------------------------------------------
void interrupt service(void){
//-------------------------
// External interrupt RB0
//-------------------------
    if(INTF){
        switch (Current_state){
            case Idle:
                INTEDG = 1;                     //interrupt on rising edge.
                Counter = 0;
                Current_state = Start_bit;
            break;
            //-------------------------
            // found the rising edge,
            // check lenght for 2.4ms
            //-------------------------
            case Start_bit:
                if(Counter == 4){               //correct signal, move on to next state
                    Counter = 0;
                    bit_count = 0;
                    input_data = 0;
                    Current_state = Capture_bit;
                }

                else {
                    INTEDG = 0;             //interrupt on falling edge.
                    Current_state = Idle;       //fault signal, reset to Idle
                }
            break;
            //-------------------------
            // check plus length
            // for 0 or 1
            //-------------------------
            case Capture_bit:
                if(Counter == 2){
                    input_data >>= 1;           // add 0 to received data
                    bit_count++;
                } 
                else{
                    if(Counter == 3){
                        input_data >>= 1;
                        input_data |= 0x8000;   //add 1 to received data
                        bit_count++;
                    }
                    //-------------------------
                    // error occurs,
                    // reset to Idle state
                    //-------------------------
                    else{
                        INTEDG = 0;             //interrupt on falling edge.
                        Current_state = Idle;
                    }
                }
                //-------------------------
                //compleat 12 bit
                //-------------------------
                if(bit_count >= 12){
                    Got_data = 1;
                    input_data >>= 4;
                    INTEDG = 0;                 //interrupt on falling edge.
                    Current_state = Idle;
                }
                Counter = 0;
            break;

            default:
                INTEDG = 0;                     //interrupt on falling edge.
                Current_state = Idle;
        }
        INTF = 0;                               //clear interrupt flag.
    }

    if(T0IF){
        TMR0 = 110;     //600us@4mhz
        T0IF = 0;       //Clear flag
        Counter++;

        if(Counter>5){
            INTEDG = 0;                     //interrupt on falling edge.
            Current_state = Idle;
        }

        if(Counter>40){
            LED8 = 0;
        }

        if(Counter>50){
            WaitRelease = 0;
        }
        ClrWDT();
    }
}

//--------------------------------------------------
// Initial start up
//--------------------------------------------------
void Start_up(void){
PORTA = 0x00;
PORTC = 0x00;

ANSEL = 0x00;               //All digital I/O
CMCON = 0x05;               //Turn off comparator
ADCON0 = 0x00;

TRISA = 0x00;
TRISC = 0x00;

TRISAbits.TRISA2 = 1;       //IR input
TRISAbits.TRISA3 = 1;       //Sw input

//-----
T0CS = 0;
PSA = 0;                    //prescaler timer0
PS2 = 0;                    //1:4
PS1 = 0;
PS0 = 1;
INTEDG = 0;                 //Falling edge

//-----
T0IE = 1;
INTE = 1;                   //External interrupt
PEIE = 1;                   //Peripheral interrupt
GIE = 1;                    //Global interrupt

}

//--------------------------------------------------
// Main program
//--------------------------------------------------
void main(void){
Start_up();

    while(1){
        if(Got_data){
            Command_code = input_data & 0x7F;
            Device_code = input_data >> 7;
            Got_data = 0;
            if(Device_code == 1 && !WaitRelease){
            WaitRelease = 1;
                switch (Command_code){
                    case 0: LED1 = ~LED1; LED8 = 1;break;
                    case 1: LED2 = ~LED2; LED8 = 1;break;
                    case 2: LED3 = ~LED3; LED8 = 1;break;
                    case 3: LED4 = ~LED4; LED8 = 1;break;
                    case 4: LED5 = ~LED5; LED8 = 1;break;
                    case 5: LED6 = ~LED6; LED8 = 1;break;
                    //case 6: LED7 = ~LED7; LED8 = 1;break;
                    //case 7: LED8 = ~LED8; break;
                }
            }
        }
    }
}


สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

BumbleT

ขอบคุณครับ ท่าน JENG

นี่คือ code ที่ผมประยุกต์จะการหาตัวอย่าง
ซึ่งผมต้องการให้มันแสดงค่าที่รับมาจะกดปุ่มใดปุ่มหนึ่งที่ Remote แล้วแสดงผลออกทางจอ LCD
ผลคือไม่รู้มันไปค้างอยู่ในฟังก์ชันไหนงงมากครับ
ท่านผู้รู้ช่วยชี้แนะด้วยครับ ผมมันด้อยความรู้นัก

ขอบคุณครับ


#include <16F877.h>
#fuses  HS,NOLVP,NOWDT,NOPROTECT
#use delay (clock = 4000000)    // Crytal = 4MHz
#include "LCD.c"
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
//----------------------------------------------------
//#byte CMCON=0x07;
//----------------------------------------------------
#define  IR_PIN  PIN_B0
//----------------------------------------------------
unsigned char bitcount;

int32 ir_tempbyte_hi;
int16 ir_tempbyte_lo;
int16 headp,heads,rise,fall;
//----------------------------------------------------
void ir_read();
void ir_get_rise();
void ir_get_fall();
void ir_build_bytes();
//----------------------------------------------------
#INT_EXT
void EXT_int()
{
   ir_read();
}
//-----------------------------------------------------------------------------
void ir_read(void)
{
   ir_tempbyte_hi=0;
   ir_tempbyte_lo=0;

   while(IR_PIN); // //Wait for minimal pre which stays low

   ir_get_rise(); // Get headp & heads to see what protocol it is
   headp=rise;
   ir_get_fall();
   heads=fall;

   if ((headp>8700)&&(headp<9090)&&(heads>4200)&&(heads<4600)) // We got NEC Start Sequence
   {
      output_high(PIN_C4);
      ir_build_bytes(); // Now trying to read data bits
   }
   else
   {
      output_high(PIN_C4);
   }
}
//-----------------------------------------------------------------------------
void ir_get_rise(void)
{
   output_high(PIN_C5);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);    // Get high
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   set_timer1(0);
   while(!IR_PIN); // Wait for signal to go high
   rise = get_timer1();
   output_high(PIN_C5);   
}
//-----------------------------------------------------------------------------
void ir_get_fall(void)
{
   output_high(PIN_C6);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);    // Get low
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   set_timer1(0);
   while(IR_PIN);                               // Wait for signal to go low
   fall = get_timer1();
   output_high(PIN_C6);
}
//-----------------------------------------------------------------------------
void ir_build_bytes(void)
{
   for (bitcount=0;bitcount!=32;bitcount++)
   {
      ir_get_rise();
      ir_get_fall();

      if ((rise>450)&&(rise<650)&&(fall>1400)&&(fall<1655))
      {
         ir_tempbyte_hi|=1; // bit=1
         //data[bitcount]=1;
      }
      else if ((rise>450)&&(rise<650)&&(fall>390)&&(fall<600)){;}
     
      else return; // Byte Check Fault
   }

   if (bitcount<31){ir_tempbyte_hi<<=1;}  // Don't shift last bit
   if (bitcount==32){output_high(PIN_C4);} // reception is valid
}
//******************************************************************************
void main()
{
   //--------------------------------------------------------------------------
   set_tris_C(0x00);
   //--------------------------------------------------------------------------
   setup_timer_1(t1_disabled);
   //--------------------------------------------------------------------------
   enable_interrupts(INT_EXT);  // Enable Interrupt Capture
   enable_interrupts(GLOBAL);    // Enable Interrupt Global
   //--------------------------------------------------------------------------
   ext_int_edge(H_TO_L);           // INT_EXT is High to Low
   //--------------------------------------------------------------------------
   lcd_init();
   //--------------------------------------------------------------------------
   lcd_gotoxy(1,1);
   printf(lcd_putc,"TEST IR Remote..");
   output_C(0xF0);
   delay_ms(1000);
   output_C(0x00);
     
   while(1)
   {
      lcd_gotoxy(1,1);         
      printf(lcd_putc,"%lX        ",ir_tempbyte_hi);
      output_high(PIN_C7);
      delay_ms(200);
      output_low(PIN_C7);
      delay_ms(200);
   }
}
//******************************************************************************

JENG

ต่อวงจรไว้ไงบ้าง xtal-ค่าตรงกันหรือป่าว code นี้เดิมใช้กับ pic เบอร์อะไร
สามารถติดตาม electoday ได้ที่

Facebook
www.facebook.com/groups/coopmicro

Google+
https://plus.google.com/communities/103482067769375459277

☺☺☺ความรู้ และความฉลาด ไม่ใช่สิ่งเดียวกัน จะมีประโยชน์อะไร ถ้าฉลาดแต่อยู่ในกะลา☺☺☺

boe

ไม่มีความยากจน ในหมู่คนขยัน

BumbleT

Quote from: JENG on August 23, 2013, 12:49:51 PM
ต่อวงจรไว้ไงบ้าง xtal-ค่าตรงกันหรือป่าว code นี้เดิมใช้กับ pic เบอร์อะไร

- ต่อวงจรไว้ยังไงบ้าง
ผมต่อประมาณนี้ครับ ดังรูป



- ค่า xtal ค่าตรงกันหรือป่าว
ค่าเดียวกันครับ

- เดิมใช้ PIC เบอร์อะไร
เดิมใช้เบอร์ 16F628A ครับ