18

EYL

2010

ATX34 ve ARX34 ile 433Mhz Kablosuz Haberleşme

Yazan: Barış Samancı
Kategoriler:Donanım, PIC

PIC 18F4685 ATX ARX 34

Bu yazımda şuan üzerinde çalıştığım bir projede geçici olarak kullanmak üzere aldığım 433Mhz bandında haberleşen ATX,ARX kablosuz alıcı ve verici modülleri test edeceğiz. Bu modülleri duymayan yoktur heralde.Kullandığım modülleri Udea’dan aldım.Datasheetlerine Udea’nın sitesinden ulaşabilirsiniz.

Modüller 433.92Mhz lik bir frekansta çalışmaktadır ve ASK modülasyon kullanmaktadır.Konuya biraz daha hakim olmak bakımından basit olarak ASK ve FSK modülasyonlara bir göz atalım. ASK modülasyonda sinyalin frekansı sabittir, genliği değiştirilir. Gönderilecek olan lojik mesajın seviyesine göre birden fazla genlik kullanılabilir.Uygulamamızda veriyi binary olarak gönderdiğimizden modülasyonda tek genlik kullanılmaktadır. Lojik 1 için A genliğinde bir sinyal gönderilirken lojik 0 için gönderilen sinyalin genliği 0 dır. FSK modülasyonda ise sinyalin genliği sabit olup frekansı değişmektedir.Lojik 1 için sinyalin frekansı artarken lojik 0 için frekans düşer.Aşağıdaki şekillerde ASK ve FSK modülasyon gösterilmiştir.


ASK FSK modülasyon

Teknik olarak fazla detaya girmeden modüllerin gereksinimlerini anlatıp direk olarak uygulama kısmına geçmek istiyorum. Modüller 433Mhzde çalışmaktadır. c / f bağıntısı ile modüllerin dalgaboyunu hesaplarız. Burada c ışık hızı, f ise çalışma frekansımızdır.Yaklaşık olarak 300/433 ten dalgaboyunu 0,693 metre buluruz. Dalga boyunuda 4 e böldüğümüzde kullanmamız gereken antenin boyunun 17.3cm olduğunu hesaplarız.Anten için 17.3cm uzunluğunda düz bir tel kullanabilirsiniz.

Modüllerin besleme gerilimi 5V tur. 2400 bauda kadar çalışmaktadırlar, üzerini denemedim. Modülleri alıp direk kablo ile seri haberleşiyor gibi haberleşebilirsiniz. Yanlız kablosuz haberleşme işin içine girince hiç beklenmedik sonuçlar doğmaktadır. Yaptığım denemelerde verici veri göndermediği halde alıcının sürekli olarak kendi kendine anlamsız değerler aldığını gördüm. Bulunduğum yerin elektromanyetik gürültüsü fazla sanırım :) Bu değerlerin alıcı tarafta hataya sebebiyet vermemesi için ve gönderilecek olan verinin sağlıklı gönderilebilmesi için çeşitli yöntemler kullanılmaktadır. En basitinden gönderilen veri “preamble + senkronizasyon + veri” şeklinde olmalıdır. Burada preamble olarak ardışıl bir şekilde “10101010” yada “01010101” değerlerini gönderebilirsiniz. Yukarıda hiç veri göndermediğim halde ortamda bulunan gürültüden dolayı alıcının veri aldığını söylemiştim. Gönderilen preamble ın amacı vericinin ortamda baskın hale gelerek alıcının kendisine senkronize olmasını sağlamaktır. Bu aşamadan sonra kullanıcının belirlediği senkronizasyon işareti ile verinin başlayacağı alıcıya bildirilmekte ve ardından veri gönderilmektedir. Ben senkronizasyon için 0x01 ve 0xFE değerlerini gönderdim.Alıcıda bu değerleri yakadadıktan sonra gelen veriyi RS232 üzerinden hyper terminale yazdırdım.Alıcı kısmında preamble kısmına bakılmaz.

