Nec kızılötesi iletişim protokolünü anlatacak hayırsever var mı?

Başlatan Recep METE, 16 Nisan 2015, 22:39:43

Recep METE

Arkadaşlar elimde kızıl ötesi kumandalar mevcut.Muhtemelen NEC protokolünü kullanıyorlar.Ben bu kumandanın butonlarını kullanarak led yak söndür yapmak istiyorum.Kızıl ötesi kumandanın her butonu ile farklı işler yaptırmak istiyorum.Alıcı taraftaki pice Nec protokolünün kodlarını yazmak istiyorum.Forumu ve google çok incelememe rağmen beni tatmin edecek ve anlayabileceğim bilgi bulamadım.Bu işi basitce anlatacak bir hayırsever var mı aranızda acaba?
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

ayhani

Alıntı yapılan: Recep METE - 16 Nisan 2015, 22:39:43
Arkadaşlar elimde kızıl ötesi kumandalar mevcut.Muhtemelen NEC protokolünü kullanıyorlar.Ben bu kumandanın butonlarını kullanarak led yak söndür yapmak istiyorum.Kızıl ötesi kumandanın her butonu ile farklı işler yaptırmak istiyorum.Alıcı taraftaki pice Nec protokolünün kodlarını yazmak istiyorum.Forumu ve google çok incelememe rağmen beni tatmin edecek ve anlayabileceğim bilgi bulamadım.Bu işi basitce anlatacak bir hayırsever var mı aranızda acaba?

Hocam sanırım şu linkteki TXT dosyasında aradığın kodlar var. RS232'den bu kodları gönder al yaparak sanırım sorunun çözülür.

http://www.google.com.tr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=11&cad=rja&uact=8&ved=0CF4QFjAK&url=http%3A%2F%2Fwww.microchip.com%2Fforums%2Fdownload.axd%3Ffile%3D1%3B397137&ei=GxswVf-ZM6rMyAOGv4DgBA&usg=AFQjCNFPb96zU_d8K1HsGFuFUo2ub2lcdg&bvm=bv.91071109,d.bGQ

En iyi bildiğim şey hiçbir şey bilmediğimdir.

ete

Aşağıdaki linkte NEC protokolü anlatılmaktadır.

http://www.sbprojects.com/knowledge/ir/nec.php

Gerek RF ve gerekse IR sinyallerin çözülmesinde temel mantık şöyledir.
Açıklamaya geçmeden önce bazı bilgiler vermekte yarar var. Bu tür sinyaller bir paket halinde yollanır. He rpaketin başına bir HEADER sinyali eklenir. Her bir paketi bir tren'e benzetebilirsiniz. Şöyle bir düşünürseniz trende bir vagon bulabilmek için önce lokomotife bakar sonra vagonları sayarsınız. İşte burada Lokomotif Header sinyali ile eşdeğer görev üstlenir.
Öncelikle bu header sinyalini yakalamak gerekiyor. NEC protokolünde header sinyali 9ms uzunluğunda bir HIGH ve peşinden 4,5ms uzunluğunda LOW sinyalinden oluşuyor. Diğer sinyal genişliklerine bakacak olursanız bu kadar uzun sinyal hiç yok. O halde işe 9ms lik uzun HIGH sinyalini yakalamakla başlamak lazım. Yapılacak iş basit bir şekilde puls genişliği ölçülerek gelen sinyalin önce HIGH mi sonrada uzunluğunun 8 ms den büyükmü olduğuna bakmak gerekiyor. Bu işlem ile Header yakalandıktan sonra gelelim bitleri almaya. Bunun için önce HIGH bitine bakalım 560us uzunluğunda bir HIGH ve 1690us uzunluğunda LOW sinyalinden oluşuyor.
LOW biti ise 560us uzunluğunda HIGH ve peşinden yine 560us uzunluğunda LOW sinyalinden oluşuyor. Bu ikisi arasında farklı olan nedir?. Tabiiki sinyallerin LOW kısımları. O halde görevimiz bu LOW ları süre bazında sırası ile almak olmalı.
Sinyal uzunluğuna bakılırsa, toplam paket 32 bit den oluşuyor. O halde yalnızca sinyallerin LOW kısımlarını süre bazında önce kayıt etmek sonrada süre karşılaştırması yaparak o bitin HIGH mı yoksa LOW mu olduğuna karar vermek gerekir.
İlk 8 bitlik sinyal  Adres.Lowbyte, sonraki 8 bitlik sinyal Adres.Highbyte, sonraki 8 bitlik sinyal Komut.Lowbyte ve en sonda da Komut.Highbyte şeklinde ayrıştırılarak kod çözülmüş olacaktır.

Olayı toparlayacak olursak,
- Header sinyalini yakalayacaksınız.
- Peşinden gelen 32 biti süre bazında ölçerek alacaksınız ve gerekirse bir dizi değişkenine bu süreleri sırası ile yerleştireceksiniz.
- Sonra süreleri yaklaşık değerler olarak karşılaştırıp bitlerin LOW mu yoksa HIGH mı olduklarına karar vereceksiniz.
- Sonuçta elde edilen bu bitleri birleştirip Adres ve KOmut değerlerini bulacaksınız.

