Elektronik Devreler Projeler Elektronik ve biraz daha fazlası İletişim - Araçlar - Dikkat - Topluluk
Elektronik / Mikrodenetleyici Projeleri/

MSP430 ile Kızılötesi Kumanda Sinyallerinin Çözülmesi

Sponsorlu Bağlantılar

Merhabalar, bu yazımda hepimizin evlerimizde sıkça kullandığı kızılötesi kumandaların çalışmalarından bahsedip bu kumandaların gönderdiği verileri MSP430 mikrodenetleyiciler ile elde etme ile ilgili örnek bir uygulama anlatmayı planlıyorum.

Kızıl ötesi kumandalar evlerimizde tv, müzik seti, klima v.s. bir çok aleti kontrol etmek için kullandığımız aletlerdir ve çoğunlukla uzaktan kumanda diye anılırlar. Kumandamızı verici, diğer tarafta ki tv, klima yada diğer cihazları ise alıcı olarak adlandırabiliriz. Verici tarafından gönderilen tuş bilgisi alıcı tarafından alınıp uygun işlem yapılarak kontrol işlemi gerçekleştirilir. Alıcı ve vericinin haberleşmesi için çeşitli iletişim protokolleri kullanılmaktadır. Bunlardan en çok bilinenleri Sony SIRC, Philips RC5, NEC isimli protokollerdir.

Daha öncesinde çeşitli mikrodenetleyicilerle yaptığım kızılötesi kontrol uygulamalarım olmuştu. Geçenlerde MSP430 denetleyiciler ile kızılötesi iletişim uygulaması yapmayı düşündüm ve TI‘nin bu konu ile uygulama notu olabileceğini düşünerek internet üzerinde araştırma yaptım. Biraz araştırdıktan sonra burada TI mühendisleri tarafından hazırlanmış olan Sony SIRC ve Philips RC5 protokollerini kapsayan açıklayıcı bir uygulama notu buldum. Uygulamayı referans alarak kendi uygulamamı yapmaya koyuldum. İlk olarak uygulama kodları asembly ile yazıldığından kodları C koduna çevirmekle başladım. Kodları çevirip, derleyip denemeleri yapınca kumanda kodlarını yakalamayı başardım. Uygulama kodunu inceleyince bir kaç mantık hatası buldum. Bu hatadan kaynaklı yanlış alımlar oluşabilirdi. Kodları kendi mantığıma göre tekrardan yazıp tekrar denedim nispeten daha iyi sonuçlar aldım. Uygulama notunda RC5 ve SIRC protokolleri için örnek kodlar bulunmakta ben elimde Sony kumanda bulunduğu için SIRC protokolü ile ilgili uygulama yaptım. Benzer şekilde örnek programın mantığı anlaşılarak uygulama kodları kolaylıkla RC5 için uyarlanabilir.

Sony SIRC Protokolü

Sony SIRC protokolü Sony firması tarafından geliştirilmiş olan kızıl ötesi iletişim protokollerinden biridir. Kumandadan bir tuşa basıldığında 38-40 kHz frekansında demodüle edilmiş bir kare dalga sinyal gönderilmektedir. Yani eğer lojik ’0′ bilgisi gönderilecekse belirli bir frekansı olan işaret gönderilir lojik ’1′ ise hiç birşey gönderilmez. Aynı şekilde iki farklı frekans tanımlanıp her lojik durum için farklı bir frekans verici tarafından gönderilebilir. Bu tür sayısal haberleşme yöntemlerine ASK, FSK modülasyon denir. Üretilen bu modüleli sinyaller IR alıcı göz diye tabir edilen demodülatörlerden geçirilerek sayısal veri elde edilir. Elden edilen veri mikrodenetleyici veya kontrolöre gönderilerek iletişim sağlanır. Aşağıda şekilde Sony SIRC protokolüne ait ASK modüleli bit işaretleri görülmektedir.

sony-sirc-protokolu

Her protokolün kendine özgü bit zamanlaması ve paket yapısı vardır. Yukarıda resimde görüldüğü üzere Sony SIRC protokolünü kullanan bir kumandadan lojik ’1′ bilgisi göndermek için 1.2 ms taşıyı frekans(38-40kHz) ve 600 us boyunca sıfır gerilim seviyesi gönderilmelidir. Aynı şekilde lojik ’0′ bilgisi içinde 600 us taşıyıcı frekans ve 600 us sıfır gerilim seviyesi gönderilmelidir. Bu zamanlamaya bağlı kalarak verici kumandadan basılan tuş bilgisi alıcı tarafa iletilmektedir. Ayrıca iletişime başlamadan önce verici tarafından start sinyali gönderilmelidir. Sony SIRC protokolüne ait paket yapısı bu yapılardan oluşmaktadır. Aşağıda resimde protokolün detaylı yapısı görülmektedir.