Şimdi denemeleri yaptığım kodu inceleyelim. Verici kısmında preamble olarak 8 adet 0xAA değerini ardından senkronizasyon için 0x01 ve 0xFE değerlerini gönderdim. Bu değerler ve uzunluğu tamamen kullanıcıya bağlıdır. Yaptığım sonraki denemelerde preamble kısmının uzatılmasının daha iyi sonuçlar verdiğini gördüm. Alıcı kısımda ardışıl olarak gelen 0x01 ve 0xFE değerlerinden sonra bir bayrak set ettim ve bu bayrak 1 olduğu sürece gelen veriyi USART’a yazdırdım. İlerişimi sonlandırmak için ‘\0’ karakterini yani 0 değerini gönderdim.Bunu alan alıcı bayrağı temizleyerek ilk aşama olan senkronizasyon aşamasına dönmektedir.Kullandığım işlemciler 18F4685 ve derleyici C18 dir. Baud rate 1200 dür.

Verici Kodu

#include<p18f4685.h>
#include <stdlib.h>
#include <string.h>
#include <usart.h>
#pragma config OSC=HSPLL, WDT=OFF, MCLRE=ON, PBADEN=OFF, LVP=OFF

char SYNC[]={0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x01,0XFE};
char veri[]="Bu bir denemedir.";
char sayi[10];

void dizigonder(char * veri , int uzunluk)
{
	int i;
	for(i=0;i<uzunluk;i++)
	{	
		while(BusyUSART());
    		putcUSART(veri[i]);
	}
}

void main()
{
	int n=0;
	long int i;

	OpenUSART( USART_TX_INT_OFF &
		USART_RX_INT_OFF &
		USART_ASYNCH_MODE & 
		USART_EIGHT_BIT &
		USART_CONT_RX &
		USART_BRGH_HIGH,
		2082);

	TXSTA = 0x20;
	RCSTA = 0x90;
	BAUDCONbits.BRG16=1;

	while(1)
	{
		i++;
		if(i>100000)
		{
			i=0;
			n++;
			itoa(n,sayi);
			
			dizigonder(SYNC,10);
			dizigonder(sayi,strlen(sayi));
			dizigonder(veri,strlen(veri));
			
			while(BusyUSART());
			WriteUSART('\r');
			while(BusyUSART());
			WriteUSART('\n');
			while(BusyUSART());
			WriteUSART('\0');
		}
	}
}

Yukarıda görüldüğü gibi for döngüsünde yaklaşık bir saniye gibi aralıklarda “[X]Bu bir denemedir.\r\n” Verisi gönderilmektedir. Burada gönderilen X değeri tekrar sayısıdır, aşağıdaki şekilde görebilirsiniz. Şimdi alıcı kodunuda inceleyip haberleşmenin performansına bakalım. Alıcıda global olarak flag değişkeni tanımlanmıştır. Senkronizasyon yakalandığı zaman bu flag değeri 1 e set edilir aksi halde 0 dır. Verinin sonunun geldiğini belirten ‘\0’ karakteri yakalandığında flag değişkeni 0 değerini alır ve yeni senkronizasyon bilgisi aranır. Senkronizasyon sync() fonksiyonunda aranmaktadır. Ardışıl olarak her bir senkronizasyon değeri alındığında static d durum değişkeni bir arttırılır. Ardışıllık bozulursa durum değişkeni 0 lanır.Senkronizasyon sağlandıktan sonra alıcı, vericinin her gönderdiğini USART üzerinden bilgisayarımızdaki terminal programına yazmaktadır.

Alıcı Kodu

#include<p18f4685.h>
#include<usart.h>
#pragma config OSC=HSPLL, WDT=OFF, MCLRE=ON, PBADEN=OFF, LVP=OFF

int flag=0;

void sync(void)
{
	static int d=0;
	char c;

	switch(d)
	{
		case 0:
			c=ReadUSART();
			if(c==0x01)
				d++;
			else
				d=0;
			break;
		case 1:
			c=ReadUSART();
			if(c==0xFE)
				d++;
			else
				d=0;
			break;
	}

	if(d==2)
	{
		d=0;
		flag=1;
	}
}

