18 Kasım 2015 Çarşamba

Çanak veya uydu antenini kumanda ile değiiştirme

Sevdiğim bir arkadaşıma yeni televizyon aldık, kendi dahili uydu alıcısı DVB S2 ile geldi. Arkadaşım zaten paralı bır kanala, sanırım dijitürk üye. Evinde 1 adet uydusu var bunu hem dijitürke hemde televizyona baglamak istiyor.

Yukardan da anlaşılacağı gibi uydu, çanak ve benzeri sistemlerin bağlantılarından fazla anlamam.

Aylar sonra beni görünce dert yakındı dijitürk ile her kanalı izleyemiyormuş (teknik servis çabaları fayda vermemiş) diğer kanalları izlemek için televizyona her seferinde uydu girişini dijitğrkten söküp bağlıyormuş.
Uydudan anlayan birisi splitter kullan demiş, gelen kabloyu bölüp 2 çıkış yapmış ama ikisi bağlı olduğu zaman ikiside çalışmıyormuş.
Disecq ilede çözüm bulamamışlar, televizyon dahili alıcısını kapatmadığı için sorun oluyormuş.

Bu iş için düşündüğüm en basit çözüm 3 uçlu anahtar kullanmaktı. 'Ortak' uç 'normalde kapalı' ve 'normalde açık' uçları ile şaseler ortak olacaktı. Anahtar konumu değişince 'canlı uç' değişecekti.
Ama elimde olan malzemelerle daha iyisini neden yapmamayım dedim.

Elimde olan malzemeler
USB Digispark (arduino uyumlu)
5v Relay SCM250VAC 10A (5v arduınio/USB uyumlu)
InfraRed alıcı TL1838 VS1838B 38Khz (5v arduınio/USB uyumlu)
Basit iki konumlu aç kapat düğmesi



Digispark ne ola
USB Digispark oldukça ucuz ve can sıkıcı bir ürün :) bir sürü kütüphane eklemek gerekiyor, geri bildirim için klavye simülasyonu kullanıyor ve üstelik doğru dürüst çalışmıyor. Çok küçük projeler için belki kullanılabilir. Çok seçici, her USB ile çalışmıyor (boot bile olmuyor)



Infrared ne ola
Daha önce hiç kumandadan gelen sinyanlleri okumamıştım ve nasıl olduğuna dair pek fikrim yoktu, İşin aslı halen pek yok ama bu proje için kullandığım kadar kısmını anlatayım. Uzaktan kumanda ile basılan tuşlar InfraRed (kızıl ötesi spektrumlu) LED ile dijital olarak gönderiliyor. Bunu mors alfabesine benzetmek mümkün. --.--...-..--...-..-- gibi..
Televizyonlar için kullanılan belirli bir IR standardı yok, benim evimdeki denediğim kumandalarda farklı kodlamar ile karşılaştım.  Yani benim kumandam ile sistem çalışıyor sizinkinin çalışmasına garanti veremem :) kullandığımız elamanın adı xxxxxx IR LED ile gönderilen verileri okuyor.



Relay ne ola
Bir anahtar devresi basitçe aç, kapat düğmesidir. 3 ucu vardır. Bendekinde ortadaki uç ortak. Vereceğmiz komuta göre sol veya sağ düğme konum değiştiriyor. Relay kullanmamın nedeni etliyi ve sütlüye birbirine karıştırmamak için.
Ardiuno 5v ile çalışan kendi halinde bir devre. Uydu ise kendi ayrı beslemesı olan 13 15 18volt olabilen apayrı bir sistem yani bizim uydudan gelen voltajla hiç münasebetimiz olmamalı bu yüzden Relay kullanıyoruz.
Relay temiz iş yapar ve devremiz ile uydu ayrı hatlardır tamamen bir birinden izoledirler



Basit aç kapat düğmesi
Eski fareden çıkma 'Normalde kapalı' formunda bir anahtar düğmesi. Bu düğmenin toprak hattına bir direnç bağlamak iyi olacaktır ama zaten toplam 1 .2 kez kullanialacağı için ben kullanmadım.

Muhafaza
Yine elimde olan malzemeleri kullandım. Hmm elimde 3 boyutlu yazıcı var o yüzden en iyisini yaptım :)

Çalışma mantığı
Digispark açılışı 5 saniye kadar sürüyor. Daha sonra EEP ROM da kayıtlı A ve B tuşlarını okuyor. Bundan sonrasında hep Infrared alıcıdan gelen bilgileri okuyoruz eğer gelen sinyal A veya B ile uyuşuyorsa Relay diğer konuma geçiyor.
Eğer A ve B kayıtlı değilse veya değiştirmek istersek düğmeye basarak kayıt moduna geçiyoruz bu modda durum LED i yanıp sönerek yeni tuşa basmamızı istiyor seçtiğim iki tuşu veya iki kere aynı tuşa basarak A ve B yi EEP ROM hafızaya saklıyoruz.