sony-sirc-protokolu-detayli-yapisi

Görüldüğü üzere SIRC protokolü veri paketi 5 bit aygıt kodu 7 bit tuş kodu ve bir start biti olmak üzere toplamda 13 bitten oluşmaktadır. Örneğin tv kumandasından ses arttırma tuşuna bastığınız anda aygıt kodu olarak 1 tuş kodu olarak ise 18 bilgisi iletilmektedir. Bu şekilde gönderilen tuş bilgisi mikrodenetleyici tarafında alınarak hangi tuşa basıldığını ve hangi cihazın kumandası olduğu anlaşılabilir.

SIRC protokolünü daha detaylı inceleyecek olursa paket yapısında görüldüğü üzere veri gönderilmediği sürece hat lojik ’1′ durumundadır. İletişim başladığı anda start biti tarafından hat lojik ’0′ a çekilir. Bu sayede alıcı taraf iletişimin başladığını anlar ve start bilgisinin süresini ölçer. Eğer start bitinin süresi belirtildiği gibi 2.4 ms ise alıcı start bilgisi alındı kabul eder ve sonrasında gelen verileri almaya devam eder. Veri bitlerini yakalamak için her ardışık 2 yükselen kenar arasındaki veri süresi ölçülebilir. Eğer ölçülen süre 1.8 ms ise lojik ’1′, 1.2 ms ise lojik ’0′ olarak kabul edilir. Bu şekilde 12 bit veri alarak bir paketin alımı tamamlanmış olur.

MSP430 ile SIRC Paketlerini Çözümlenmesi

Her mikrodenetleyicinin yapısına ve çevresel birimlerine uygun şekilde tasarımına göre SIRC sinyallerini çözümlenmesi yapılabilir.

MSP430 denetleyicilerde ise TimerA modülünün capture(yakalama) özelliği kullanılarak kolaylıkla SIRC veri paketleri elde edilebilir.

İşlemin mantığı çok basittir. Öncelikle TimerA birimi düşen kenarları yakalamak üzere kurulur. Alıcı göz tarafından düşen kenar geldiğinde TimerA kesmesi oluşturulur ve yakalanan start bitinin süresi ölçülür ve TimerA yükselen kenarları algılayacak şekilde tekrar kurulur ve sayaç değişkenin içeriği sıfırlanıp kesme programından çıkılır. Sonrasında ilk düşen kenar geldiği anda tekrar kesme programı çağrılır ve iki kenar arasındaki süre ölçülür. Eğer ölçülen süre start biti süresine eşit ise iletişimin başladığı anlaşılır ve diğer gelen bitleri algılanmak üzere TimerA tekrar düşen kenarları yakalamak üzere kurulur ve sayaç değişkeni sıfırlanır. Start bitinin algılanmasından sonraki kesmeler de her iki ardışık yükselen kenar arasında ki süre ölçülür. Eğer ölçülen süre 1.2 ms ise veri biti lojik ’0′ 1.8 ms ise lojik ’1′ olarak algılanır ve hafızada saklanır.

MSP430 toplamda 12 bit veriyi elde ettikten sonra iletişimi bitirir ve aldığı veriyi 5 bit aygıt ve 7 bit tuş bilgisi olmak üzere ayırarak hafızaya kayıt eder. Sonrasında kaydedilen bu veri MSP430 uart modülü kullanarak 9600 baud hızından 8N1 formatında bilgisayara ASCII karakterler olarak gönderilir. Uygulama deneme amaçlı olduğu için alınan veriler bilgisayara gönderilmiştir. isterseniz aldığınız veriler ile kendi kontrol işlemlerinizi yapabilirsiniz yada bilgisayar tarafında aldığınız bu veri ile kumandan kontrollü bilgisayar programları yazabilirsiniz.

Sony SIRC Kızılötesi Decoder Uygulaması C Yazılımı


