seriport hakkında

Başlatan görkem, 10 Eylül 2017, 00:30:54

görkem

Arkadaşlar merhaba,

Seriporttan byte veri gönderip alabiliyorum fakat şöyle bir durumum var  dizi olarak veri almaya kalktığımda sürekli dizinin 0.byte ına veriyi yazıyor diğer byte lar hep boş kalıyor kullandığım kod aşağıda nerede hatam var ?

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            UInt16 len, d;
            int u;
            byte[] buffer new byte[200];

            serialPort1.Read(buffer, 0, 200);
       }

muhittin_kaplan

readline ile alın, gönderdiğiniz verinin sonına da \n koyun.

bsenguler

 byte[] buffer new byte[200];


satırını aşağıdaki değiştirebilir misiniz?

byte[] buffer = new byte[200];

Hadi

#3
bence buffer değişkenini global tanıman lazım. yazdiğim şekilde ne zaman o metoda gelse buffer değişkenini yeni oluşturuyor ve eski veriler siliniyor. ondan obalibir bence.

bide offset neden her zaman 0 da? her seferinde onu artırmayı denediniz mi?

görkem

buffer değişkeni global kende aynı sorun vardı.ofset değerinde dizinin ilk adresini bildiriyoruz  fonksiyon diziye otomatik 0 dan başlayıp aktarmıyor mu  len değeri kadar ?

@bsenguler  kodda eşittir var ben buraya kopyalarken gözden kaçmış.

foseydon

Hocam sizin düştüğünüz hata şu, "data received" olayı doğal olarak seri portakal veri geldiği zaman oluşur. Bu çoğu zaman tek bir byte ile oluşur. Bu yüzden siz Buffer array'ine çoğu zaman tek byte yazarsiniz. Çünkü her zaman buffer'in üstüne yazıyorsunuz, sonuna eklemiyorsunuz. Burada yapacağınız şey ayrı bir değişken ile bu olaya kaçıncı girişi olduğunu sayıp ona göre array'ine doldurmak. Fakat benim tavsiyem list<byte> yapısını kullanmaniDir. Bu yapı bu işler için biçilmiş kaftan. List.add(serialport.readbyte); ile bu olaya her girdiğinde seri port takı veriyi okuyup kistin sonuna eklersiniz. Başka bir yerde islersiniz. Cep telefonundan yazdığım için tam kodu yazamadım. Bilgisayara geçince eklerim. Umarım hatayı anlamışsınızdır.

hasankara

@foseydon haklı. çözüm olarak fifoda ki byte sayısını kontrol edebilirsin. yeterli byte olmadığında okuma yapmadan çıkmasını söylersin. diğer bir husus ta bufferi global tanımlaman yada olay işleyicisinin girdi veya çıktısından dışarı alman. yoksa okuduğun veriyi dışarda kullanamazsın.

dumansiz

Hatırladığım kadarıyla olay şuydu:
Gelen her bir byte için datareceived olayı oluşmuyor.
Paket için datareceived oluşuyor.

foseydon

List<Byte> buffer = new List<Byte>();

 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            if(serialPort1.BytesToRead > 0)
            {
                  int i = 0
                  for(i =0; i < serialPort1.BytesToRead;i++)
                  {
                        buffer.add(serialPort1.ReadByte);
                  }
           }
      }


bu şekilde yaparsanız, seri porta veri geldikçe buffer'a ekler, daha sonra başka bir yerde işlersiniz. İşlediğiniz verileri silmeniz gerekiyor. List ile bunları yapmak oldukça kolay, esnek bir array gibi düşünebilirsiniz. Fakat zaten veriyi düzenli olarak bir noktada işlemeniz gerekecek, bunun içinde muhtemelen timer kullanmanız gerekecek. Bu yüzden benim size tavsiyem, 100ms gibi bir timer kurup, bu timer içerisinde seri portta veri olup olmadığını kontrol edin, varsa veriyi buffera alıp işleyin. bu şekilde daha kolay olur ve buffer üzerinde ekleme çıkarma işlemini tek noktada yaptığınız için daha güvenli olur.

