Proton'da RF seri iletişim sorunu!

Başlatan alayli, 29 Mayıs 2006, 16:34:17

alayli

Sevgili arkadaşlar;

PDS'de 433 MHz modüllerle tek taraflı seri iletişim içeren bir proje ile uğraşıyorum. Fakat günlerdir çözmeyi başaramadığım bir sorunum var...

Projede bir verici ve bir de alıcı var. Vericinin işi sadece buton bilgisini göndermek. Üzerindeki iki butondan birine basınca manchester kodlamayla paket gönderiyor o kadar. Fakat alıcı kısımın iş yükü daha ağır ve belirli zaman aralığında RF alıcıdan gelen dataya bakıp tekrar diğer rutinlere dallanmasını istiyorum. Verici ve alıcıdaki ilgili kodlar şöyle:
Verici 16F675
...........

Symbol SEND = GPIO.0
.........
........
..........
For X =  0 To 2
SerOut SEND, 18030, [$55,&55]
Next

SerOut SEND, 17197, ["YE", SW_M, ID0_M , HP0_M , ID1_M , HP1_M , SW_M ,0]
.................
.................
.................


Alıcı 16F876

..............
....................
Symbol RECEIVE = PORTB.1
....................
...........................
...........................
..........................
SerIn RECEIVE, 17197, 100 ,SiL, [Wait ("YE") , SW_M1, ID0_M , HP0_M , ID1_M , HP1_M , SW_M ]
.................................
................................
..............................


Burada alıcının serin komutunu icra ettiğinin haricindeki diğer işler simulasyonda yaklaşık 70ms'lik bir zamanda halloluyor. Yani programın serin'e geldiğinde 100ms içinde bir data gelmez ise diğer kısma dallanmasını istiyorum. Fakat RF alıcı modül işi yokuşa sürüyor. Bu modüllerin çıkışında bulunan parazit (Sürekli ve anlamsız 1 0 değişimi) programın serin komutunda çakılmasına sebep oluyor. RF verici ve alıcı modülleri devreden çıkarıp direkt kablo bağladığımda sorun yok. 100ms içinde bir data gelmeyince progran "SiL" etiketine dallanıyor. Ama RF modülleri bağlayınca sürekli değişen 1 0 girişi nedeniyle (anladığım kadarıyla 100ms boyunca RX pininin 0 da kalamaması serin komutunu ve benim şart koştuğum 100ms süreyi sürekli tetikleyip resetliyor) Kod içindeki "Wait ("YE"), " belirleyicisini kaldırdığım zaman programın SeRin komutunda çakılması sona eriyor. Fakat bu defa da haberleşmede data bozuk alınıyor. Parity ve CRC' yi de denedim ama nafile. Zaten sıyırmıştım balataları yakında erken 90000 km bakımına girmem gerekecek galiba...

Olayı interrupt ile halletmeyi de denedim fakat bu defa da sürekli interrupt oluşturuyor RF alıcı modül ve sonuç: Serin komutunda çakılma...

Bu konuda PDS ile çalışmış benzer soruna çözüm üretebilmiş kimse var mı? Yada sevgili arkadaşlarımın bir çözüm önerisi olabilir mi.  

Şimdiden teşekkürler ve saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

bsivgin

bence seri portu RF uygulamasında kullanma onun yerine patterni sen oluştur derim...


saygılarımla
Bülent ŞIVGIN
www.diyot.com

alayli

Alıntı yapılan: "bsivgin"bence seri portu RF uygulamasında kullanma onun yerine patterni sen oluştur derim...


saygılarımla
Bülent ŞIVGIN
www.diyot.com

Sevgili bsivgin;

Burada hardware usart kullanmıyorum zaten. PDS'nin 14 bit pic lerle çalışabilen seri haberleşme komutunu kullanıyorum sadece. (Daha doğrusu kullanmaya çalışıyorum) Zaten burada bir pattern sözkonusu. Wait ("YE") den sonra alınan veya "YE" den sonra gönderilen tüm data içinde machester kodlama var ve data $FF yada $00 da olsa sürekli 1 de veya sürekli 0'da kalmıyor. Bu patterni çözme işini asm ekleyerek yaptığımda sorun yok. Ben işe hiç asm karıştırmadan sadece basic ile çözmenin bir yolu var mıdır diye uğraşıyorum. Sözkonusu patterni basic ile alıp çözen kod örnekleri çok işimi görürdü...

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