/****************************************************************
 * Proje : Sony SIRC Kızılötesi Decoder Uygulaması *
 * Yazar : Erhan YILMAZ *
 * E-posta : erhanyilmaz.ytu@gmail.com *
 * Tarih : 26.02.2013 *
 * Sürüm : 1.0 *
 ****************************************************************/

#include "msp430g2553.h"
#define IR_Mid 55 // 1500us @ 32768Hz ACLK
#define IR_Start 75 // 2300us @ 32768Hz ACLK
#define IR_Start2 82 // 2500us @ 32768Hz ACLK
#define IRIN BIT1 // IR input on P1.1
#define TXD BIT2 // TXD on P1.2
#define LED0 BIT0 // LED0 on P1.0
#define LF 0x0a // ASCII Line Feed
#define CR 0x0d // ASCII Carriage Return

unsigned char Device,Command,IRBit,IR_Received=0,TX_String[7];
unsigned int IRData,CCR0_Temp;

void IRReady(void);
void paket_gonder(void);

void main(){
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
TACTL = TASSEL0+MC1; // ACLK, continous
P1SEL |= IRIN + TXD; // P1.1 CCR0, P1.2=TXD
P1SEL2|= TXD; // P1.2=TXD
P1OUT |= IRIN; // P1.1 Pullup
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 104; // 1MHz 9600
UCA0BR1 = 0; // 1MHz 9600
UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine
IRReady(); // IR alım için timera'ı ve değişkenleri kur
__bis_SR_register(GIE); // Kesmeleri aç
while(1){ // Sonsuz döngü
if(IR_Received){ // IR veri alındı mı?
IR_Received=0; // Veri alındı bitini temizle
IRData &= 0x0fff; // Gelen veriyi maskele
Device = (unsigned char)((IRData >> 7) & 0x001f); // Gelen veriden aygıt bilgisini ayır
if(Device==1){ // TV kumandası mı?
Command = (unsigned char)(IRData & 0x007f); // Alınan veriden komut bilgisini ayır
TX_String[0] = Device/10+0x30; // Aygıt bilgisi onlar basamağını ASCII karaktere çevir
TX_String[1] = Device%10+0x30; // Aygıt bilgisi birler basamağını ASCII karaktere çevir
TX_String[2] = ' '; // İki veri arasına boşluk karakteri yerleştir
TX_String[3] = Command/10+0x30; // Komut bilgisi onlar basamağını ASCII karaktere çevir
TX_String[4] = Command%10+0x30; // Komut bilgisi birler basamağını ASCII karaktere çevir
TX_String[5] = LF; // Satır besleme verisi
TX_String[6] = CR; // Satır başı verisi
paket_gonder(); // Hazırlanan veri paketini uarttan gönder
}
IRReady(); // Tekrar alım için timera'ı ve değişkenleri kur
}
}

}

// TX_String karakter dizisini uarttan gönderen fonksiyon
void paket_gonder(void){
unsigned char i;
for (i=0;i<7;i++){
while (!(IFG2&UCA0TXIFG));
UCA0TXBUF = TX_String[i]; }
}

// IR Alım için timerA'yı ve değişkenleri kuran fonksiyon
void IRReady(){
IRData = 0; // Başlangıçte veriyi sıfırla
IRBit = 14; // Bit sayacını kur (2 start + 12 veri biti)
CCTL0 = CM1+SCS+CAP+CCIE; // CCTL0 birimini düşen kenarda kesme üretmesi için kur
}

// Timer A0 kesme programı
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{

TAR = 0; // TimerA sayacı sıfırla
CCR0_Temp = CCR0; // Ölçülen süreyi kaydet
if(IRBit == 14){ // İlk düşen kenar geldi mi? İletişim başladı mı?
CCTL0 = CM0+SCS+CAP+CCIE; // İlk düşen kenar ise timerı yükselen kenar yakalamak için kur
IRBit--; // Bit sayacını azalt
}
else if(IRBit==13){ // Start biti geldi mi?
if(CCR0_Temp > IR_Start && CCR0_Temp < IR_Start2) // Start bitini kontrol et
IRBit--; // Doğruysa bit sayacı azalt
else // Hatalı start biti ise iletişimi yeniden başlat
IRReady();
}
else{ // Veri gelmeye başladıysa
if(CCR0_Temp < IR_Mid) // Gelen veri süresini ER_Mid'ten küçük mü?
IRData &= ~0x1000; // Evet ise gelen veri '0'
else
IRData |= 0x1000; // Hayır ise gelen veri'1'
IRData = IRData >> 1; // Veri değişkenini 1 kaydır
IRBit--; // Bit sayacını azalt
if(IRBit == 0){ // Paket alımı tamamlandı mı?
CCTL0 = 0; // Alımı durdur
IR_Received = 1; // Veri alındı bayrağını set et
}
}

} // Kesme programı sonu