görkem

@foseydon bu kodu olduğu gibi timer a geçirsek dediğiniz olur sanırım.birde  ben buffer i her veri geldiğinde aktarıp temizliyordum çözümü şöyle bulmuştum  for döngüsünde her okumada ofset i bir arttırıp veriyi  alıyordum işe yaradı fakat sizin kodunuz daha mantıklı.
Şöyle bir problemim var 2 adet seriport bağlantısına ihtiyacım var tanımlamaları ayrı ayrı yapmama rağmen veri alışverişinde bulunamadım

foseydon

Timer'a aktarirsaniz aynı şekilde çalışır. Çalışır diyorum ama, çalışmayabilir. Kafadan yazdım, harf hatası falan olabilir. Ama mantık doğrudur.

Şayet cihazda iki seri port varsa ikisininde sorunsuz kullanabilirsiniz. Her biri için ayri ayrı açma kapama, veri toplama işlemi yapmanız gerekir. Tam kodu paylaairsaniz yardımcı olurum.

görkem

portları bir türlü ayıramadım hepsini ayrı ayrı tanımladım fakat biri bağlıyken diğeri bağlanmıyor.kodların hepsini paylaşamam düzensiz olduğu içinde blok şeklinde paylaşıyorum

   

            serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            serialPort2.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler2);

//seriport 2 için 
 private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort2.BaudRate = int.Parse("9600");
                serialPort2.DataBits = int.Parse("8");

                serialPort2.StopBits = System.IO.Ports.StopBits.One;

                serialPort2.Parity = Parity.None;

                serialPort2.PortName = "COM3";

                serialPort2.Open();

                MessageBox.Show("Bağlandı", "", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

            }
            catch (Exception)
            {

                MessageBox.Show("Cihazınız Bağlı Değil...", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);

            }

        }


