C# 'da SerialPort Readline işlevi gelen verileri atlıyor.

Başlatan Mucit23, 14 Temmuz 2022, 11:20:47

Mucit23

Selamlar

Şöyle bir sorunum var. C# da seri port ile 4-5kb string veri aktarıyorum PC'ye, Her bir string değişken uzunlukta. Fakat her birinin sonunda '\n' satır sonu karakteri var. Verileri alıyorum ama örneğin 2000 satır veri gönderiyorsam arada atladıkları oluyor ve bana ulaşan 1000-1100 civarı.

Readline değilde ReadExisting ile denedim ama bu fonksiyonda birkaç satır veriyi yarım yamalak birleştirip öyle dataRecieved Eventine gidiyor. Fakat bu şekilde veri atlama yapmıyor.

Baudrate değerim normalde 115200 ama düşük badurate ile denedim yine Readline'daki sorunu yarattı.

Yüksek hızda ard arda veri almak için nasıl bir yöntem uygulamak gerekiyor?

serdararikan

Okuma işlemi için kendi ring buffer ınızı oluşturun. C# ın datareceiveBuffer ına güvenmeyin

Mucit23

Byte byte okumak istedim.  *String# şeklinde gönderim yaptım. Bu şekilde de verileri atlıyorum.
                byte RxByte = (byte)serialPort1.ReadByte();
                if (serialport_state == false)
                {
                    if (RxByte == '*')
                    {
                        RxBuffer[RxIndex] = RxByte;
                        serialport_state = true;
                    }
                }
                else
                {
                    RxIndex++;
                    RxBuffer[RxIndex] = RxByte;
                    if (RxByte == '#')
                    {
                        RxBuffer[RxIndex + 1] = (byte)'\0';
                        RxIndex = 0;
                        serialport_state = false;
                        
                        RxString=Encoding.ASCII.GetString(RxBuffer);
                    }
                   
                }

Gelen verilerin %20'sini anca alıyorum. Bu yavaş çalışmanın sebebi nedir?

Sabit veri uzunluğuna geçip SerialPort.Read() fonksiyonunu deneyeceğim birde.

dumansiz

Seriport nesnesinin RxBuffer kapasitesi düşük olabilir mi?

Mucit23

Çok basit bir şekilde Veri uzunluğunu Sabit 4 byte yaptım. Ama burada bile veri atlıyorum. Readbyte fonksiyonu ile arada gelene birçok veriyi atlıyorum. Bir tek ReadExisting fonksiyonu ile gelen verileri eksiksiz alabiliyorum. Ama bu fonksiyon karakter sonuna bakmıyor. Buffer boyutu dolduğunda fonksiyondan geri dönüyor.

erkantr67

Alıntı yapılan: Mucit23 - 14 Temmuz 2022, 11:55:23Byte byte okumak istedim.  *String# şeklinde gönderim yaptım. Bu şekilde de verileri atlıyorum.
                byte RxByte = (byte)serialPort1.ReadByte();
                if (serialport_state == false)
                {
                    if (RxByte == '*')
                    {
                        RxBuffer[RxIndex] = RxByte;
                        serialport_state = true;
                    }
                }
                else
                {
                    RxIndex++;
                    RxBuffer[RxIndex] = RxByte;
                    if (RxByte == '#')
                    {
                        RxBuffer[RxIndex + 1] = (byte)'\0';
                        RxIndex = 0;
                        serialport_state = false;
                        
                        RxString=Encoding.ASCII.GetString(RxBuffer);
                    }
                  
                }

Gelen verilerin %20'sini anca alıyorum. Bu yavaş çalışmanın sebebi nedir?

Sabit veri uzunluğuna geçip SerialPort.Read() fonksiyonunu deneyeceğim birde.

Bu kodlar dataReceive içindeyse çok normal. Event bitmeden diğeri mecbur kaçar.

DataReceive DLL'inin içinini bilmeden fonksiyonun ismine aldanmamak gerekir.

@serdararikan 'ın belirttiği sistemi kurun. Tabi ilk ve son indeks kontrolü içinde thread kullanmanızda fayda var.

void datareceive()
{
   buffer[son_indeks]=read.byte();
  
   if(son_indeks<buffer.length-1)
      son_indeks++;

}

thread:
{
  while(son_indeks!=ilk_indeks)
  {
     paket[ilk_indeks] = buffer[ilk_indeks];
     
    if(ilk_indeks<buffer.length-1)
      ilk_indeks++;
  }
  
  paket_isle();

}

Mucit23

Sorun şu ki veri boyutunu bilmiyorum. Zorlandığım kısım burası. Paket sonuna bildiğim bir karakter eklemem lazım ama Datarecieve fonksiyonunda bunu işlemek veri kaçırmama neden oluyor.

erkantr67

Datanın sonuna 00 FF FF FF ekleyin.
Thread içinde gelen dataları(bufferdaki) pakete aktarırken ilk indeksin 0, -1, -2, -3 indekslerinde yukarıdaki diziyi arayın. Bulduğunuzda paketi kapatıp, işlersiniz. İşledikten sonra paketi sıfırlayıp, tekrar sonlandırma dizisini kontrol edersiniz.

NOT: Bufferdaki dataları pakete aktarırken, son indeks değerini bir ara belleğe atın. Paket işlenen thread içinde while(ilk indeks!=arabellek) yapın.