C# - Serial Porttan veri alma hakkında fikrinize ihtiyacım var

Başlatan Hadi, 12 Şubat 2017, 14:29:23

Hadi

Herkese merhaba.

C# da bir program üzerinde çalışıyorum ve böyle bir sorunum var:

Bildiğiniz gibi Serial port veriyi byte byte gönderir ve uzun veriler bazen parça parça geliyor. Şimdi her seferinde gelen veriyi alıp bir öncekinin sonuna eklemek gelen verinin sanki tek sefer de gelmiş izlemini verir.
Ama benim sorunum şu ki gelen her verinin karşısında, geldiği zamanı da ekliyorum. Bu şekilde mecbur, veriyi parça parça göstermek zorunda kalıyorum. Bunun bir çözümü var mı?


Resimde de görüldüğü gibi 2. kez gelen picproje.org verisi ikiye bolunmuş şekilde gösteriliyor.


Not: veriyi sp.ReadExisting(); komutu ile alıyorum.

Diye bilirsiniz ki veriyi sp.ReadLine(); ile al ama verinin sonunda '\n' karakteri olmadığından veriyi göstermiyor ve '\n' karakteri gelene kadar tüm veriyi bekletiyor.

muhittin_kaplan


Hadi

Alıntı yapılan: muhittin_kaplan - 12 Şubat 2017, 16:02:18
readbyte

Bu tek byte almıyor mu ki? gonderilen verinin tamamını nasıl alabilirim? bir örnek verirmisiniz?

muhittin_kaplan

gönderilen bilginin hespsini aldığını nereden anlayacaksınız hocam (\n ile de olmaz diyorsunuz. Gönderirken Sonuna \n eklemeniz lazım.)
ya sonuna bir "bitti" ekleyeceksiniz (\n)
yada struct yapıp göndereceksiniz (lütfen arayınız "struct göndermek")

Hadi

Alıntı yapılan: muhittin_kaplan - 12 Şubat 2017, 19:21:54
gönderilen bilginin hespsini aldığını nereden anlayacaksınız hocam (\n ile de olmaz diyorsunuz. Gönderirken Sonuna \n eklemeniz lazım.)
ya sonuna bir "bitti" ekleyeceksiniz (\n)
yada struct yapıp göndereceksiniz (lütfen arayınız "struct göndermek")

Sıkıntı da burda zaten. ben alan kısmı yazıyorum gönderen kısmı değil.  :)

Cemre.

Gönderilen veri belirli bir yapıya sahip değilse (başlangıcı ve bitişi belli değilse, checksum gibi kontroller  yoksa) sisteminiz hataya açık demektir. Bunu kabul ediyorsanız misal gelen son byte'tan sonra yeni byte gelmesi için geçen süre 100ms'yi aşarsa veriyi yazdırır ve yeni satıra geçersiniz. Ne kadar sağlıklı olur bilmem.

muhittin_kaplan

veriyi alırken (örneğin 10 byte), araya başka bir thread girerse zaman uzar, @cemre  zaman kontrolü yapmak bir yere kadar garanti eder. sonrası hatalı davranır.

Hadi

Siz neden israrla gönderilen tarafla ilgileniyorsunuz anlamadım. heralde donanım forumu olduğundandır. neyse cevaplar için teşekkürler.  :)

Cemre.

Aslında gerekli açıklamayı yapmıştım. Gözden kaçtı herhalde.

foseydon

TL;DR yaşadığınız sorunun bir çözümü yok.