void main()
{
	char c;

	OpenUSART( USART_TX_INT_OFF &
		USART_RX_INT_OFF &
		USART_ASYNCH_MODE & 
		USART_EIGHT_BIT &
		USART_CONT_RX &
		USART_BRGH_HIGH,
		2082 );

	TXSTA = 0x20;
	RCSTA = 0x90;
	BAUDCONbits.BRG16=1;

	while(1)
	{
		if(DataRdyUSART())
		{
			if(flag==1)
			{
				c=ReadUSART();

				if(c==0)
					flag=0;

				putcUSART(c);
			}
			else
				sync();
		}		
	}
}

Şimdi yukarıdaki kodların bilgisayardaki çıktısına bakalım. Aşağıdaki ekran görüntüsünde çıktı görülmektedir.

Görüldüğü gibi 2 metre uzaklıktan 115 gönderim denemesinin 20 si başarılıdır. Başarım oranı %17 dir. Çalışma ortamımdaki bozucu etkenlerin seviyesinin yüksek oluşundan dolayı bu sayının düşük çıktığını düşünüyorum. Ama fizik kitaplarındaki gibi kayıpsız ideal ortam bulamayacağımız için her koşulda çalışan bir sistem yapmamız gereklidir :)

Yukarıdaki görüntüden görüldüğü üzere gönderilen veri eğer preamble ve senkronizasyon başarılı ise sağlıklı bir şekilde alınmaktadır.Demekki haberleşmedeki kilit nokta burasıdır. Bunu düşünerek ikinci bir deneme yaptım. Bu denemede preamble kısmını bit bit değerlendirecek bir kod yazdım. Preamble daki 1 ve 0 değişimleri kesilip ardından en az yedi adet 0 ve ardından bir adet 1 gelmişse 0x01 değeri yakalanmış demektir. Bunun ardından 0xFE değeri yakalanıyorsa eğer senkronizasyon sağlanmış demektir. Bu denemede preamble olarak gönderdiğim 0xAA değerlerinide epeyce uzattıktan sonra Başarı iki katına çıkarak %35 oldu.Yukarıdaki örnekteki gibi aralıklar ile veri gönderecekseniz arkaplanda alıcıyı devamlı meşgul edecek çöp veriler gönderilmesinin daha olumlu sonuçlar vereceğini düşünüyorum.Denemelerimde 1200 ve 2400 baud kullandım ve aralarında iletişim kalitesi bakımından fark görmedim.

Eğer sistemler arası karakter katarı, yüksek miktarda veri, vs gönderecekseniz daha kaliteli anten kullanılması, yazılım ve haberleşme yönteminde iyileştirilme yapılması gerektiğini düşünüyorum. Benim böyle bir ihtiyacım olmadığından bu alandaki geliştirmelerimi bıraktım. Şuan çalıştığım bir projede sadece uzaktan kontrol amaçlı olarak bir bytelık veri gönderilmesi gerekmektedir. Verici devresinde tuş basılı tutulduğu sürece veri gönderdiğimden başarım oranı uygulamamda çok önemli olmamaktadır.

Ayrıca bu alıcı ve verici açık alanda 17cm lik tel anten ile yukarıda anlattığım bir bytelık veriyi yaklaşık 50m den (benim adımlarım ile tam 100 adım) hatasız bir şekilde gönderip alıyor.Uzaklık 50 metreden fazlaysada veri gönderiliyor ama hatalı alınmaya başlıyor.

Uygulamalarda kullandığım alıcı ve verici devrelerinde fotoğraflarını ekleyerek bu yazıyıda burda noktalayalım.

433Mhz ATX
Verici devresi (maxipaket'e bu güzel hediyeyi gönderdikleri için teşekkür ederim :) )

433Mhz ARX
Alıcı devresi

433Mhz ATX ARX

Yorumlar
taner
12 Oca 2012 Perşembe, 14:16 tarihinde yazmış.

slm calısmanız baslangıc olarak guzel ogrencilerin çozmede zorlandıkları onlara ufuk olacak en uzak mesafeye data gondermek için dijital veri kodlama sifrelemeler üzerine çalısmalar sergileyebilirseniz umuyorumki daha guzel olacaktır saygılar

Adınız *:
e-Mail Adresiniz *:  ??
Web Siteniz:
Yorumunuz *:
Kalan karakter sayısı: 500
 
 

Tasarım ve Programlama Barış SAMANCI
Her hakkı saklıdır.
barissamanci.net  ©  2010-2024