mmengi

Öncelikli sıkıntın RF modülden gelen sürekli değişen 1 0, daha doğrusu boşta iken devamlı bir gürültü olması bunu engelleyemezsin basit modüller ile dolayısıyla gönderici kısım belli bir süre bir header gönderip yaklaşık 2-3 ms. ve alıcı bu header dediğimiz sürekli 1 i aldığında arkasından data geldiğini anlayacak ve data alma moduna geçecek. Böylelikle sen bu gürültülere aldırış etmeyeceksin sen hep bahsettiğim 2-3 ms. lik header i bekleyeceksin eğer bu yoksa hiç data alımına başlamayacaksın. Bunun için pulsin komudunu çok rahatlıkla kullanabilirsin hatta bütün datayı bu pulsin komutları ile bile alabilirsin hiç serin yada HW usart ı kullanmadan ve daha sağlıklı olur bu şekilde. Bir şey daha pulsin komutu aksi bildirilmediği sürece 65ms ölçüm yapmaya çalışır bu süreyi kısaltmak için

"declare PULSIN_MAXIMUM 500" mesela 5ms. boyunca sinyal varsa ölç yada ölçeceğin sinyal 5ms den kısa ise bunu tanımla. Bu süre 1 ve 0 için geçerlidir.

alayli

Alıntı yapılan: "mmengi"Öncelikli sıkıntın RF modülden gelen sürekli değişen 1 0, daha doğrusu boşta iken devamlı bir gürültü olması bunu engelleyemezsin basit modüller ile dolayısıyla gönderici kısım belli bir süre bir header gönderip yaklaşık 2-3 ms. ve alıcı bu header dediğimiz sürekli 1 i aldığında arkasından data geldiğini anlayacak ve data alma moduna geçecek. Böylelikle sen bu gürültülere aldırış etmeyeceksin sen hep bahsettiğim 2-3 ms. lik header i bekleyeceksin eğer bu yoksa hiç data alımına başlamayacaksın. Bunun için pulsin komudunu çok rahatlıkla kullanabilirsin hatta bütün datayı bu pulsin komutları ile bile alabilirsin hiç serin yada HW usart ı kullanmadan ve daha sağlıklı olur bu şekilde. Bir şey daha pulsin komutu aksi bildirilmediği sürece 65ms ölçüm yapmaya çalışır bu süreyi kısaltmak için

"declare PULSIN_MAXIMUM 500" mesela 5ms. boyunca sinyal varsa ölç yada ölçeceğin sinyal 5ms den kısa ise bunu tanımla. Bu süre 1 ve 0 için geçerlidir.

Bu bordu gerçekten çok seviyorum... :D  Çok çok sağol dostum mmengi! Zihnimde şimşeği çaktırdın ya sağolasın sen. Bir header ekleyip bunu pulsin ile okuyup dallanmayı burada gerçekleştirmek güzel fikir. Şu an pratikte deneme şansım yok ama (ki simulasyonda zaten eski haliyle de sorun yoktu.) yüksek ihtimalle çalışacağını düşünüyorum. Yalnız tüm patterni pulsin ile çözmek için bit boyutunda array tanımlamak lazım. PBP buna izin veriyor ve eskiden PBP de yaptığım bu komutları (PULSOUT ve PULSIN) kullanan bir uygulamam vardı. Bunu Proton a aktarmak mümkün olmuyor çünkü Proton da bit boyutlu array tanımlayamıyoruz. Neyse uzatmadan kodları şöyle değiştirmeyi ve çalışacağını düşünüyorum. Yarın işyerimde pratikte de deneyip sonucu burada belirtirim.

Verici taraf 12F675
........... 
.............
Symbol SEND = GPIO.0 
......... 
........ 
.......... 
For X =  0 To 2
SerOut SEND, 18030, [$55,&55] '600 baud'da 6 adet $55'i preamble olarak gönder
Next

DelayMs 4  'çıkış 4 ms 0'da bekler. Header için...

SerOut SEND, 17197, ["YE", SW_M, ID0_M , HP0_M , ID1_M , HP1_M , SW_M ,0] 
................. 
................. 
.................