Bu arada linkte verilen bilgiye bakılırsa data paketi bir kere verildikten sonra ikincisinde bütün bitler invert edilip yeniden veriliyormuş. Bunu bir düz bir ters sinyal yollanıyor şeklinde de yorumlayabilirsiniz. Ama siz sadece düzleri yada tersini yapıp tersleri almaya yönelirseniz başarırsınız.

Ete


Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Recep METE

@ayhani ve @ete hocam, çok teşekkür ederim.İyi ki varsınız.Uygulama yapmaya başlayacağım karşılaştığım sorunları burada paylaşacağım.Yardımlarınızı yine bekliyorum.Çok sağolun.
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

atomx

/*
 * NEC Protocol IR Remote decoder
 * Badr Ghatasheh
 * badr.ghatasheh@gmail.com
 * July 2013
 */
#include <stdint.h>
#include <stdbool.h>
#include <delays.h>
#include <xc.h>

// Use #define P16F877A to compile the code for PIC16F877A
#define P16F84A

// Uncomment this to enable debugging
//#define debugging

#if defined(P16F84A)
    #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
    #pragma config CP = OFF         // Code Protection bit (Code protection disabled)
#elif defined(P16F877A)
    #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
    #pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#endif

#define _XTAL_FREQ 4000000L  // required by delays.h, crystal frequency

// button commands, I've decoded those values earlier using a similar program
#define txt_command     0x44
#define sub_command     0x45
#define zoom_command    0x42
#define epg_command     0x17

#if defined(debugging)
    int debug_buffer[33]; // a placeholder for signal analysis
#endif

/*
 * Initialize ports tri state buffers, timer 0 and ADC if exists
 */
void init() {
    TRISA = 0xFF; // Set PORTA as input port
    TRISB = 0x00; // Set PORTB as output port
    PORTB = 0b01110000 & EEPROM_READ(0); // read the last state from eeprom address 0
    OPTION_REG = 0b11010101; // Setup Timer 0 Module, internal clock with 64 divider
    // Timer 0 Frequency = FCYC / 64 = 1MHz / 64 = 15.625KHz
    #if defined(P16F877A)
     ADCON1 = 0b00000110; // this is in case of using PIC16F877A, turn off ADC module
    #endif
}

/*
 * This function writes the new states [PORTB value] to the eeprom
 * and lights an indication LED on pin RB7 for 500ms
 * those 500ms is also used to provide time separation between bounces
 */
void update_status() {
    EEPROM_WRITE(0,PORTB);
    PORTBbits.RB7 = 1;
    __delay_ms(500L);
    PORTBbits.RB7 = 0;
}

void main(void)
{
    init();

    unsigned int time = 0;
    short start_bit = 0;
    unsigned int command;
    unsigned int index = 0;

    while(1) // infinite loop
    {
        TMR0 = 0x00; // Reset Timer
        while (PORTAbits.RA0 == 1); // wait until sensor changes from high to low
        time = TMR0; // get timer 0 register value
        if (time >= 67 && time <= 71) { // Start bit detected {around 4.5ms}
            start_bit = 1; // set flag
            command = 0; // reset old command value
        }
        
        if (start_bit) {
            // Logic 1 is around 1690us, around 26 timer clicks
            // Logic 0 otherwise {560us} around 8 timer clicks
            if (index > 16 && time >= 24 && time <= 27) { // discard address bits [for the sake of simplicity
                // setting each bit of the command variable according to the corresponding decoded value in the stream
                // our command starts at index 17 [1 start bit + 16 address bits = 17]
                command = command | (1 << (index - 17));
            }

            #if defined(debugging)
                debug_buffer[index]=time;
            #endif

            index++;
        }

        while (PORTAbits.RA0 == 0); // wait until sensor flips
        
        if(index == 24) // a full 8 bit command received
        {
            // Toggle outputs depending on the value of the command
            switch(command) {
                case txt_command:
                    PORTBbits.RB4 = ~PORTBbits.RB4;
                    update_status();
                    break;
                case sub_command:
                    PORTBbits.RB5 = ~PORTBbits.RB5;
                    update_status();
                    break;
                case zoom_command:
                    PORTBbits.RB6 = ~PORTBbits.RB6;
                    update_status();
                    break;
            }

            // reset values for another round
            index = 0;
            start_bit = 0;

            #if defined(debugging)
                for(int i=0; i<33 ; i++) debug_buffer[i]=0;
            #endif
        }
    }
}


İşine yarar diye düşündüm. Açıklama kodda mevcut zaten.
Hüseyin TECER

Recep METE

Alıntı yapılan: atomx - 17 Nisan 2015, 11:59:42
/*
 * NEC Protocol IR Remote decoder
 * Badr Ghatasheh
 * badr.ghatasheh@gmail.com
 * July 2013
 */
#include <stdint.h>
#include <stdbool.h>
#include <delays.h>
#include <xc.h>

// Use #define P16F877A to compile the code for PIC16F877A
#define P16F84A

