PIC16F628A ile Infrared (Kızılötesi) (IR) Verici Led'den Veri Yaymak

Başlatan PIC16F, 23 Ekim 2016, 15:10:30

PIC16F

Yapmak istediğim şey; UART modülünü kullanarak PIC16F628A aracılığıyla IR Led'den veri yaymak...

void main() {


trisb.f0 = 1;
trisb.f1 = 1;
trisb.f3 = 1;
trisb.f4 = 1;
trisb.f5 = 1;
trisb.f6 = 1;
trisb.f7 = 1;
porta = 0;

//trisb.f2 yi 1 olarak ayarlamadım çünkü o pini TX bacağı olarak kullanıp IR LED in + ucuna bağladım.

UART1_Init(2400);

while(1){
          if (portb.f0){
                    while(!UART1_Tx_Idle());
                    UART1_Write(1);
          }
         
}

}


Devreden bahsedeyim;
PIC16F628A nın 5. pini GND'a; 14.pini +5V a bağlı.
8.pini ise IR Led in + ucuna bağladım.
IR Led in - ucu GND'a gidiyor...
RB0 a ise 1 aktif buton bağlı.

İstediğim şey 1 verisini göndermesiydi fakat Arduino üzerine kurduğum IR Alıcıdan verileri aldığımda karışık veriler geldiğini gördüm...
Yani kararlı bir veri gelmiyordu...

Benim istediğim; UART1_Write() fonksiyonu içerisine yazdığım byte ı kararlı bir şekilde gönderebilmesi fakat anladığım kadarıyla aldığı elektriğe göre karışık veriler yolluyor...

http://www.pictutorial.net/2016/01/ir-Infrared-Remote-Control-Communication-Between-Two-Microcontroller-Step-By-Step-Tutorial-Part-46.html adresinden aldığım şu kod da işe yaramadı:
 #define address  0xff
  #define command_1 0xFF
  #define command_2 0x81
  #define command_3 0x42
  #define command_4 0xC3
  #define command_5 0x24
unsigned int i=0,j=0;
void repeat(){
PWM1_Start();
delay_us(8000);
PWM1_Stop();
delay_us(8000);
}
  send_data_byte(unsigned char dattt){
   PWM1_init(36000);
PWM1_Set_Duty(127);
  for(j=0;j<8;j++){
PWM1_Start();
delay_us(562);
PWM1_Stop();
  if(dattt & 0x01){
  delay_us(1687);
  dattt=dattt>>1;
  }
else
  {
  delay_us(562);
   dattt=dattt>>1;
  }
  }
PWM1_Stop();
  }
  void send_data_command(unsigned char dat){
  PWM1_init(36000);
PWM1_Set_Duty(127);
PWM1_Start();
delay_us(9000);
PWM1_Stop();
delay_us(4500);
  send_data_byte(dat);
  repeat();
  }
void main() {
CMCON=7;
TRISA.F0=1;
TRISA.F1=1;
TRISA.F2=1;
TRISA.F3=1;
TRISB.F0 = 0;
TRISB.F3=0;
PORTB.F3=0;
PORTB.F0 = 0;

while(1){
  if(PORTA.F0==0){
  portb.f0 = 1;
send_data_command(command_2);
while(PORTA.F0==0){
repeat();
}
  }
  if(PORTA.F1==0){
send_data_command(command_3);
while(PORTA.F1==0){
repeat();
}
  }
   if(PORTA.F2==0){
send_data_command(command_4);
while(PORTA.F2==0){
repeat();
}
  }
    if(PORTA.F3==0){
send_data_command(command_5);
while(PORTA.F3==0){
repeat();
}
  }
}
}


Cevaplarınızı bekliyorum; teşekkürler.

ete

Usart dan 1 verisini yollarsan onun Ascii karşılığı olan 49 bilgisi yollanmış olur. Karmaşık dediğin bilgi bu olmasın.?
Ete

PIC16F

Demek istediğim, her butona basışımda farklı verilerin gelmesi. Sabit bir veri almıyorum.

ete

