C# - RS232 ve Timer Sorunu

Başlatan Bahadır AYDINOĞLU, 02 Haziran 2016, 16:33:02

berat23

bence c#da serial event konusu biraz sorunlu, ya da çok lezzetli değil diyelim. benim tavsiyem polling yapmaktır. bir thread içinde sürekli gelen veri var mı diye bakmak daha garanti bir çözüm oluyor. böylelikle hem parse etmesi kolay hem de veri kaçırma olasılığınız az oluyor.

robomaster

#16
Surekli gelen veriye geldi mi gelmedi mi bakmaya gerek yok,angarya. Bu isler icin eventhandler kullaniliyor.

Bahadır AYDINOĞLU

Baya bir tartışma dönmüş :). Teşekkür ederim arkadaşlar.

Timer kullanmadan datareceived eventı ve readtimeout ile çözdüm, gelen veriyi de split ile ayırdım. Örnek kod aşağıda,

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using Microsoft.Office.Core;
using Excel = Microsoft.Office.Interop.Excel;

namespace Data_Okuma
{
    public partial class Form1 : Form
    {
        string[] ports = SerialPort.GetPortNames();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            label4.Text = DateTime.Now.ToShortDateString();
            foreach (string port in ports)
            {
                comboBox1.Items.Add(port);
                comboBox1.SelectedIndex = 0;
            }            
            comboBox2.Items.Add("2400");
            comboBox2.Items.Add("4800");
            comboBox2.Items.Add("9600");
            comboBox2.Items.Add("19200");
            comboBox2.Items.Add("115200");
            comboBox2.SelectedIndex = 2;
            //AÇILIŞTA BAĞLANTININ KAPALI OLDUĞUNU BELİRT.
            label3.Text = "Bağlantı Kapalı";    }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            {
            // Form kapandığında SerialPort1 portu kapat.
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Close();
            }
        }
        }
        string sonuc;       
        private void yaz(object o, EventArgs e)
        {
            string[] stringSeparators = new string[] { " " };
            string[] dizi = sonuc.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);
           

            string agirlik = dizi[1];
            textBox1.Text = agirlik ;
           if (dizi[0] == "US,GS,")
            {
                textBox2.Text = "OKUNUYOR";
            }
            else
            {
                textBox2.Text = "OKUNDU" ;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            if (serialPort1.IsOpen == false)
            {
                if (comboBox1.Text == "")
                    return;
                serialPort1.PortName = comboBox1.Text;
                serialPort1.BaudRate = Convert.ToInt16(comboBox2.Text);
                try
                {
                    serialPort1.Open();
                    label3.ForeColor = Color.Green;
                    label3.Text = "Bağlantı Açık";


                }
                catch (Exception hata)
                {
                    MessageBox.Show("Hata:" + hata.Message);
                }
            }
            else
            {
                label3.Text = "Bağlantı kurulu !!!";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //BAĞLANTIYI KES BUTONU
           
            if (serialPort1.IsOpen == true)
            {
                serialPort1.Close();
                label3.ForeColor = Color.Red;
                label3.Text = "Bağlantı Kapalı";
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            listBox1.Items.Add(textBox1.Text);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }
        
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            serialPort1.ReadTimeout = 100;
            try
            {
                sonuc = serialPort1.ReadLine();
                this.Invoke(new EventHandler(yaz));
            }
            catch (Exception hata)
                {
                    MessageBox.Show("Hata:" + hata.Message);
                    serialPort1.Close();
                    label3.ForeColor = Color.Red;
                    label3.Text = "Bağlantı Hatası";

                }

        }     

        
                       

    }
        }
 

cemilkendir

verdiğiniz örnekler rastgele zamanlarda seri porttan gelebilecek dataları alabilmek için

peki cihaza belli periyodlarda (1 Saniye) sorgu yapıp cevap almak için nasıl bir yapı kurmak lazım.

Şuan benim yaptığım yöntem
priyodu doğru yakalamak için 1000ms lik timerin tick event inde sorgu yapıp gelecek datayı da yine timer tick event i içerisinde beklemek (datarecevied time out 100ms).

olemiss

> priyodu doğru yakalamak için 1000ms lik timerin tick event inde sorgu yapıp gelecek
> datayı da yine timer tick event i içerisinde beklemek (datarecevied time out 100ms).

"Period'u doğru yakalamak" nedir, anlayamadım?
Yazılım Mühendisi, Çevirmen.

cemilkendir

Alıntı yapılan: olemiss - 06 Haziran 2016, 16:13:34
> priyodu doğru yakalamak için 1000ms lik timerin tick event inde sorgu yapıp gelecek
> datayı da yine timer tick event i içerisinde beklemek (datarecevied time out 100ms).

"Period'u doğru yakalamak" nedir, anlayamadım?

Saniyede 1 defa cihazdan veri alıp bu veriyi kaydetmek amaç.

olemiss

Şu anda çalışıyor ise dokunmayın.  Herhalde arayüzde donma yaşamıyorsunuz.

Programları erken optimize etmemek gerek.
Yazılım Mühendisi, Çevirmen.

fighter_36

#22
Merhabalar
Ethernet ile plc'ye veri alıp yolluyorum ve timer kullandım fakat zamanla timer sorun çıkardı. Zamanla programda true false ile kontrol ettiğim resim görünürlük süresi yavaşladı. Altta bununla ilgili kodlar bulunmakta bu thread kullanımı ile bu sorunu hallede bilir miyim? şimdiden teşekkürler

private void Timer4_Tick(object sender, EventArgs e)
        {
            try
            {
                if (plc.IsConnected)
                {


                    int startbyte = Int32.Parse("333");
                    int selectedbit = Int32.Parse("0");
                    byte[] byteArray = plc.ReadBytes(PROFINET_STEP_7.Profinet.DataType.Marker, 0, startbyte, 1);
                    bool kumanda = Convert.ToBoolean(byteArray[0].SelectBit(selectedbit).ToString());
                    if (kumanda == true) pictureBox2.Image = ımageList1.Images[0];
                    else pictureBox2.Image = null;
                    
                }


            }
            catch (Exception)
            {
                return;
            }
        }