Arama butonu
Bu konudaki kullanıcılar: 2 misafir, 1 mobil kullanıcı
4
Cevap
1234
Tıklama
0
Öne Çıkarma
C# - RS232 Timer Sorunu
G
10 yıl (87 mesaj)
Çavuş
Konu Sahibi

Merhaba arkadaşlar,
Bir seri port haberleşmeli terazim var. Putty ile veri alabiliyorum. C# ile Arduino için daha önceden yapmış olduğum bir arayüzüm vardı ordan da veri okuyabiliyorum. Fakat çok sağlıklı olmadığı için bir kaç düzenleme yaptım ama çözemediğim ve önerilerinizi beklediğim bir kaç sorun ortaya çıktı.

1-) Data'yı timer ile alıyorum. Terazi 9600 baudda çok hızlı gönderiyor ölçtüğü ağırlığı.
Bu yüzden daha önceden,
 sonuc = serialPort1.ReadExisting();

olan komutu
 sonuc = serialPort1.ReadLine();

olarak çevirdim.

Timer Interval süresini 200ms ve daha yukarısı yaptığımda terazi verileri düzgün gelmiyor, geç kalıyor sanki kasıyormuş gibi.
Süreyi 5-75 ms civarı yaptığımda da veri tam istediğim gibi geliyor fakat bu sefer de arayüzdeki hiçbir butonu kullanamıyorum, "bağlantıyı kopar" butonum var basıyorum işlemiyor, 20-30 sn sonra işliyor.

2-) Terazinin gönderdiği data
"ST,GS, 15.6 g" tarzında geliyor. Sadece sayıyı nasıl çekebilirim. Split modunu tam uygulayamadım. Yardım ederseniz çok sevinirim. Kodlar 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;

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

private void Form1_Load(object sender, EventArgs e)
{
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)
{
label1.Text = sonuc + ""; ;
}

private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
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
timer1.Stop();
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(label1.Text);
}

private void button4_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
}

private void timer1_Tick(object sender, EventArgs e)
{

sonuc = serialPort1.ReadExisting();
this.Invoke(new EventHandler(yaz));
}




}
}



< Resime gitmek için tıklayın >

DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.

Üye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.

Üye Ol Şimdi Değil



G
10 yıl (2540 mesaj)
Binbaşı

Şimdi dostum öncelikle timer ın nasıl çalıştığını anlaman lazım. toolboxtaki timer ui threadında çalışıyor. Bu yüzden ui yi meşgul ediyor. Multi threaded asenkron programlamayla felan çok içli dışlı değilim ama senin kullanman gereken şey System.Threading.Timer . Farklı bir threadda çalışacağı için ui yi meşgul etmez sen de istediğin gibi durdurabilirsin. UIde değişiklik yapmak istediğinde hata vericektir. Onun için şuna bakhttp://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c


Bu mesaja 1 cevap geldi.
T
10 yıl (15005 mesaj)
Yarbay

Split:

 
"ST,GS, 15.6 g".Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);


sana 3 değer döndürür: "ST,GS," - "15.6" - "g"



Multithread:

Thread t = new Thread(new ThreadStart(fonksiyonAdi));


şeklinde threadleri kurduktan sonra,

t.Start(); 


şeklinde başlatırsın. Threadler çok önemli bir kod bloğunda aynı anda bulunmasın diye de kilit mekanizmasını kullanırsın:

 
object kilit=new object;


lock(kilit) 
{
calisiyorTmp = calisiyor; // yapılması gerekenleri burada yaparsın, aynı anda sadece bir thread burada bulunabilir
Monitor.PulseAll(kilit); // gerekirse, burayı bekleyen diğer threadlere işaret gönderir(bekleyen varsa uyandırır)
Monitor.Wait(kilit); // gerekirse, bu threadi uyutur ki boş çalışmasın, işlemci yükü oluşturmasın gereksiz şekilde.

}





< Bu mesaj bu kişi tarafından değiştirildi Tugrul_512bit -- 2 Haziran 2016; 18:42:33 >
Bu mesaja 1 cevap geldi.
G
10 yıl (87 mesaj)
Çavuş
Konu Sahibi

Çok teşekkür ederim.
Okuma sorununu
" private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) " ve readtimeout kullanarak çözdüm. Split için de timer için de teşekkür ederim. :)


Bu mesaja 1 cevap geldi.
G
10 yıl (1562 mesaj)
Yüzbaşı

Bu Tiip durumlarda System.Threading.Timer kullanmak kesin çözüm.
UI üstündeki timer belirli bir zaman sonra sıkıntı yaratmaya başlıyor.
Uygulama Açık kalma süresi ortalama 20 günü geçtiğinde, o yüzden System.Threading.Timer kullanmak gerekir. RS232 gibi bağlantı seçeneklerinde, sunucu dan cevap beklerden vs.



DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.