C dilinde çalışmadığım için soruna çok somut bir cevap veremiyorum. Okuyunca biraz anlayabiliyorum programı ve anladığım kadarı ile işini görecek program ikincisi. Sebebini açıklayayım.
Infrared denilen şey kızıl ötesi ışık anlamına geliyor ve maalesef gün ışığı içinde bir miktar kızılötesi ışık bulunuyor.
Bu nedenle IR sinyallerin gün ışığından olumsuz etkilenmeleri söz konusudur. Bir yerde sinyali bozma etkisi yaratırlar.
Bu olumsuz etkiyi ortadan kaldırmak için IR sinyal bir başka sinyal üzerine bindirilir. Bu üzerine bindirilen sinyalde protokolün cinsine göre 36 Khz den 40 Khz'e kadar değişen bildiğimiz bir kare dalga sinyalidir. Peki bindirme denilen şey nedir.?
Bu sorunun cevabına geçmeden geliştirilmiş protokollerde her bir data bitinin nasıl oluşturulduğu belirlenmiştir. Genellikle 2 bit ile ifade edilirler. Mesela senin 2ci programda NEC protokolü uygulanmış. Bu protokolde HIGH biti 560us lik bir HIGH ve peşinde 1690us lik bir LOW sinyali ile belirlenir. LOW Biti ise yine 560us lik bir HIGH ve peşine 560us lik bir LOW sinyali ile belirlenir.
IR_DATA bilgisinin %11001100 şeklinde olduğunu var sayarsak bu sinyalin 38Khz lik bir kare dalga üzerine bindirilmesi şöyle olur. (Soldan sağa doğru bitleri verelim)
1 biti için : 560 us süreli 38 Khz lik sinyal çıkışa verilir. Ardından 1690 us boyunca sinyal LOW yani sıfır seviyesinde sürer.
Dikkat edersen sinyalin 1 kısmı direk HIGH şeklinde değilde 38 Khzlik kare dalga şeklinde verilir.  Low kısmı ise sinyalsiz sıfır çıkışı şeklinde görülür. Bütün bitler bu esasa göre verildikten sonra sinyal tamamlanmış olur.
Ancak bu bilgilerin bir alıcı tarafından alınıp ne olduğunun çözülebilmesi için bir bilgi başı (Header) eklenmesi böylelikle bilgi paketinin başını bulunup ardından gelenlerin alınması kolaylaştırılmış olur. Nec protokolünde bu 9 ms uzunluğunda bir HIGH sinyali ardından 4,5ms uzunluğunda bir LOW siyali şeklindedir. Bu sinyal verildikten sonra data paketi peşine eklenir.
IR-GÖZ dediğimiz IR alıcı ise içinde yer alan devresi yardımı ile bu sinyalleri alır ve 38khz lik kare dalgayı sabit HIGH sinyaline çevirerek dışarı verir. Bir farkla, devredeki çıkış transistör nedeni ile IR-GÖZ gelen sinyalleri ters çevirerek dışarı verir. Bunu alıcıda dikkate almak gerekir.
Örnek datamızın %11001100 olduğunu varsaymış idik. Bu bilgi vericiden aşağıdaki şekilde çıkacaktır.
ters çevrilmiş Header+Data Paketi yani 9ms LOW+4,5ms HIGH + 560us LOW+1,69ms HIGH+ 560us LOW+1,69ms HIGH+ 560us LOW+560us HIGH+ 560us LOW+560us HIGH+ 560us LOW+1,69ms HIGH+ 560us LOW+1,69ms HIGH+ 560us LOW+560us HIGH+ 560us LOW+560us HIGH
Alıcının öncelikle bu kodu çözebilmek için baş tarafta bulunan 9ms lik LOW ve ardından gelen 4,5ms HIGH sinyalini yakalaması gerekir. Sonra peşinden gelenleri alarak onları ayıklaması gerekiyor. Bu işte laf kalabalığı çok ama işlem öyle anlatıldığı gibi zor değildir. Normalde data paketleri arasında verilirken uzunca bir LOW (bu gözden çıkınca HIGH olarak gözükür) ardından header gelir. Bu nedenle düşen kenar kesmesi yaratılarak haderin ilk low kısmı yakalanmalıdır. Yakalandıktan sonra kesme içinde 1 adet 4,5us lik HIGH sinyali alınıp süresi ölçülmeli ve şayet doğru ise peşinden gelen dataların sadece HIGH kısımları süre olarak kayıt edilmelidir. Sonra bu süreler 560 us den büyük ise data biti HIGH 560 a eşit yada küçük ise Data biti LOW dur diye karar verilmelidir. Hepsi bu kadar.

