c# Seri Port Okuma Dağınıklığı

Başlatan mutta16, 29 Ekim 2013, 18:04:39

mutta16

Merhabalar,

Seri portu okuduktan sonra düzensiz olarak veri okuğumu farkettim, şöyle ki,

aşağıda verilerden 3 ncü sıradaki olanı fark edebilirsiniz diğerlerinden farklı. Seri porttan nasıl sürekli düzenli veri alabilirim?

-----M5-2|0|1|0|50|0000000000000000|0001
-----M5-2|0|1|0|50|0000000000000000|0001
-----?M5-2|0|1|0|50|0000000000000000|0001
-----M5-2|0|1|0|50|0000000000000000|0001
-----M5-2|0|1|0|50|0000000000000000|0001


Teşekkürler.

camby


mutta16

Timer in click olayina
Serialport1.Open ();
Serialport1.readline ().ToString ();
Serialport1. Close ();

Yazdim ve timer 2 sn araliklarla seri portu okuyor.
Sorun su ki bazen okudugum degerde ??? isaretleri oluyor.


Tesekkurler.

omereliusuk

SerialPort.ReadExisting()
ve seriport kesmesi

mutta16

Readline dan once bu senin soyledigin kesmeyi kullandim dogru mudur?
Sonuc yine ayni malesef :/

atillaa

#5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RasSegwayTool
{
	public class SeriCihaz
	{
		private FormSeriKonsol ReportForm;

		public delegate void MessageRecievedHandler(string Message);
		public event MessageRecievedHandler MessageRecieved;

		private System.Threading.Semaphore RecentResponseSema = new System.Threading.Semaphore(1, 1000);
		private System.Threading.Semaphore MessageRecievedSema = new System.Threading.Semaphore(0, 1000);
		private System.Threading.Semaphore JobQueuedSema = new System.Threading.Semaphore(1, 1000);

		private System.IO.Ports.SerialDataReceivedEventHandler Handle;

		private System.IO.Ports.SerialPort _SeriPort;
		public System.IO.Ports.SerialPort SeriPort
		{
			get { return _SeriPort; }
		}

		public SeriCihaz(string Port, int BaudRate)
		{
			_SeriPort = new System.IO.Ports.SerialPort(Port, BaudRate, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
			_SeriPort.Handshake = System.IO.Ports.Handshake.None;
			_SeriPort.ReadBufferSize = _SeriPort.ReadBufferSize * 4;
			Handle = new System.IO.Ports.SerialDataReceivedEventHandler(SeriPort_DataReceived);
			_SeriPort.DataReceived += Handle;

			_SeriPort.Close();

            //try
            //{
            //    _SeriPort.Open();
            //}
            //catch (System.Exception Ex)
            //{
            //    System.Windows.Forms.MessageBox.Show("Seri port bağlantısında hata var.\r\n" + Ex.Message, "Hata", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            //}
		}

		private void FireMessageRecieved(object InMessage)
		{
			if (MessageRecieved != null)
			{
				MessageRecieved((string)InMessage);
			}
		}

		List<int> _RawBytes = new List<int>();


		/// <summary>
		/// Gelen Seri port datasını ham olarak almak ve gerekirse ön anlamdırma ile gelen listesine koyan fonksiyon.
		/// </summary>
		void SeriPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
		{
			try
			{
				int PromtIndex = 0;
				string Msg = "";

				while (_SeriPort.BytesToRead > 0)
				{
					int ReadByte = _SeriPort.ReadByte();

					if (ReadByte != 10 || ReadByte != 13)
					{
						_RawBytes.Add(ReadByte);
					}

					if (_RawBytes.Contains(62) && _RawBytes.Contains(59))
					{
						PromtIndex = _RawBytes.IndexOf(62);
						for (int i = PromtIndex; i < _RawBytes.Count; i++)
						{
							Msg = Msg + Convert.ToChar(_RawBytes[i]);

							if (_RawBytes[i] == 59)
							{
								Thread MessageRecievedThread = new Thread(new ParameterizedThreadStart(FireMessageRecieved));
								MessageRecievedThread.Start(Msg);
								Msg = "";
								_RawBytes.RemoveRange(PromtIndex, i - PromtIndex + 1);
							}
						}
					}

				}

			}
			catch (System.Exception Ex)
			{
				System.Windows.Forms.MessageBox.Show(Ex.Message);
				SeriPort_DataReceived(this, e);
			}
		}

		internal void Send(string p)
		{
			for (int i = 0; i < p.Length; i++)
			{
				SeriPort.Write(p[i].ToString());
				//Thread.Sleep(50);
			}

		}
	}
}


seri haberleşmede kullandığım class

mutta16

Arkadaşlar Merhaba,

Durumu şöyle özetleyebilirim, ben her 2,5 sn de veri alıyordum seri porttan bu süreyi 3 sn yaptım ve veri dağınıklığı ortadan kalmış oldu.

Desteğiniz için teşekkürler.

muhittin_kaplan

mutta yanlış yapıyorsun,
timer la okunmaz,
sen bilginin geldiğini tespit edip gidip tüm bilgiyi okuyacaksın.

bunun için  MCU tarafında gönderdiğin bilginin ardına bir belirtec koyacaksın (/r/n gibi ki bu belirteçler yeni satır felan demektir) . Pc deki c# aldığı bu bilgiyi /r/n gibi belirtece kadar okuyuacak.

lütfen bunun için pc tarafında  serialport un
readexiting
readbyte
readline

olaylarını araştırınız.

mutta16

Teşekkürler Muhittin Bey zaten aksam uygulamayi sabaha kadar calistirdim yine bir kac yerde degisik veriler oldugunu gördüm,  dediğiniz olaylari en kısa zamanda inceleyecegim.

micelow

Muhittin hocamin dediği gibi veriyi timerla okumak pek doğru bir yöntem olarak gözükmüyor. serialport.datareceived olayını kullanarak çok daha güvenli ve esnek hale getirebilirsin. İyi çalışmalar.
"Bir tek şeye ihtiyacımız var çalışkan olmak."

omereliusuk

arkadaş keşke tüm yazılanları okusaymış.

YavuzCetin

Sırf Burada gördüğüm bilgiler için üye oldum Gerçekten teşekkür ederim. Daha önce Sıcaklık sensöründen bilgi almıştım ama aynı bu sorunla karşılaştım çünkü bende timer ile veri alıyorudm ve arada veriler bozuluyordu bunları çok çeşitli yollarla(C# tarfında) düzeltip almak zorunda kalmıştım. Dediğiniz yolların çoğunu kullandım hatta timerla veri aldığım için eski bilgileri portan silip yenisini alıyordum ama pic tarfında da timer olduğu için sıkıntı çıkartıyordu şimdi biraz daha mantık oluştu. Burda tekrar teşekkür etmek istedim

mutta16

Sevgili Yavuz Çetin kodlarını seri portun "DataReceived" bölümüne yazarsan çok daha mantıklı olacak ki ben öyle yaptım saçma sapan veriler gelmiyor artık.

mutta16

DataRecieved bölümüne aşağıdaki kod kullanımı forumu gezenlere yardımcı olabilir.

try
            {
                RxString = serialPort1.ReadLine();
                this.Invoke(new EventHandler(DisplayText));
               
            }
            catch (System.TimeoutException)

            {

            }