Alıcı taraf 16F876
.............. 
....................
Declare PULSIN_MAXIMUM 500 'gelen 0 palsini max 5 ms bekle
Dim HEADER as BYTE 
Symbol RECEIVE = PORTB.1 
.................... 
........................... 
........................... 
HEADER = Pulsin RECEIVE, 0 'sıfır palsinin süresini oku ve header adlı değişkene değeri yaz
If HEADER >= 300 Then 'eğer sıfır palsinin değeri büyük eşit 3 ms ise (ki burada verici 4 ms sıfır palsi gönderiyor. Fazladan 1 ms if then döngüsüne yeter.
HEADER = 0
SerIn RECEIVE, 17197 [Wait ("YE") , SW_M1, ID0_M , HP0_M , ID1_M , HP1_M , SW_M 'komutu icra et (zamanaşımına burada dikkat edilmiyor. bir üst komutta zamanaşımı işliyor.[/I]
Else
goto SiL  'header alınamazsa SiL isimli etikete git diğer işleri icra et...
EndIf 
................................. 
................................ 
..............................


Sanırım yukarıdaki haliyle sorunum hallolacak. Tekrar sağolasın mmengi kardeşim. Hem bu modifiyede RF datanın gelip gelmediğini kontrol etmek için eski halinde 200ms oyalanırken burada sadece 5 ms oyalanıp diğer rutinlere dönecek program... :)  :)
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

mmengi

Alıcı kısımı bit boyu sayarak şöyle yapabilirsin :

Header=pulsin porta.2,1
	  	
	IF Header < 420 Then Return	   
    IF Header > 490 Then Return	   

	For bit_count=0 to 31	
	bit_value=pulsin porta.2,1
	

	IF bit_value > 80 AND bit_value< 120 Then 
	setbit Packet,bit_count
	elseIF bit_value > 30 AND bit_value < 70 THEN
 	clearbit Packet,bit_count
	ELSE
	RETURN
	ENDIF
	Next


header=4.5 ms
1 Bit= 1ms.
0 bit= 0.5ms

alayli

Alıntı yapılan: "mmengi"Alıcı kısımı bit boyu sayarak şöyle yapabilirsin :

Header=pulsin porta.2,1
	  	
	IF Header < 420 Then Return	   
    IF Header > 490 Then Return	   

	For bit_count=0 to 31	
	bit_value=pulsin porta.2,1
	

	IF bit_value > 80 AND bit_value< 120 Then 
	setbit Packet,bit_count
	elseIF bit_value > 30 AND bit_value < 70 THEN
 	clearbit Packet,bit_count
	ELSE
	RETURN
	ENDIF
	Next


header=4.5 ms
1 Bit= 1ms.
0 bit= 0.5ms

Sevgili mmengi;

Örnek kod için teşekkür ederim. setbit ve clearbit komutlarını kullanmak hiç aklıma gelmemişti. Bir zamanlar PBP'de olduğu gibi index kullanacam diye uğraşıp durmuş, didinmiştim. Neyse tekrar teşekkür ederim. Şu an tüm kodu değiştirmek (özellikle alıcıda) işime gelmiyor. Yukarıdaki verdiğim örnek kod ve serin komutu ile şansımı tekrar denemek istiyorum. En son çare pulsin'i verdiğin bu kodu uyarlayarak kullanabilirim. Fakat sürekli 1 veya sürekli 0 göndermeyip manchester kodlama yaptığım için serin'de de sorun çıkacağını sanmıyorum. Senin bu konuda (Serin komutuyla RF seri data alımı) hatırı sayılır bir mağduriyetin oldu mu? Mesela ne sorun çıktı? Hatalı data iletimi?.. Menzil kaybı?..vb. vb.

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

alayli

Arkadaşlar;

Yukarıda öngördüğüm kod çalışmadı. Sazan gibi atladım hemen ama kafa üstü çakıldım. Senkronu tuturmak tesadüfe kalıyor orada...

@mmengi'nin tavsiyesine uyup (bilen sözü dinleyip) kodu PulsIn komutuna uyarlıyacam...

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

mmengi