Şimdi ikinci programa bakılırsa 36 Khz lik bir PWM sinyali yaratılıyor ve buna %50 duty veriliyor. Aslında NEC protokolü 38 Khz ile çalışıyor 36 burada biraz yanlış olmuş. Sonra anlayamadığım bir kısım geliyor. Data bilgisi bitlerine göre işlem yapılması gerekirken (Dattt değişkeni) bunun bitlerini nasıl ele aldığını anlamadım. Burada bir eksiklik var gibi geliyor bana.
Bu sitede benim verdiğim NEC protokolünü okuma programı mevcut. Bizzat denediğim için çalıştığınıda söyleyebilirim. Ama basic de yazılmıştır program. Verici kısmı için bir şey yapmadım sanırım. Standart Infrared vericileri kullanmıştım.
Ama yapmasıda zor değil mantık senin ikinci program mantığı ama oda çok açık değil benim için. Ama ben olsam şu şekilde bir algoritma kurardım;
Dattt=%11001100 olsun. Öncelikle programda 38Khz lik bir PWM sinyali oluşturup buna %50 duty değerini verirdim. Ama sinyali çıkış pininden lazım olunca çıkartacağım için çıkış kapalı beklerim.
Önce header sinyalini verirdim. Bunun için PWM=on yapıp 9ms süresinde HIGH verip PWM=off yaparım ve 4,5ms bu konumda bekledikten sonra ilk data bitini verirdim. Bitleri sağdan sola doğru vereceğiz.
Dattt.0 biti=0 olduğu için, 560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 5600us bekle.
Dattt.1 biti=0 olduğu için , 560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 560us bekle.
Dattt.2 biti=1 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 1690us bekle.
Dattt.3 biti=1 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 1690us bekle.
Dattt.4 biti=0 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 5600us bekle.
Dattt.5 biti=0 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 560us bekle.
Dattt.6 biti=1 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 1690us bekle.
Dattt.7 biti=1 olduğu için,  560us HIGH yani PWM=on 560us bekle pwm=off ve ardından 1690us bekle.
şeklinde bilgiyi verirdim.
Burada önemli olan Dattt değişkeninin bitlerine C dilinde ulaşmak yada onları test edebilmek. Basic de bu kolay Dattt.0
  • index değişkeni kullanarak ve buna 0-7 arasında değer vererek kolaylıkla bunu yapabiliyoruz. C dilinde nasıl yapılıyor bilmiyorum. Programda da buna ait bir bölüm göremedim. Olsa olsa hata burada olabilir.
    Anlatacaklarım bu kadar.  Ancak son anda farkettimki senin amacın dahada başka. Sen bir protokole bağlı kalmaksızın USART modülünden bu bilgileri IR led yardımı ile çıkartayım karşıdan da bunu alayım istiyorsun. Bir yerde kablosuz IR alıcı verici kullanarak seri haberleşme yapmak istiyorun. Ben bu şekilde anladım amacını. Bunu yapmak elbette biraz daha zor.
    Zira sistem gün şığından etkilenecektir. Etkilenmemesi için sinyali diğer sinyal üzerine bindirmen gerekecek. Bunu yapıncada USART gelen bilgileri çözemeyecektir. Belkide çözer IR göz çıkışını direk RX pinine girersen olabilir. Ama verici tarafını nasıl halledeceksin. Ufak bir hile uygulaman gerekir. Mesela, bir iki girişli bir AND kapısı kullanarak girişin birine 38Khz lik PWM sinyalini ki bu sinyal sürekli çıkış verecek şekilde tutulmalıdır. Diğerine de TX pininden gelen ucu bağlayacaksın. Böylece seri data kodlanmış yani modüle edilmiş dataya çevrilecektir. And kapısının çıkışınıda bir IR lede uygun seri direnç ekleyerek verdinmi kablosuz sistemin hazır demektir. Tabiiki siyali uzun mesafelere aktarmak için arada transistör kullanmak akıllıca olur. Unutma koyduğun her transistör sinyali ters çevirir. Zaten verdiğin şekilde bir sinyal alabilmek için verici tarafında AND kapısından sonra bir transistör kullanman doğru olacaktır. Bu sinyali ters çevirecek ve IR göz alıcı tarafında da bir kez daha ters çevirerek sinyalin verildiği şekilde çıkmasını sağlayacaktır. Bu şekilde TX pininden yollanan veri kablosuz olarak alıcıaki RX pinine aktarılmış olacaktır. Sistemin doğru çalışabilmesi için data paketi başına uyandırma sinyali eklenmesi gerekir.

    Ete

    not: sonradan farkettimki aşağıdaki komut satırları dattt değişkeninin bitlerini test etmekte kullanılıyor.
    if(dattt & 0x01){
      delay_us(1687);
      dattt=dattt>>1;
    önce 1 ile dattt değişkeni and yapılıyor şayet bit0=1 ise 1687 us gecikme, sıfır ise 562us gecikme uygulanıyor. Sonra dattt değişkeni 1 bit sağa kaydırılarak tekrar sıfır nolu bit test ediliyor ki bu aslında 1 nolu bit olmuş oluyor. Böylece hepsi test edilmiş oluyor.

Powered by EzPortal