NI Ürünleri İle İlgili Tartışmalar

cancel
Showing results for 
Search instead for 
Did you mean: 

Seri port dinleme (okurken data kaçırıyorum)

Solved!
Go to solution

Merhaba .. Seri port ile bilgi alışverişi yaparken bilgi gönderdiğim kısım sadece bilgi göndermiyor aynı zamanda başka işlemleri de yapmak zorunda oldugundan  okudugum verileri kaçırıyorum. almam gereken 2 tane 8 bitlik data var  bunları alırken  bazen sırasını kaçırıyorum. haliyle birleştirince datam bozulmuş oluyor.

Bunun için bir port kontrolu varmı acaba. Sadece veri geldiği zaman port açıp okuyup kapatabilecek.başka durumlarda port okuma yapmayacak.

 

 

kullandığım program gönderiyorum.(ekte bulunuyor.)

 

açıklama : programın case kısmında B ve C harflerini gönderince yapması gerekenler bulunuyor. o kısımlara çok fazla takılmayın.çıkartılabilir

0 Kudos
Message 1 of 7
(10,638 Views)

Merhaba,

 

Seri iletişimde "sadece veri gelince portu açmak" gibi bir yaklaşım mümkün değildir.

 

İletişim yapacağınız süre boyunca portunuz devamli açık olmalıdır.

 

Size gelen veriler içeride geldiği sırada bir buffer'da tutulur.

Siz kodunuzda okuma yaptığınızda aslında bu buffer'dan okursunuz.

 

Bu nedenle veri kaçırmanız, çok yüksek bir hızda çok fazla veri gelmiyorsa, hatanın sebebi olmayabilir.

 

Önce verilerin size doğru sırada gönderildiğine emin oldunuz mu?

Kodunuzdaki (incelyemediğim için bilmiyorum) bir bug sebebiyle de değişken değerleri karışıyor olabilir.

 

S. Eren BALCI
IMESTEK
0 Kudos
Message 2 of 7
(10,636 Views)

Eren Bey'in dediklerine tümüyle katılıyorum. Paylaştığınız kodu da gözden geçirdim ve ana yapıyı hatalı oluşturduğunuzu söyleyebilirim.

 

Labview örnekleri içerisindeki "Basic Serial Write and Read.vi" kodunu incelemenizi tavsiye ederim. Bu örnekte öncelikle yazma sonra cevap almak için bekleme ve porttaki veri uzunluğuna göre bu verileri okuma adımları sırasıyla verilmiştir.

 

Eğer port okuma kod parçasının bağımsız çalışmasını istiyorsanız bu kodu ayrı bir "thread" olarak yazmanız gerekir. Bu da o kod parçasının Labview içerisinde ayrı bir "While" döngüsü içerisinde yazılmasıyla kolayca gerçekleştirilebilir. Ancak yazacağınız diğer kod port okuma ile doğrudan ilişkili ise aynı döngüde kullanmanız daha doğru olacaktır. Hız konusunu ise daha sık okumak yerine daha uzun veri parçacıkları okuyarak halledebilirsiniz.

0 Kudos
Message 3 of 7
(10,632 Views)

Mehabalar, 

Bende size Advanced Serial Write and Read.vi example ını incelemenizi tavsiye ederim. Orada seri port ayarlarını yaparken, "termination char" diye bir bölüm mevcut. Bu kısıma A(0xA) yazdığınız taktirde labview bunu \n olarak algılayacaktır ve her gönderdiğiniz satır sonunda karşılıklı olarak bekleyecektir. Eğer bir mikrodenetleyici ile seri iletişim yapmaktaysanız, zaten okumak isteyeceğiniz "B" ve "C" karakterleri bilgisayara ASCI değerleri olarak gelecektir. Kodunuzuda bu şekilde düzenlemeniz gerekebilir. Aynı zamanda şunu belirtmek isterim ki, mikrodenetleyiciden gönderdiğiniz "merhaba/n" komutunu doğrudan string olarak algılayabilirsiniz.

 

Ekte dediğim örneği gönderiyorum, termination char ile dediğim düzgün okumayı sağlayabilirsiniz, ayrıca aldığınız değeri, doğrudan string olarak zaten görebileceğiniz gibi, üzerinde işlem yapmak için asci karşılıkları üzerinden gidebilirsiniz.

 

umarım faydalı olmuştur.

sevgiler

-- 
Kaan ALPER
Bahcesehir University
Technology Development Center

Message 4 of 7
(10,629 Views)

Örneği inceledim.belki bekleme süresi eklersem düzelebilir diye düşünüyorum.ms nin altında bekleme eklemek için nasıl bir parçacık kullanmak gerekir?

 