Serin ile yada usart komutları ile havadan data aktarımı biraz sıkıntı yani standart 8n1 seri iletişim yapmaya kalkınca mesafe çok düşüyor ve hatalı alım olabiliyor. Çünkü belli bir baud hızında bitlerin süreleri son derece hassas olmak zorunda ama ucuz yollu rf modüller ile data aktarımı sırasında bit sürelerinde bariz sapmalar var bunun için dikkat edersen örnek kodda bit sürleri belli bir limit içinde olduğunu görürsün kendine oluşturacağın bu yapı ile çok sağlıklı max. mesafeye data aktarabilirsin.

Kolay gelsin.

OG

Alıntı YapSerin ile yada usart komutları ile havadan data aktarımı biraz sıkıntı
Evet üstadın dediği gibi bu komutların kodlarını direk çıkışda görmek istiyorsanız, hızınız da yeterince düşükse standart FSK kullanmanız gerekir. FSK da 1700Hz, 2400Hz gibi 2 ayrı sinyal ile modülasyon vardır. Fakat modülasyonda kesinti olmadığından alıcıda da çıkışda kesinti olmaz. Hangi frekans alınıyorsa ona göre data üretilir. Bunu elde edebilmek için modem gerekir. Yani eski bir yöntem.

Manchester kod ile açık örnek vermek imkanınız varmı?
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

alayli

Alıntı yapılan: "alayli"Arkadaşlar;

Yukarıda öngördüğüm kod çalışmadı. Sazan gibi atladım hemen ama kafa üstü çakıldım. Senkronu tuturmak tesadüfe kalıyor orada...

@mmengi'nin tavsiyesine uyup (bilen sözü dinleyip) kodu PulsIn komutuna uyarlıyacam...

Saygılar...

Sazan gibi atlayıp çakıldıktan sonra, şöyle bir titreyip kendime geldim ve çakılma nedenimi biraz irdeledim ve çözüm buldum. Şu an senkronu PulsIn ile tutturup, hemen arkasından SerIn komutunu icra ettirince iletişimde sorun olmuyor ve program SerIn komutunda çakılmıyor. Ama "belli bir baud hızında bitlerin süreleri son derece hassas olmak zorunda ama ucuz yollu rf modüller ile data aktarımı sırasında bit sürelerinde bariz sapmalar var bunun için dikkat edersen örnek kodda bit sürleri belli bir limit içinde olduğunu görürsün kendine oluşturacağın bu yapı ile çok sağlıklı max. mesafeye data aktarabilirsin" şeklindeki uyarıyı da atlamak olası değil... Kulağıma küpe yaptım bile...

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

bsivgin

assambly de yazmıştım ama sayfanın en altına eklediğim notlar belki çabalarına katkısı olur.

http://www.diyot.com/RF.html

saygılarımla
Bülent ŞIVGIN

alayli

Alıntı yapılan: "OG"
Alıntı YapSerin ile yada usart komutları ile havadan data aktarımı biraz sıkıntı
Evet üstadın dediği gibi bu komutların kodlarını direk çıkışda görmek istiyorsanız, hızınız da yeterince düşükse standart FSK kullanmanız gerekir. FSK da 1700Hz, 2400Hz gibi 2 ayrı sinyal ile modülasyon vardır. Fakat modülasyonda kesinti olmadığından alıcıda da çıkışda kesinti olmaz. Hangi frekans alınıyorsa ona göre data üretilir. Bunu elde edebilmek için modem gerekir. Yani eski bir yöntem.

Manchester kod ile açık örnek vermek imkanınız varmı?


Sevgili OG;
Uyarın için teşekkür ederim. Aslında olayı biraz daha açsam daha iyi olacak galiba... Yapmaya çalıştığım şey "Hopping Code" yöntemine benzer bir yöntemle data aktarımı ve öğrenmeli RF UK yapmak. Onun haricinde SerIn komutunda ısrar etmemin sebebi; gönderilen ve alınan data paketi boyutunu çok pratik olarak değiştirebiliyor olmam. Senkronu tutturup SerIn'e dallandıktan sonra programda alınan ve gönderilen bit sayısını arttırıp azaltmak için çok uğraşmak gerekmiyor... Köşeli parantezin içine yazılan tanımlı bir değişken ismi yetiyor datayı göndermek için. Datayı 8N1 formatında gönderiyor olsam da hiç bir zaman ard arda 8 bit dijital 1 veya dijital 0 olamıyor. Burada sorun çıkartabilecek tek şey mmengi arkadaşımın bahsettiği "bit sürelerindeki sapmalar" olabilir kannatindeyim. Ama sürekli 1 ve 0 devinimi bu olumsuz etkiyi giderebilir diye de geçmiyor değil içimden. Deneyip göreceğim. İşin mantığını kod ile açıklamaya çalışmak daha yerinde olacak sanırım.

