Merhaba arkadaşlar, bu dersimizde C# ile seri port kullanımını detaylı olarak anlatmaya çalışacağız. C# ile string, byte ve char türü veri gönderip alma işlemlerini inceleyeceğiz. Ayrıca seri porttan otomatik veri okuma işlemini öğreneceğiz.
Öncelikle seri port nesnesini kullanabilmek için, System IO Ports kütüphanemizi projemize dahil ediyoruz. Bunun için sayfamızın en üst kısmına using System.IO.Ports; kodunu ekleyerek derleyiciye giriş çıkış portlarını kullanacağımızı bildiriyoruz.
Seri port nesnesini kullanabilmek için öncelikle bir seri port oluşturuyoruz;
1 2 3 4 5 6 7 8 9 10 11 12 |
namespace SeriPort { public partial class main : Form { SerialPort sp = new SerialPort(); // Seri port nesnesi oluşturuyoruz sp.PortName = "COM1"; // Kullanacağımız seri port adını seçiyoruz (String) sp.BaudRate = 19200; // Seri haberleşme hızını seçiyoruz (int32) sp.DataBits = 8; // göndereceğimiz bilginin kaç bitten oluşacağını bildiriyoruz (int32). sp.Parity = Parity.None; // Eşlik bitidir. Gönderilen verinin doğruluğunu kontrol etmek için kullanılır. sp.StopBits = StopBits.One; // Stop bitinin kaç bit olacağını belirtir. } } |
Yukarıda verdiğimiz kodları inceleyelim;
PortName : Seri port adını belirtir. String türü değer alır. Bilgisayarınızda bağlı olan seri portları aygıt yöneticisinden görebilirsiniz. Port adı kesinlikle belirtilmeli.
BaudRate : Seri haberleşme hızını belirtir. int32 türü değer alır. Bir saniyede gönderilebilecek maksimum bit sayısıdır. Alıcı ile aynı değer almak zorundadır. Standartlaşmış olarak 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 değerlerini alabilir. Varsayılan değeri 9600 Baud’dur.
DataBits : Gönderilecek her bilgini/karakterin kaç bitten oluşacağını belirtir. int32 türü değer alır. 5 ile 8 arasında değer alabilir. Genelde 7 ve 8 değerini alır. Varsayılan değeri 8’dir.
Parity : Eşlik bitinin sayısını belirtir. Alınan verinin doğruluğunu kontrol etmek için kullanılır. None (0), Odd (1), Even (2), Mark (3), Space (4) değerlerini alabilir. Varsayılan değeri None ‘dur.
StopBits : Durdurma bitinin kaç bit olacağını belirtir. One (1), Two(2), OnePointFive(3) değerlerini alabilir. Varsayılan değeri One ‘dır.
Seri portu tek satır kod ile oluşturabiliriz;
1 |
SerialPort sp = new SerialPort("COM1",9600,Parity.None,8,StopBits.One); |
Bilgisayarımızdaki tüm seri portları bir combobox’da listelemek için SerialPort nesnesinin GetPortNames özelliğini kullanarak portları bir diziye atarız. Ardından diziye atadığımız string türündekiport adlarını bir foreach döngüsü yardımı ile combobox’ta listeleyebiliriz;
1 2 3 4 |
string[] portlar = SerialPort.GetPortNames(); // Bağlı seri portları diziye aktardık foreach(string portAdi in portlar){ comboBox1.Items.Add(portAdi); } |
Seri port nesnesini tanımladıktan sonra veri gönderip alabilmek için seri portumuzu açmamız gerekiyor. Bunun için Open() fonksiyonunu çağırıyoruz. Eğer seri port başka bir cihaz tarafından kullanıyorsa portumuz açılmayacaktır. Çünkü bir seri port aynı anda bir uygulama ya da bir cihaz tarafından kullanılabilir.
1 |
sp.Open(); // Seri portumuzu açıyoruz |
Seri Port Veri Gönderme :
Seri porta veri göndermek için Write() fonksiyonu kullanılır. Gönderilen veri String, Byte dizisi ya da Char dizisi olabilir. String türü veri göndermek için parantezler içerisinde Çift tırnak içerisinde gönderilecek veri yazılır.
Örnek:
1 |
sp.Write("Yazı"); // Burada String türü veri gönderdik |
Byte ya da Char dizisi göndermek için ise parantezler içerisinde dizi değişkeni, gönderilecek dizinin başlangıç indisi, ve dizide gönderilecek indis sayısı yazılır.
Seri port Byte dizisi gönderme örnek:
1 2 3 4 5 6 7 8 9 10 11 |
/* * Örnek olarak veri adında bir byte dizisi oluşturalım * Burada byte değişkeninin 8 bitlik sayı oluştuğunu * göz ardı etmeyin */ byte[] veri = new byte[] {12, 15, 22, 25}; /* * Şimdi veri dizimizin sıfırıncı indisinden son indisine kadar * olan tüm verileri seri porta yazdıralım. */ sp.Write(veri, 0, veri.Length); |
Seri port Char dizisi gönderme örnek:
1 2 3 4 5 6 7 8 |
/* * Örnek olarak bir char dizisi oluşturalım */ char[] karakter = new char[] { 'a','1', (char)15,}; /* * Şimdi dizinin tüm elemanlarını seri porta yazalım */ sp.Write(karakter, 0, karakter.Length); |
Seri Port Veri Okuma :
Bu konuda bir çok kişi sıkıntı yaşamaktadır. Seri port sadece açık olduğu zaman veri alabilir. Bir timer yardımıyla sürekli seri port kontrol edilebilir yada seri portun DataReceived eventi ile seri port dinlenebilir. Timer kullanarak seri porttan alınan veride kayıp yaşanma ihtimali yüksektir. Bu sebeple biz DataReceived eventini kullanacağız.
Bunun için öncelikle DataReceived eventini tanımlamamız gerekiyor.
1 |
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); |
Ve ardından fonksiyonumuzu yazıyoruz:
1 2 3 4 |
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) { } |
Bu event içerisinde seri porttan gelen bilgileri otomatik olarak okuyup bir değişkene aktarabiliriz ya da textBox, listBox gibi araçlara yazdırabiliriz. Birkaç çeşit okuma şeklimiz vardır.
1- ReadExisting() fonksiyonu ile String olarak okumayı görelim;
1 |
string veri = sp.ReadExisting(); |
2- ReadLine() fonksiyonu ile yine Strig türünde satır satır okuma;
1 |
string veri = sp.ReadLine(); |
3- Read() fonksiyonu ile Byte dizisi olarak okuma:
1 2 3 4 5 6 7 8 9 10 11 12 |
/* *Öncelikle okuyacağımız veriyi atayacağımız dizimizi oluşturuyoruz. *Dizimizin uzunluk değeri gelen byte sayısı kadar olmalı *BufferSize bize gelen verinin uzunluğunu verir. */ byte[] veri= new byte[sp.ReadBufferSize]; /* *Ardından Read() fonksiyonu ile gelen her byte bilgisini *veri dizisine aktarıyoruz. */ sp.Read(veri,0,sp.ReadBufferSize); |
Read() fonksiyonu ile byte dizisi gibi char dizisi şeklinde de okuma yapabiliriz.
4- ReadByte() ve ReadChar() fonsiyonları ile bir byte ve bir char veri okuma:
1 2 |
int veri = sp.ReadByte(); // Seri porttan integer türünden 1 byte veri okur int veri = sp.ReadChar(); // Seri porttan integer türünden 1 karakter veri okur |
Diğer Seri Port Fonksiyonları:
Github üzerinden yayınladığım örnek seri port uygulamasına buradan erişebilirsiniz: C# Seri Port Örnek Uygulaması
Merhaba; C# Formunda 2 adet çift tabanlı veri var. (Örn; A Sayısı : 25, B Sayısı 34). Bu verileri Arduino ile Seri Port bağlantısını yapar yapmaz yani gönder butonuna basmadan anında yazdırmak istiyorum. Nasıl yapabilirim yardımcı olabilir misiniz?
Merhaba.
Seri porta veri gönderebilmek için ilgili seri port seçili olması ve ayarları yapılmış olması gerekir. Tüm ayarları yaptığınızı varsayarak:
Eğer seri porta verileri belli aralıklarla gönderecekseniz timer kullanmalısınız.
Yok eğer verileri bağlantıdan sonra yalnızca 1 defa gönderecekseniz, serialPort.Open() komutundan sonra veri gönderme komutunu yazabilirsiniz. En azından Formda bir port seçmek için ComboBox ve bağlantı kurmak için Bağlan butonunuz olması gerekir. Bağlan butonunun Click eventi içerisinde veri gönderecek ya da Timer’ı başlatacak kodu yazabilirsiniz.
Merhaba , bu kaynak benim adıma çok iyi oldu çok bilgi aldım. Amacım USB bağlantısı ile 18F sürümü bir PIC Mikrodenetleyiciye veri alıp göndermek. Örneğin PIC den anlık olarak sıcaklık bilgilerini alıp C#’da hazırladığım formda anlık olarak görmek ve aynı zamanda PIC e komut da verebilmek istiyorum. C#’ da program hazırlıyorum. Bu yazınızdaki bilgiler bunları yapabilmeme yeterli midir acaba? Çok teşekkür ederim bilgileriniz için…
Merhaba
Eğer 18F serisi denetleyici ile USB D+/D- pinleri üzerinden haberleşme sağlayacaksanız, bu makaledeki bilgiler işinizi görmez.
Eğer USB – Seri port çevirici ile Rx/Tx pinleri üzerinden haberleşme sağlayacaksanız, buradaki bilgiler ile programlama becerinize bağlı olarak dilediğinizi yapabilirsiniz. C# ve PIC programlama beceriniz ne kadar bilmiyorum. Buradaki bilgiler ile, PIC ile PC arasında yalnızca veri alışverişi yapabilirsiniz. Geri kalanı sizin programlama becerilerinizie bağlıdır. Çünkü veri alıp gönderme en basit iştir, zor olan kısım veriyi kullanabilmektir.
Merhaba port isimlerini combobox eklemiyor niye olabilir acaba
Merhaba.
Seri Portların Comboboxta listelenebilmesi için bilgisayarınızda en az bir seri port bağlı olması gerekmektedir.
Portları listelemek için “Yenile” adında bir buton ve “PortListele” adında bir metod (fonksiyon) oluşturun. Ardından bu fonksiyon içerisine port listeleme kodlarını yazın. Form load metodu içerisinden ya da Yenile butonu click eventi içerisinden bu fonksiyonu dilediğiniz zaman çağırabilirsiniz.
Örnek:
void PortListele(){
comboBox1.Items.Clear(); // Combobox içeriğini temizledik
string[] portlar = SerialPort.GetPortNames(); // Bağlı seri portları diziye aktardık
foreach(string portAdi in portlar){
comboBox1.Items.Add(portAdi); // Dizideki portları ComboBox’ta listeledik
}
}
Artık bağlı portları listelemek için PortListele() fonksiyonunu çağırmanız yeterli
merhaba. arduino da butona her basıldığında 1 artan sayacı c# ta label a nasıl aktarabilirim?
Merhaba,
C# üzerinde seri port ayarlarını yaptığınızı varsayıyorum.
Yukarıda bahsettiğim gibi önce bir evet oluşturacağız;
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
Ardından olay tetiklendiğinde çalışacak kodlarımızı yazacağız;
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
label1.Text = serialPort1.ReadExisting();
}
Arduino ile sayaç değerini
Serial.print(sayac);
şeklinde seri port gönderdiğinizde sayaç değeri label1 üzerinde görüntülenmiş olacaktır.İlk başta Türkçe kaynak bulamam diye yabancı sitelerde epey dolaştım, istediğim şeyi bulamadım. Sizin örnek ile (özellikle GitHub üzerindeki) 1 gecede tam olarak istediğimi yaptım, daha önce hiç C# veya masaüstü uygulama yapmamıştım.
Uygulamada yaptığım değişiklikler; tek bir giriş alanı yerine 1’den fazla giriş alanı oluşturdum, bir de her gönder butonuna basınca artan bir text alanı ekledim. Verileri gönderince her alan verisinin arasına delimiter koyup o şekilde gönderiyor.
çok faydalı oldu, teşekkür ederim.
teşekkür ,
sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived); bu kısımdaki += anlamı nedir?
Elinize, emeğinize sağlık hiçbir yerde bulamadığım uygulamayı ve açıklamayı burda buldum. Çok teşekkürler.