// Uncomment this to enable debugging
//#define debugging

#if defined(P16F84A)
    #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
    #pragma config CP = OFF         // Code Protection bit (Code protection disabled)
#elif defined(P16F877A)
    #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
    #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
    #pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#endif

#define _XTAL_FREQ 4000000L  // required by delays.h, crystal frequency

// button commands, I've decoded those values earlier using a similar program
#define txt_command     0x44
#define sub_command     0x45
#define zoom_command    0x42
#define epg_command     0x17

#if defined(debugging)
    int debug_buffer[33]; // a placeholder for signal analysis
#endif

/*
 * Initialize ports tri state buffers, timer 0 and ADC if exists
 */
void init() {
    TRISA = 0xFF; // Set PORTA as input port
    TRISB = 0x00; // Set PORTB as output port
    PORTB = 0b01110000 & EEPROM_READ(0); // read the last state from eeprom address 0
    OPTION_REG = 0b11010101; // Setup Timer 0 Module, internal clock with 64 divider
    // Timer 0 Frequency = FCYC / 64 = 1MHz / 64 = 15.625KHz
    #if defined(P16F877A)
     ADCON1 = 0b00000110; // this is in case of using PIC16F877A, turn off ADC module
    #endif
}

/*
 * This function writes the new states [PORTB value] to the eeprom
 * and lights an indication LED on pin RB7 for 500ms
 * those 500ms is also used to provide time separation between bounces
 */
void update_status() {
    EEPROM_WRITE(0,PORTB);
    PORTBbits.RB7 = 1;
    __delay_ms(500L);
    PORTBbits.RB7 = 0;
}

void main(void)
{
    init();

    unsigned int time = 0;
    short start_bit = 0;
    unsigned int command;
    unsigned int index = 0;

    while(1) // infinite loop
    {
        TMR0 = 0x00; // Reset Timer
        while (PORTAbits.RA0 == 1); // wait until sensor changes from high to low
        time = TMR0; // get timer 0 register value
        if (time >= 67 && time <= 71) { // Start bit detected {around 4.5ms}
            start_bit = 1; // set flag
            command = 0; // reset old command value
        }
        
        if (start_bit) {
            // Logic 1 is around 1690us, around 26 timer clicks
            // Logic 0 otherwise {560us} around 8 timer clicks
            if (index > 16 && time >= 24 && time <= 27) { // discard address bits [for the sake of simplicity
                // setting each bit of the command variable according to the corresponding decoded value in the stream
                // our command starts at index 17 [1 start bit + 16 address bits = 17]
                command = command | (1 << (index - 17));
            }

            #if defined(debugging)
                debug_buffer[index]=time;
            #endif

            index++;
        }

        while (PORTAbits.RA0 == 0); // wait until sensor flips
        
        if(index == 24) // a full 8 bit command received
        {
            // Toggle outputs depending on the value of the command
            switch(command) {
                case txt_command:
                    PORTBbits.RB4 = ~PORTBbits.RB4;
                    update_status();
                    break;
                case sub_command:
                    PORTBbits.RB5 = ~PORTBbits.RB5;
                    update_status();
                    break;
                case zoom_command:
                    PORTBbits.RB6 = ~PORTBbits.RB6;
                    update_status();
                    break;
            }

            // reset values for another round
            index = 0;
            start_bit = 0;

            #if defined(debugging)
                for(int i=0; i<33 ; i++) debug_buffer[i]=0;
            #endif
        }
    }
}


İşine yarar diye düşündüm. Açıklama kodda mevcut zaten.

Hocam çok teşekkür ederim.Çok işime yarayacak.Sormak istediğim şudur,  ben bu kodu nasıl kullanmalıyım.Şifre çözücü kod zannedersem.Bilginiz varsa paylaşır mısınız?
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

atomx

Timer0 zamanlayicisi kullanilmis. İlk once 4.5ms low header verisini algilamis eger aldigilandi ise 560us low verisine bakilmis eger kosula uygun ise veri icerigini 1 sola kaydirma yapmis. Timer0 zamanlamalari 4mhz crystal e gore ayarlanmis.
Hüseyin TECER

baran123

Benim bildiğim kumandalar 16 bit data gönderiyor arkadaşın örneğindeki açıklamada 8 bit olduğu yazıyor kumandanın bilgileri de önemlii

necati

[email]entegreterbiyecisi@yahoo.com[/email]

Recep METE

Bu iş çok karmaşık geldi.  Ben Serdar Çiçek hocanın yaptığı çalışma ile yetinecegim galiba. Ir kumanda kullanilarak yapılmış elinde calima olan varsa buraya yukleyebilr mi? Ya da parayla satilan bir çalışma varsa alabilirim.
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

baran123

Bu kadar uğraşıyorsun ağabey kendin yapabilirsin emeğine yazık :) ben dediğin gibi denedim ama her seferinde farklı datalar geliyor.Mutlaka iyi bilen birileri vardır da hala arıyorum. :D Dahada ararım gibime geliyor.Eski bir sistem olduğundan kullanan yok sanırım.