microişlemciden hesapladığım kadarıyla ortalam 20 ila 30 us arasında bekleme koymuş olsam bir nebze yakalama işini yapabilirim diye düşünüyorum.

0 Kudos
Message 5 of 7
(10,620 Views)
Solution
Accepted by topic author Seyf

Buradaki bekleme, mikroişlemcinin işlem yapma süresinden ziyade sistem cevap süreleri, aradaki bilginin porta yazılması okunması esnasında veri aktarımı için gereken süreler olarak düşünülebilir. Dikkat edilecek nokta sisteminiz bu bekleme süresinden önce cevabı porta gönderebilmiş olmalıdır.

 

Bunu da genelde şu şekilde yaparız. Varsayalım porta komut yazdınız ve arkasından 10ms bekleme eklediniz. Daha sonra porttaki verinin uzunluğunu yada sonlandırma karakteri ile veri aktarımının bitip bitmediğini kontrol ettiniz (okuma işleminde ister sonlandırma karakterlerini esas alın ister belirli uzunluğa göre kontrol yapın bu sizin seçimizdir) ve istediğiniz verinin henüz hazır olmadığını gördünüz. Öyleyse bir döngü içerisinde 2nci bir 10ms bekleme olacak şekilde yeni bir bekleme süresince bekleyip portu tekrar kontrol edersiniz. Bu işlemi istediğiniz veri gelinceye yada belirlediğiniz zaman aşımı süresine göre tekrarlayabilirsiniz. İstediğiniz veri tamamsa işlemi gerçekleştirir değilse bir hata durumunu ele alıp değerlendirmenizi yaparsınız.

 

Eğer veri uzunsa, sık haberleşme yapmak yerine uzun verileri bitişik halde almak daha doğru olacaktır. Açıklamak gerekirse, diyelim 1Mbit/sn ile haberleşme yapabilen bir ara biriminiz var. Bu ara birim 1Mbit lik bir paketi 1 sn içerisinde iletilebiliyor anlamını çıkarabiliriz ancak aynı donanım ile 1 milyon kere sorgulama yapıp 1er bitlik verileri 1 sn içerisinde almanız mümkün olmayacaktır. Donanımlar veri aktarımında çok yinelenmeyen işlemleri istenilen boyutta gerçekleştirebilir. Aynı durum veri toplama kartları için de geçerlidir.

0 Kudos
Message 6 of 7
(10,615 Views)

Merhabalar;

 

Bildiğim kadarıyla normal Windows işletim sistemleri altında, programlama araçlarının erişebildiği Windows Timer'ı fonksiyonu 1ms. çözünürlüktedir, dolayısıyla LabVIEW gibi programlama ortamlarında 1ms'nin altında Wait fonksiyonuna doğrudan erişemeyeceğinizi düşünüyorum.

(bkz. http://en.wikipedia.org/wiki/System_time#Operating_systems)

 

(Belki Intel'in ya da AMD'nin özel işlemci kütüphaneleri kullanılması ile daha düşük çözünürlüklü beklemeler -örneğin interrupt (kesme) tabanlı - yaratılabilir, ancak böyle bir yöntemi şahsen denemediğim için yapılabilirliği konusunda şüphelerim var).

 

Öte yandan, sorununuza çözüm olabilmesi adına, yazılımsal senkronizasyon (el sıkışma -handshake-) yerine donanımsal bir senkronizasyonu deneyebileceğinizi düşünüyorum. Tipik masaüstü bilgisayarların seri portlarındaki XON/XOFF ya da Hardware gibi yöntemlerle senkronizasyona olanak sağladıklarını biliyorum. Eğer geliştirmiş olduğunuz mikroişlemci kartınızda da bu yöntemlerden herhangi birine destek varsa, bu yönde deneme yapabilirsiniz.

 

Son olarak, donanımsal senkronizasyon mümkün olmazsa; yazılımsal olarak çift yönlü veri gönderme - karşı taraftan onay alma yönteminin kullanılabileceğini düşünüyorum. Örneğin sırasıyla PC aynı veriyi sürekli gönderir - mikroişlemci onay verir ardından mikroişlemci aynı veriyi sürekli gönderir - PC onay verir; ve bu döngü bu şekilde devam ettirilebilir. Belki veri transfer hızında düşüş olacaktır ama sonuca hizmet edebileceğini düşünüyorum.

 

 

Kolaylıklar dilerim.

 

Candan

(Bay) Candan CANER
National Instruments Türkiye
0 Kudos
Message 7 of 7
(10,601 Views)