disket.net Beta
Konu Listesine Dön

PIC16F628A ile C'de RF alıcı-verici protokolü: Manchester kodlama sorunu

Programlama Açılış: 01.08.2026 01:00 3 Görüntülenme
Selam dostlar, uzun zamandır retro projelerle uğraşıyorum ve bu sefer kafayı taktığım bir konu var. Elimde birkaç tane PIC16F628A ve 433 MHz'lik ucuz RF modüller (FS1000A ve XY-MK-5V) var. Bunlarla basit bir kumanda/alıcı sistemi yapmak istiyorum. Ama işin içine Manchester kodlama girince takıldım kaldım. Şimdiye kadar hep assembly yazdım, C'ye yeni geçtim ve MPLAB X + XC8 derleyicisi kullanıyorum. Veriyi gönderirken her biti ikiye bölüp geçiş yaptırıyorum ama alıcı tarafta veri bozuluyor. Özellikle senkronizasyonu nasıl sağlayacağımı çözemedim. Başlangıçta bir preamble (başlangıç dizisi) gönderiyorum ama alıcı bunu algılamıyor. Osiloskopum yok, sadece logic analyzer var ama o da eski bir model, 24 MHz'den yüksek sinyalleri göremiyor. Modüllerdeki veri pinini doğrudan PIC'in RB0 pinine bağladım, kesme ile okumaya çalışıyorum. Ama sürekli yanlış veri alıyorum. Acaba direnç mi lazım, yoksa kod mu hatalı? Bir de XC8'de bit işlemleri için ne önerirsiniz, portB'nin tamamını okuyup maskeleme mi yapmalıyım? Şimdiden teşekkürler, yardımcı olursanız sevinirim.

Cevaplar (4)

Merhaba, öncelikle Manchester kodlama konusunda yalnız değilsin, ben de zamanında çok uğraştım. Önemli olan alıcıda örnekleme noktasını doğru ayarlamak. 433 MHz modüllerde veri hızını çok yüksek tutma, ben 2400 baud kullanıyorum ve sorunsuz çalışıyor. Preamble olarak 0x55 veya 0xAA gibi alternatif bit dizisi gönder, alıcıda bunu yakalayıp senkron ol. Ayrıca RB0'yı kesme ile okumak yerine, timer ile periyodik örnekleme yapman daha sağlıklı olur. XC8'de bit işlemleri için PORTB'nin tamamını okuyup & 0x01 ile maskele, bu en temiz yöntem. Bir de modüllerin veri pinine 10k pull-down direnç ekle, çünkü boşta iken seviye kararsız olabiliyor. Kodunu paylaşırsan daha detaylı bakabilirim.



Önemli olan alıcıda örnekleme noktasını doğru ayarlamak. 433 MHz modüllerde veri hızını çok yüksek tutma, ben 2400 baud kullanıyorum ve sorunsuz çalışıyor.



Aynen katılıyorum, 2400 baud ideal. Ama bir de şuna dikkat et: FS1000A modülünde veri pinine doğrudan PIC bağlamak yerine, bir transistör veya op-amp ile seviye dönüşümü yapman gerekebilir. Çünkü bu modüller 5V ile çalışıyor ama çıkışta bazen zayıf sürüyor. Ayrıca Manchester kodlamada her bitin ortasında geçiş olmalı, bu geçişi alıcıda timer ile yakalamalısın. Ben genelde bir byte'ı göndermeden önce 4 byte preamble (0xAA) ve 1 byte senkron baytı (0x2D) gönderiyorum. Alıcıda bu senkron baytını yakalayınca veri okumaya başlıyorum. Logic analyzer'da 24 MHz yeterli, çünkü 2400 baud'da sinyal zaten çok düşük frekansta. Bir de kesme yerine Timer0'ı kullan, her 208 mikrosaniyede bir örnek al (2400 baud için). Bu şekilde daha stabil olur.
Dostlar, bir de şu var: Manchester kodlamada alıcı tarafta bit süresini bilmen lazım. Eğer verici ve alıcı aynı kristali kullanmıyorsa, kayma olur. PIC16F628A'da iç osilatör kullanıyorsan, tolerans %1 civarındadır, bu da uzun paketlerde sorun yaratır. Ben harici 4 MHz kristal kullanıyorum ve 1200 baud'da hiç sorun yaşamıyorum. Ayrıca alıcıda veriyi okurken, her bitin ortasında değil, bit süresinin 3/4'ünde örnekleme yapmak daha güvenli. Yani 2400 baud için bit süresi 416 mikrosaniye, 312 mikrosaniyede örnek al. Bunu Timer1 ile yapabilirsin. Ayrıca RF modüllerdeki veri pinine seri bir direnç (100 ohm) ekle, parazitleri azaltır. Ve toprakları ortak yapmayı unutma, modülün GND'si ile PIC'in GND'si aynı olmalı. Logic analyzer'da göremiyorsan, bir LED ve osiloskop kadar iş gören basit bir devre kurabilirsin, veri hattına LED bağla, yanıp sönme hızından veriyi anlarsın.
Herkese çok teşekkürler, özellikle microknight11 ve segablaster27'in önerileri işe yaradı. Preamble olarak 0xAA gönderdim, alıcıda 0x2D senkron baytını yakalayınca veri okumaya başladım. Ayrıca Timer1 ile bit süresinin 3/4'ünde örnekleme yaptım ve 10k pull-down direnç ekledim. Şu an 2400 baud'da sorunsuz çalışıyor, veri bozulması tamamen bitti. segaspecter48'in dediği gibi harici kristal kullanmak da işi sağlamlaştırdı. Tekrar teşekkürler, sorun çözüldü!

Bu konuya cevap yazabilmek için retro topluluğumuza üye olmalı veya giriş yapmalısınız.

İlgili Konular & Benzer Paylaşımlar

PHP'de PDO ile MySQL bağlantısı neden hata veriyor? (Fatal error: Uncaught PDOException) Kategori: Programlama
ESP32'de FreeRTOS ile Task Önceliklendirme Sorunu - Watchdog Reset Yiyorum Kategori: Programlama
Turbo Pascal ile COM port üzerinden veri okurken program donuyor, yardım! Kategori: Programlama