Siz muhtemelen veriyi, byteReceived() event'i geldiği zaman işliyorsunuz. C# seri port nesnesi, Microsoft'un C++ seri port kütüphanesi wrap edilerek hazırlanmıştır ve belli sorunları vardır. Biraz google araması yaparsanız bunları bulabilirsiniz. Buradaki sorun şu, donanım seri porttan tek byte veri yolluyor, bigisayar tarafında byteReceived() event'i ilk byte'ı aldığı zaman oluşuyor. Siz event'e gidip gelen veriyi işledikten sonra bu event temizleniyor. İşte bu arada geçen zamanda donanımınız veri yollamaya devam ediyor, bu gelen veriler bilgisayar tarafında serialport.buffer array'inde tutuluyor. Bu event sizin bütün veriyi almanızı garanti etmez, sadece en az 1 tane byte alınmış olduğunu garanti eder.

yapabileceklerinize gelelim.
1. iletişimi duplex hale getirebilirsiniz. yani donanım 1 byte yollar, bilgisayar donanıma veriyi aldığını belirten bir veri yollar, donanım bunu görünce 1 byte daha yollar. bu şekilde her seferinde tek byte almayı garanti edersiniz. mahzurları nedir bunun? veri yolunuzu gereksiz tıkamış olursunuz. iletişiminiz yavaşlayacaktır.
2. zaten veriyi belirli bir şekilde paketlemeniz gerekiyor, başlangıç bitiş byteları ve/veya checksum olan bir data frame kullanmanız gerekir. verinin doğruluğundan emin olmak için. bu durumda byteReceived() event'i geldiği zaman gelen byte'ları bir array içinde toplarsınız, ve yine bu event içinde en az 1 tane data frame var mı diye bakarsınız. data frame varsa, bunu işler, verileri ekrana bastırırsınız zamanı ile birlikte. bunun mahzuru ise verinin geldiği zaman tam olarak ekrana basamazsınız, arada çok çok ufak(milisaniye seviyesinde belki) bir fark olur. ama bu da kullanıcı açısından çok birşey farketmez.

erpay

Serial porttan gelen verilerin yanlış gelme ihtimali yüksek olduğu için bu tarz haberleşmelerde genelde checksum konulur. Bir alt derece de ise bir bitiş imi belirlenir. Yani donanım formu olmakla pek alakası yok. Belki de siz fazla yazılımcısınız :)

Hadi

Alıntı yapılan: erpay - 13 Şubat 2017, 00:49:05
Serial porttan gelen verilerin yanlış gelme ihtimali yüksek olduğu için bu tarz haberleşmelerde genelde checksum konulur. Bir alt derece de ise bir bitiş imi belirlenir. Yani donanım formu olmakla pek alakası yok. Belki de siz fazla yazılımcısınız :)

Fazla yazılımcı (zaten bişey olduğumu da iddaa etmiyorum) değilim sadece donanım kısmına müdahale edemiyorum. zaten kapalı kutu ben sadece gelen veri ile ilgileniyorum. orda da sıkıntı yaşadım soru sordum ama illa donanım tarafını değiştir diyorlar. cihaz kotu ya da iyi uretilmiş bi kere zaten yerli mal da değil ki suçlu arayalım ama gelen cevaplar verinin sonuna bişey koy, struct yapıp gönder, sistem hataya açık, geçikme ekle, checksum koy vb olunca anladım ki buradan bana cevap cıkmaz.  :)

sadogan

Alıntı yapılan: Hadi - 13 Şubat 2017, 01:02:25
gelen cevaplar verinin sonuna bişey koy, struct yapıp gönder, sistem hataya açık, geçikme ekle, checksum koy vb olunca anladım ki buradan bana cevap cıkmaz.  :)
Burdakiler bu işlerden anlamaz diyorsun yani.

Hadi

Alıntı yapılan: sadogan - 13 Şubat 2017, 01:09:07
Burdakiler bu işlerden anlamaz diyorsun yani.

;D

adını ne koyuyorsunuz koyun ama benim sorduğum soru açık.
veriyi alırken sıkıntı yaşıyorum. (veriyi alırken, gonderirken değil)
bunun cevabi, "öyle gonderme, boyle gönder" mi?  :)

sadogan

Almaya çalıştığınız veri yapısını biliyormusunuz.