Kısaca kumandadan seçtiğimiz bir tuşa basında otomatık olarak uydu tv veya dijitürk arasında geçiş yapıyor.




Daha fayla detay ve bacak bağlantıları kod içinde


#include <EEPROM.h>

/* kaynak
 * http://www.ediy.com.my/index.php/blog/item/74-digispark-infrared-receiver
 */

int ledPin = 1; //digispark 1 nano 13
int irPin  = 2; //Sensor pin connect to digital pin2 (ATINY85 pin7)
int rlyPin = 4; //relay pin
int btnPin = 0; //VCC ile switch HIGH

/*
  eğer yeterince ısrarcı olursanız, olmayan kumandayı
  bu değerleri kurcalayarak olur haline getirebilirsiniz
*/
int start_bit = 3000; //Start bit threshold (Microseconds)
int repeat_bit = 1700; //Repeat bit threshold (Microseconds)
int bin_1 = 900; //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)
const byte BIT_PER_BLOCK = 32;

int activeKeyA =- 1;
int activeKeyB =- 1;
int rlyPos = HIGH;  //high relay kapali


///////////////////////////////////////
//
///////////////////////////////////////
void setup()
{
  pinMode(ledPin, OUTPUT); //LED on Model A
  pinMode(irPin, INPUT);
  pinMode(btnPin, INPUT);
  pinMode(rlyPin, OUTPUT);
  activeKeyA = EEPROM.get(0, activeKeyA);
  activeKeyB = EEPROM.get(2, activeKeyB);
  //Serial.begin(9600);
  //Serial.print("store A:");
  //Serial.println(activeKeyA);
  //Serial.print("store B:");
  //Serial.println(activeKeyB);

  digitalWrite(rlyPin, rlyPos);
  //digitalWrite(btnPin, HIGH);
}


///////////////////////////////////////
//
///////////////////////////////////////
void ledState(int state, int dly){
  digitalWrite(ledPin,state);
  delay(dly);
}


///////////////////////////////////////
// decode infrared signal
///////////////////////////////////////
int getIRKey() {
  int data[BIT_PER_BLOCK];
  int i;

  int test = pulseIn(irPin, HIGH);
  if(test > start_bit) //tests for the 4.5 ms start bit
  {
    for(i = 0 ; i < BIT_PER_BLOCK ; i++)
      data[i] = pulseIn(irPin, HIGH); //Start measuring bits, I only want HIGH pulses

    delay(100);
    for(i = 0 ; i < BIT_PER_BLOCK ; i++) //Parse them
    {
      if(data[i] > bin_1) //is it a 1?
        data[i] = 1;
      else if(data[i] > bin_0) //is it a 0?
        data[i] = 0;
      else
        return -2; //Flag the data as invalid; Return -2 on invalid data
    }
 
    //based on NEC protocol, command data started from bit 16
    //and end with bit 24 (8 bits long)
    int result = 0;
    for(i = 16 ; i < 24; i++) {
      if(data[i] == 1) result |= (1<<i-16); //Convert data bits to integer
    }
    return result; //Return key number

  }
    else if(test > repeat_bit) return -1; //Tests for the 2.5 ms repeat bit and sends -1 if true
    else return -1; //Tests for the 2.5 ms repeat bit and sends -1 if true
}


///////////////////////////////////////
//
///////////////////////////////////////
int waitAndStoreKey(){

  ledState(HIGH,0 );

    int key = getIRKey();      //Fetch the key

    while (key < 0){
      key = getIRKey();
    };

  ledState(LOW, 0);
  //Serial.print("Captured key:");
  //Serial.println(key);
  return key;
}

///////////////////////////////////////
//
///////////////////////////////////////
void loop()
{
  int key = getIRKey();      //Fetch the key

  if (key == activeKeyA || key == activeKeyB)
  {
    rlyPos = not rlyPos;
    digitalWrite(rlyPin, rlyPos);
    ledState(HIGH, 60);  
    ledState(LOW, 60);
    ledState(HIGH, 60);  
    ledState(LOW, 60);
    ledState(HIGH, 60);  
    ledState(LOW, 60);
    ledState(HIGH, 60);  
    ledState(LOW, 60);
  }
  else if (key > 0)
  {
    //Serial.print("key pressed :>");
    //Serial.println(key);
    ledState(HIGH, 200);  
    ledState(LOW, 200);
  }


  if (digitalRead(btnPin) == HIGH)
  {
       activeKeyA = waitAndStoreKey();
       EEPROM.put(0, activeKeyA);
       delay(250);
       ledState(HIGH,250);
       ledState(LOW,250);
       ledState(HIGH,250);
       ledState(LOW,250);
       activeKeyB = waitAndStoreKey();
       EEPROM.put(2, activeKeyB);
       delay(250);
  }
 
}