Verici:
Device = 12F675
XTAL 4
Config WDT_OFF,PWRTE_OFF,BODEN_OFF,CP_OFF,MCLRE_OFF,XT_OSC
ALL_DIGITAL = 1
Dim HPNG As Word  'HOPPING CODE SAYAÇ DEĞİŞKENİ
Dim ID As Word    'KUMANDA KİMLİK NUMARASI
Dim HP1_M As Word 'KODLANMIŞ HOPPING CODE SAYICISININ İKİNCİ BYTE'I
Dim HP0_M As Word 'KODLANMIŞ HOPPING CODE SAYICISININ İLK BYTE'I
Dim ID1_M As Word 'KODLANMIŞ VERİCİ KOD NO İKİNCİ Byte'I
Dim ID0_M As Word 'KODLANMIŞ VERİCİ KOD NO İLK BYTE'I
Dim MANCH As Word '16 BIT'LİK ENCODER GEÇİCİ DEĞİŞKENİ
Dim X As Byte
Dim SW_M As Byte
Dim BYTEIN As Byte '8 BIT'LİK ENCODER GEÇİCİ DEĞİŞKENİ
Dim BCOUNT As Byte 'ENCODER BIT SAYAÇ DEĞİŞKENİ

Symbol BUTON1 = GPIO.1
Symbol BUTON2 = GPIO.2
Symbol SEND = GPIO.0  
Symbol CARRY = STATUS.0 '
		
TRISIO = %00111110		
'--------------------------------------------------------------------

EData	5,0
DelayMS 100
SEND = 0
ID.LowByte = ERead 0
ID.HighByte = ERead 1
HPNG.LowByte  = ERead 2
HPNG.HighByte = ERead 3
DelayMS 20

MANCH = 0
BYTEIN = 0
BCOUNT = 0
SW_M = 0
X = 0



BASLA: 
If BUTON1 = 1  Or BUTON2 = 1 Then
DelayMS 20' BUTON TİTREŞİM GECİKMESİ
Inc HPNG
EWrite 2 ,[HPNG]
GoTo MAIN
Else
GoTo BASLA
EndIf

MAIN:
BYTEIN = ID.LowByte
GoSub ENCODE
ID0_M = MANCH

BYTEIN = ID.HighByte
GoSub ENCODE
ID1_M = MANCH

BYTEIN = HPNG.LowByte
GoSub ENCODE
HP0_M = MANCH

BYTEIN = HPNG.HighByte
GoSub ENCODE
HP1_M = MANCH

BYTEIN = GPIO & %00000110
GoSub ENCODE
SW_M = MANCH.LowByte

For X =  0 To 3
SerOut SEND, 18030, [$55]'
Next
High SEND
DelayMS 3
Low SEND
For X = 0 To 3
SerOut SEND, 17197, ["YE", SW_M, ID0_M , HP0_M , ID1_M , HP1_M , SW_M ]
Next
DelayMS 5
GoTo BASLA
End

ENCODE:
BCOUNT = 8 ' 8 bits per byte
EN_REPEAT: ' Create a loop for all the bits
rol BYTEIN ' Rotate in order to test the CARRY flag
If CARRY = 1 Then ' Bit to convert = 1 ? 
rol MANCH , Set ' Place '1' into manchester bytes
rol MANCH , Clear ' Place '0' into manchester bytes
Else ' Bit to convert = 0 
rol MANCH , Clear ' Place '0' into manchester bytes
rol MANCH , Set ' Place '1' into manchester bytes
EndIf 
djnz BCOUNT , EN_REPEAT ' Close the loop 
Return