Yukarıda uygulamaya ait C kodları görülmektedir. Kodlar MSP430G2553 için yazılmıştır. IAR 5.20.2 sürümlü IDE üzerinde derleme yapılmıştır. Alıcı göz olarak eski uydu alıcılarından çıkma bir demodülatör kullandım. Piyasadan TK19 , SFH506 gibi alıcı gözler temin edilip kullanılabilir. Alıcı göz tarafından alınan veri “DD CC\lf\cr” şeklinde 7 karakterlik bir dizi halinde bilgisayara gönderilir. İlk iki karakter aygıt kodu sonrasında boşluk karakteri, sonrasında 2 karakter tuş kodu ve ardından satır besleme ve satır başı bilgileri gönderilir. Aşağıda resimden uygulamanın çalışma görüntüsü görülmektedir.

sony-sirc-protokolu-msp430g2553-yazilmistir-iar-5-20-2-ide

Herhangi bir seri port terminal programı kullanılarak MSP430 tarafından gönderilen veriler görüntülenebilir. Yukarıda şekilde görüldüğü üzere 01 verisi ardından tuş verisi gelmektedir. 01 kullanılan kumandanın tv kumandası olduğunu belirtmektedir. Diğer veri ise kumandadan basılan tuşun kodudur. Programı sadece TV kumandalarını algılayacak şekilde derledim. İstenirse küçük bir değişiklik ile istenilen cihazların kumandalarını algılamak için uyarlanabilir. Yaptığım denemelerde bazen hatalı veri alımı ile karşılaştım. Bunun nedenleri kullandığım alıcının eksi olması, launcpad’in 3.3v vermesi ve alıcı göz için 5 v gerekli olması yada yazılımsal zamanla ile ilgili sorunlar olabilir. Yeni bir alıcı göz ile harici 5 volt besleme kullanılırsa daha iyi sonuçlar alınabilir. Aşağıda Sony SIRC protokolüne ait aygıt ve tuş kodlarının listesi görülmektedir.

sony-sirc-protokol-command-adress-aygit-tus-kodlarinin-listesi

Sony tarafından belirlenmiş çeşitli aygıt ve tuş kodları bulunmaktadır. Sizde bu tabloya sadık kalarak kendi uygulamalarınıza kumanda kontrolü ekleyebilirsiniz. Aşağıda uygulamanın launchpad üzerinde gerçeklenmiş hali görülmektedir.

sony-msp430g2553-launchpad-timera-catpture

Alıcı gözler genellikle VCC,GND ve OUT bacağı olmak üzere 3 bacaklı üretilmektedir. Alıcının çıkış bacağı MSP430G2553′ün P1.1(TimerA Catpture pini) pinine bağlanmıştır. VCC ve GND pinleri aynı şekilde launchpad’in VCC ve GND pinlerine bağlanmıştır. Ayrıca hassas zamanlama gerektirdiği için kristal olarak 32.768 kHz kristal kullanılması gerekmektedir. Ayrıca 2553′ün uart pinleri farklı olduğu için launchpad uart modülü ile 2553 arasında resimde görüldüğü gibi çapraz bağlantı yapmak gerekmektedir. Bu şekilde devreyi kurup uygulamayı deneyebilirsiniz. Uygulama ile ilgili anlatacaklarım bu kadardır. Bu uygulama referans alınarak diğer protokollerin içinde uyarlanabilir. Yazı ile ilgili sorularını sorabilirsiniz elimden geldiğince cevaplamaya çalışırım. Bir sonraki yazıda görüşmek üzere inşaallah selametle..

  • Serhat

    Kolay gelsin. Msp430g2553 ile zaman ayarlı led yakmak istiyorum. Delay_cycle hesaplamasına göre 5 saniye için 80.000.000 çıkyor. ama Programı yazıp çalıştırdığımda Delay_cycle(6.000.000) civarı 5 saniye yakıyor.80000000 sayısı çok yüksek oluyor. Ben hesap hatası mı yapıyorum?

  • Özcan Özkan

    çapraz kullanmayı açıklaya bilir misin ?