//seriport1

  void seriport_baglan()
            {
                try
                {

                    serialPort1.BaudRate = int.Parse("9600");
                    serialPort1.DataBits = int.Parse("8");

                    serialPort1.StopBits = System.IO.Ports.StopBits.One;

                    serialPort1.Parity = Parity.None;

                    serialPort1.PortName = "COM1";

                    serialPort1.Open();

                baglan.Enabled = false;
                baglantikes.Enabled = true;

                MessageBox.Show("Bağlandı","",MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
               
                }
                catch (Exception)
                {
                baglan.Enabled = true;
                baglantikes.Enabled = false;

                MessageBox.Show("Cihazınız Bağlı Değil...","",MessageBoxButtons.OK,MessageBoxIcon.Warning);

                }


            }

  //serial port1 receive 

 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
            {
                UInt16 len=10,s=0,b,i;
               

            for (s = 0; s < len; s++)
            {
                serialPort1.Read(buffer, s, len);
                modul =  buffer[0];
                ID[0] =  buffer[1];
                ID[1] =  buffer[2];
                ID[2] =  buffer[3];
                ID[3] =  buffer[4];
                dat[0] = buffer[5];
                dat[1] = buffer[6];
                dat[2] = buffer[7];
                dat[3] = buffer[8];
                dat[4] = buffer[9];

            }

     //seri port2 receive

  void DataReceivedHandler2(object sender, SerialDataReceivedEventArgs e)
            {
                UInt16 uzunluk = 4, z;

                for (z = 0; z < uzunluk; z++)
                {
                    serialPort2.Read(serino, z, uzunluk);
                 
                }

                parca[0] = serino[0];
                parca[1] = serino[1];
                parca[2] = serino[2];
                parca[3] = serino[3];

                 c = BitConverter.ToString(parca);  // byte veri hex formatında string 
                label23.Text = c.Replace("-", "");        //olarak gösterir
           
            
            }      
            



            }

elektronik

#12
bu kodu denermisiniz
   
         if (serialPort1.BytesToRead >0)
            {


                byte[] buffer_gelen = new byte[this.serialPort1.BytesToRead];
                serialPort1.Read(buffer_gelen, 0, serialPort1.BytesToRead);
                serialPort1.DiscardInBuffer();


                label7.Text = Convert.ToString(Display(buffer_gelen));// Gelen veriyi label7 de gösteriyoruz


            }

foseydon

#13
Alıntı yapılan: görkem - 28 Eylül 2017, 12:46:36
portları bir türlü ayıramadım hepsini ayrı ayrı tanımladım fakat biri bağlıyken diğeri bağlanmıyor.kodların hepsini paylaşamam düzensiz olduğu içinde blok şeklinde paylaşıyorum


Üstat, serialPort1'i seriport_baglan() fonksiyonu içerisinde açıyorsun, fakat seriport_baglan() fonksiyonunu çağırdığın bir yer yok. biraz karışık olmuş.

List<Byte> port1Buffer = new List<Byte>();
List<Byte> port2Buffer = new List<Byte>();

private void button2_Click(object sender, EventArgs e)
{
	serialPort2.BaudRate = serialPort1.BaudRate = int.Parse("9600");
    serialPort2.DataBits = serialPort1.DataBits = int.Parse("8");
	serialPort2.StopBits = serialPort1.StopBits = System.IO.Ports.StopBits.One;
	serialPort2.Parity = serialPort1.Parity = Parity.None;
	serialPort2.PortName = "COM3";
	serialPort1.PortName = "COM1";

	if(serialport1.isOpen)
	{
		serialport1.Close();
	}
	serialport1.Open();

	if(serialport2.isOpen)
	{
		serialport2.Close();
	}
	serialport2.Open();
	// bu noktada 2 seriportunuz da acildi
}

private void timer1_tick(object sender, SerialDataReceivedEventArgs e)
{

    if(serialPort1.BytesToRead > 0)
    {
          int i = 0
          for(i =0; i < serialPort1.BytesToRead;i++)
          {
                port1Buffer.add(serialPort2.ReadByte);
          }
   }

	if(serialPort1.BytesToRead > 0)
    {
          int i = 0
          for(i =0; i < serialPort2.BytesToRead;i++)
          {
                port1Buffer.add(serialPort2.ReadByte);
          }
   }
	// bu noktada 2 seri porttaki veride ilgili bufferlara yaziliyor.
}


şu şekilde basitçe, hiç event olayına girmeden yaparsan hallolur bence. burada timer'ın sonunda şayet yeterli veri varsa işlersin. Burada bir nokta var, seri port isimleri "hard coded" yani sen sistemde COM1 ve COM3 var mı bilmiyorsun. Yoksa hata verecektir. Şu şekilde yazıp, timer'ın içine bir "breakpoint" koyarak bir dene, veriler ilgili buffer'lara düzgün alınıyor mu diye. Daha sonra veri işleme kısmına geçersin.

Aslında en güzeli, serialPort extension class yazıp veri toplama işlerini fonksiyon haline getirmek ve her seri porta kendi buffer'ını falan eklemek. Sen şimdilik bunu bir dene, sonrasına bakalım.

görkem

@foseydon şöyle bir sıkıntım var sanal port oluşturup terminal programından 8 byte lık veri gönderiyorum sıkıntısız serialport1.readbyte çalışıyor fakat işlemci den normal seriport ile  8 byte lık veri gönderdiğimde serialport1.readbyte  da veri bekliyor da kalıyor.
İşlemciyi terminal programına bağladığımda sorunsuz 8 byte geldiğini görüyorum ama c# da veri bekliyor görünüyor neyden kaynaklanır usb yapsaydım şimdiye çözmüştüm seri port çok uğraştırdı