Alıcı:
Device = 16F628
XTAL=4
Config INTRC_OSC_NOCLKOUT , WDT_OFF , PWRTE_ON , BODEN_OFF , LVP_OFF , CP_OFF ,MCLRE_OFF 
ALL_DIGITAL = True
PULSIN_MAXIMUM 330
LCD_DTPIN = PORTB.4	
LCD_RSPIN = PORTB.3
LCD_ENPIN = PORTB.2
LCD_INTERFACE = 4
LCD_LINES = 4
LCD_TYPE = 0
Print $FE,$40,$04,$0E,$04,$04,$04,$04,$0e,$00   'İ DATALARI
Print $FE,$48,$0E,$10,$10,$0E,$01,$05,$1E,$04   'Ş DATALARI
Print $FE,$50,$0E,$11,$10,$10,$10,$15,$0E,$04   'Ç DATALARI
Print $FE,$58,14 ,14 ,17 ,16 ,23 ,17,14,0       'Ğ DATALARI
Dim X As Byte
Dim SW_M As Byte
Dim SW_M1 As Byte
Dim SW As Byte
Dim SW1 As Byte
Dim BYTEOUT As Byte '8 BIT'LİK DECODER GEÇİCİ DEĞİŞKENİ
Dim BCOUNT As Byte 'ENCODER BIT SAYAÇ DEĞİŞKENİ
Dim HEADER As Word
Dim ID As Word
Dim ID0_M As Word 'KODLANMIŞ VERİCİ KOD NO 1
Dim ID1_M As Word 'KODLANMIŞ VERİCİ KOD NO 2
Dim HP0_M As Word 'KODLANMIŞ HOPPING CODE SAYICISININ İLK BYTE'I
Dim HP1_M As Word 'KODLANMIŞ HOPPING CODE SAYICISININ İKİNCİ BYTE'I
Dim MANCH As Word '16 BIT'LİK DECODER GEÇİCİ DEĞİŞKENİ
Dim HPNG As Word 'HOPPING CODE SAYAÇ DEĞİŞKENİ
Symbol RECEIVE = PORTB.1
Symbol CARRY = STATUS.0 ' Alias the CARRY flag
CMCON=7
DelayMS 100 ' Wait for PICmicro to stabilise
BYTEOUT = 0
MANCH = 0
Cls
DelayMS 30
DIGER_ISLER:
DelayMS 100 ' BU ESNADA ALICI DİĞER RUTİNLERİ ÇALIŞTIRACAK VE YAKLAŞIK 70 ms GİBİ TUTUYOR FAZLADAN BİR 30 ms PAY DA BIRAKTIM... 
GoTo REC
End
 


REC:
For BCOUNT = 0 To 30 
HEADER = PulsIn RECEIVE, 1 'sıfır palsinin süresini oku ve header adlı değişkene değeri yaz 
If HEADER > 280 And HEADER < 320 Then 'eğer bir palsinin değeri  3 ms civarında ise 
HEADER = 0
GoSub SERIAL  
EndIf
Next
GoTo DIGER_ISLER

SERIAL: 
SerIn RECEIVE, 17197, [Wait ("YE") , SW_M1, ID0_M , HP0_M , ID1_M , HP1_M , SW_M] 
MANCH = ID0_M
GoSub DECODE                                                          
ID.LowByte = BYTEOUT

MANCH = HP0_M
GoSub DECODE
HPNG.LowByte = BYTEOUT

MANCH = ID1_M
GoSub DECODE
ID.HighByte = BYTEOUT

MANCH = HP1_M
GoSub DECODE
HPNG.HighByte = BYTEOUT

MANCH = SW_M
GoSub DECODE
SW = BYTEOUT

MANCH = SW_M1
GoSub DECODE
SW1 = BYTEOUT

Print At 1,1,"ID:", DEC5 ID, "  SW:" , DEC1 SW
Print At 2,1,"ID:", BIN16 ID ' Display the 16-bit WORD in binary
Print At 3,1,"HP:", DEC5 HPNG, "  SW1:", DEC1 SW1' Display the 8-bit BYTE in binary
Print At 4,1,"HP:", BIN16 HPNG 
Return

DECODE: 
BCOUNT = 8 ' 8 bit pairs to convert
DE_REPEAT: ' Create a loop for all the bits 
rol MANCH ' 1st bit determines result bit
rol BYTEOUT ' Rotate CARRY flag into BYTEOUT
rol MANCH ' skip unused 2nd bit 
djnz BCOUNT , DE_REPEAT ' Close the loop
Return


Kodları yukarıdaki haliyle kopyala yapıştır yapıp PDS'de derlerseniz çalışıyor. Aşağıdaki linkten Proteus dizayn dosyasını da indirebilirsiniz.

http://groups.yahoo.com/group/elektronik_sebil/files/      içinde TX_RX.zip

Bu kod deneme amaçlı alıcı olarak 16F628'i kullandığım basit bir haberleşme. Dediğim gibi yukarıdaki haliyle çalışıyor ve haberleşiyor. Pratiğe gerçek malzemelerle de döktüm ve sorun yok.

Sevgili OG'un sorduğu manchester kodlama ve kod çözme işlemlerini vericide ENCODE, alıcıda da DECODE alt rutinleri yapıyor. Dikkat ederseniz, burada; her bir WORD tipi değişkenin alt ve üst baytları ayrılıp teker teker decode ve encode ediliyor. Yani 8 bitlik %00000000 şeklindeki bir bayt 16 bitlik %0101010101010101 şekline çevrilip gönderiliyor. Böylelikle her ne kadar 8N1 formatında data gönderilse de sürekli 1 0 devinimi sağlanıyor...

İş pratiğe döküldüğünde paket gönderiminin her hangi bir anında kullanıcı butondan elini çekince -ki bu esnada header gönderilmiş, senkron sağlanmış ve "YE" belirleyicisi de alıcı tarafından alınmışsa ardından giden bilgi hatalı gidiyor. Ama buna yazılım ve donanımda muhtelif çözümler bulunabilir.  Mesela ben buton bilgisini hem başta hem de sonda gönderiyorum bu ikisi eşit değilse date onaylanmıyor. Ek olarak CRC ve parity de eklenebilir. Zaten alıcıda paket alındıktan sonra bir sürü karşılaştırma ve koşul işlemi sıralamayı planlıyorum. ID'nin alıcının öğrendiği ve belleğinde yer alan bir ID ile uyuşması şartı. İlgili ID'ye ait hopping code değişkenin daha önce kayıtlı olandan küçük bir rakam olmaması, belirli bir pencere aralığında bu rakamın denetlenmesi (Mesela 00010 ID numaralı verici, en son 32455 nolu hopping kodu göndermişse bunun altındaki ve 128 fazlası olan kodlar kabul edilmez diğer kodlar kabul edilir.) Kullanıcının alıcının menzilinin dışındayken 128'den fazla kez butona basıp bırakması halinde kumandanız alıcı tarafından bir daha kabul edilmez ve yeniden tanıtılması gerekir. Bu pencere arlığını arttırıp azaltmak sizin elinizde...

Bu arada burada sadece "YE" şeklindeki belirleyici, standart 8N1 formatında gidiyor. Bunu da manchester kodlayıp, alıcının belirleyicisini de uygun değere değiştirmek mümkün... Yada bu da sürekli 1 0 devinsin diye "UU" veya "33" vb. değerlerle değiştirilebilir. (ASCII U = %01010101, ASCII 3 = %00110011)

Kod bu haliyle tüm uygulamalar için çalışır demek yanlış olur. Alıcıdaki öğrenme rutinleri ve karşılaştırma rutinleri eklenince daha sağlıklı çalışacağı inancındayım. DIGER_ISLER kısmında zamanın uzaması yada kısalması durumuna göre zamanlama optimizasyonu gerekeceği (senkron beklenilen for next döngüsü mesela) aşikardır...

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)

OG

Sevgili alaylı alici tarafını derledi ama bende şu hatayı verdi;

*** DJNZ is a multi instruction macro! ***


"DJNZ is a multi instruction macro! "

Neden olabilir.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

alayli

Alıntı yapılan: "OG"Sevgili alaylı alici tarafını derledi ama bende şu hatayı verdi;

*** DJNZ is a multi instruction macro! ***


"DJNZ is a multi instruction macro! "

Neden olabilir.

Dostum;

O hata mesajı değil sadece hatırlatma mesajı. ASM'deki warning benzeri. O mesaja rağmen hiç sorunsuz çalışıyor kod. ENCODE ve DECODE alt programlarında en alt satırda return den hemen önce kulanılan bir makro komutu djnz.

Bu arada hatırlatayım: Proteus dosyası 6.7 SP3 de kaydedildi ve düşük versiyonlarda çalışmaz...

Saygılar...
Anca kazganmiş itmiş ilimiz törümüz erti. Türk Oguz begleri budun esiding. Üze tengri basmasar, asra yir telinmeser, Türk budun, ilingin törüngin kim artati? (udaci erti)