C# Serial Port Bileşeni!

Siteme her gün bir makale eklemek istiyorum ama bir şekilde ne oluyorsa ekleyemiyorum. Okul beklediğimden de çok vaktimi aldı üstüne birde çalıştığım firmanın projeleri, okuldaki kulüp etkinlikleri derken bu zamana kadar makale ekleme fırsatım olmadı. Forumlarda gezindiğimde seri port ile ilgili birçok arkadaşın sıkıntısı oluyordu bende C#’ın ‘Serial Port’ bileşeni ile ilgili bir makale yazmak istedim. Şimdi bu bileşeni inceleyelim;

Yaptığımız yazılımlar bazen bir cihazla haberleşmek durumda kalabilir. Örnek olarak, bilgisayardan kontrol edebileceğiniz bir robot olabilir, ısı değeri okuyabileceğiniz bir sistem olabilir, kısacası bir sistemi bilgisayarınızdan kontrol etmek istiyorsanız serial port bileşeni sizin imdadınıza yetişiyor. Şimdi gelin bu sınıfın bazı faydalı fonksiyonlarını, olaylarını ve özelliklerini inceleyelim;

serialPort.BaudRate: SerialPort sınıfının BaudRate isimli özelliği bilgisayardan kontrol edeceğiniz sistem ile haberleşme esnasında ki veri iletişimi hızı. Bu özellik sistemden sisteme değişiklik göstermektedir. BaudRate için şunu söyleyebiliriz saniye gönderilen bit sayısı, eğer sisteminizle iletişim hızınız 9600 ise bilgisayarın seri portundan saniyede 9600 bit veri gönderip alabilirsiniz demektir. Bu yüzden eğer sisteminiz 19200 ise ve siz bilgisayar programından bu özelliği set etmez iseniz verileri sağlıklı bir şekilde gönderip alamayacaksınız çünkü bu özelliğin default değeri 9600.

serialPort.IsOpen: SerialPort sınıfının IsOpen isimli özelliği seri portun açık olup olmadığını bool türünden söyleyen bir özellik. Portu kullanmadan önce mutlaka açık olup olmadığını kontrol etmenizde fayda var eğer portu kullandıktan sonra kapatmadan tekrar açmaya çalışırsanız programınız hata verecektir.

serialPort.PortName: SerialPort sınıfının PortName isimli özelliği seri portunuzun ismini isteyecektir. Eğer bir çevirici kullanmadan direk seri porta bağladıysanız ‘COM1’, bir çevirici aracılığıyla ismini değişti ise ‘COM5’, ‘COM6’ vb. string türünden port isminizi girebilirsiniz.

serialPort.ReadTimeout: SerialPort sınıfının ReadTimeout isimli özelliği seri portun cihazdan kaç saniye boyunca cevap beklemesini istiyorsanız onu int türünden mili saniye cinsinden girmeniz gerekiyor. Eğer istediğiniz cihazdan 3 saniye boyunca cevap gelmez ise hata vermesi ise buraya serialPort.ReadTimeout = 3000 demeniz gerekiyor.

serialPort.WriteTimeout: SerialPort sınıfının WriteTimeout isimli özelliği ise seri portunuzun yazma işlemini kaç saniye boyunca sürdürmesini istiyorsanız yine int türünden mili saniye cinsinden bu özelliği set etmeniz gerekmektedir.

Serial Port sınıfının önemli bir kaç özelliğini inceledikten sonra şimdide bir kaç tane fonksiyonlarını inceleyelim.

serialPort.DiscardInBuffer(): SerialPort sınıfının DiscardInBuffer isimli fonksiyonu seri portunuzun bufferını temizlemek için kullanılan geri dönüş değeri ve parametresi olmayan fonksiyondur. Çok sık veri alış-verişi yaptığınız sistemlerde kullanmanız gereken bir fonksiyondur. Bazen haberleşme esnasında kullanmadığınız ama portda kalan verileriniz olabilir böyle bir durumda ikinci kez veri okumaya kalktığınız da hem o önceki okumada kalan verileri hem de cihazdan gelen doğru cevabı alırsınız. Bundan dolayıda doğru veri ile işlem yapmamış olursunuz.

serialPort.DiscardOutBuffer(): SerialPort sınıfının DiscardOutBuffer isimli fonksiyonu seri portunuzun veri gönderme aşamasındaki verileri temizlemek için kullanmanız gereken geri dönüş değeri ve parametresi olmayan fonksiyonudur.

serialPort.GetPortNames(): SerialPort sınıfının static GetPortNames isimli fonksiyonu bilgisayarınızdaki kullanılabilir portların isimlerini size string dizisi şeklinde söyleyen fonksiyondur. Eğer kullanıcınıza açık olan portları söylemek istiyorsanız bu fonksiyonu kullanabilirsiniz. Şöyle ki; formunuzda bir comboBox olduğunu düşünün ve bu comboBox’ın içini kullanılabilir portların isimleri ile doldurmak istiyorsanız. Bunun için iki yol;

Birinci Yol;

for (int i = 0; i < 30; i++)
{
   try
   {
      serialport.PortName = "COM" + i.ToString();
      serialport.Open();
      comNo_cb.Items.Add(serialport.PortName);
      serialport.Close();
   }
   catch (Exception)
   { continue; }
}

En fazla 30 tane port olduğunu düşünürüz ve bu portları tek tek açıp kapatırız, eğer sorunsuz bir şekilde açılırsa demek ki bu port kullanılabilir deriz ve hemen comboBox’a ismini yazarız. Birde bunu GetPortNames ile yapalım;

comNo_cb.Items.Add(SerialPort.GetPortNames());

2. yol hepimiz için daha hayırlı bir yol gibi duruyor :).

serialPort.Open(): SerialPort sınıfının Open isimli fonksiyonu seri portunuzu açmanıza yarar. Hemen şunu söylemekte fayda var bu işlemi yapmadan önce bir hata almak istemiyorsanız port adını, baudRate’inizi belirtmeyi unutmayın. Eğer port adını belirtmez iseniz veya yanlış yazarsanız hata alacaksınız.

serialPort.Read(byte[] buffer, int offset, int count): SerialPort sınıfının Read isimli fonksiyonu seri portunuzdan veri okumanızı sağlayan bir fonksiyondur. İlk parametresi byte türünden bir dizi, ikinci parametre dizinin kaçıncı indisinden itibaren veri yerleştireceğini, son parametresine ise kaç byte veri okuyacağınızı söylemeniz gerekiyor. İlk parametre char türünden bir dizide olabilir. Fonksiyonun geri dönüş değeri ise kaç byte okunduysa onu size int türünden söyler.

serialPort.ReadByte(): SerialPort sınıfının ReadByte isimli fonksiyonu seri portdan sadece bir byte okumanızı sağlayan fonksiyon. İsmi ReadByte olmasına rağmen geri dönüş değeri int türüdür ve size okunan değeri söyler.

serialPort.ReadExisting(): SerialPort sınıfının ReadExisting isimli fonksiyonu çağrıldığı zaman seri portdan okunabilen tüm veriyi size string türünden geri döndürür.

serialPort.ReadLine(): SerialPort sınıfının ReadLine isimli fonksiyonu seri portdan NewLine karakteri gelene kadar tanımladığınız ReadTimeout süresince bekler. Gelen veriyi size string türünden geri döndürür.

serialPort.Write(): SerialPort sınıfının Write isimli fonksiyonunun 3 tipi var bunlardan biri cihaza göndermek istediğiniz veriyi string türünden göndermenizi sağlıyor;

serialPort.Write("Bu veriyi cihaza yaz");

İkinci yöntem ise veriyi byte dizisi türünden göndermenizi sağlıyor.

byte[] gidecekVeri = new byte[] {0x30, 0x31, 0x32, 0x33, 0x34};
serialPort.Write(gidecekVeri, 0, gidecekVeri.Length);

Tahmin edeceğiniz gibi ilk parametre byte türünden bir dizi, ikinci parametre ise bu dizinin kaçıncı indisinden itibaren üçüncü parametredeki değer kadar seri portdan veri göndermenizi istiyor. Birde byte dizisinin yerine char dizisi ile gönderebileceğiniz üçüncü bir tipi bulunuyor.

serialPort.WriteLine(): SerialPort sınıfının Write isimli fonksiyonu göndermek istediğiniz veriyi string türünden parametre geçerek gönderebilirsiniz. Write fonksiyonundan tek farkı göndermek istediğiniz verinin sonuna ‘\n’ karakterini ekliyor olması.

Genel olarak serialPort sınıfının fonksiyonlarını ve özelliklerini inceledik, en kısa zamanda bununla ilgili bir uygulama yapıp siteme koymayı düşünüyorum.Seriport ile uğraşan arkadaşlar için umarım faydalı olmuştur.

Görüşmek üzere, iyi çalışmalar…

Paylaş:
37 Responses to C# Serial Port Bileşeni!
  1. Osman

    Merhaba. Sitenizi cok faydali buldum. C# projemde data_received kisminda problem yasiyorum. Kisa ya da uzun data dizisi geldiginde data_received icerisine bir kac kez girebiliyor. Ayni islemi birkac kez yapmamasi icin ne yapmam gerekir.

  2. tayfun

    merhabalar.
    biz seri port tan verileri okuma işlemini yapıyoruz fakat bizim ihtiyacımız olan extradan bu aldığımız verilere pc i saati üzerinden bir zaman ataması yapmak ( okunan her veri için o anki zamanı işlemesi.) bu sağlanabilinir mi yardımcı olabilir misiniz? teşekkürler.

  3. yucel özcan

    hocam merhabalar ben serialport1.readexiting verı gelıyormu dıye kontrol ettırmek ısıtıyorum if komut yapısı ıle !=null seklınde yapıyorum fayda etmıyor nasıl kontrol edebılırmycl17041990@gmail.com

  4. sema

    İyi gunler burak bey. Ben serial porttan okuma yapmaya caliisiorum. Realterm diye hazir okuyan programla benim c# da okudum veri ayni degil. Bunun sebebi nedir nasil duzeltebilirim .

  5. ismail kaya

    Selam kardeş. Benim c# ile turnikeye bir kez aç demem gerekiyor. Aradım ama bir şey bulamadım. Bir yazılımcıya yaptırayım dedim çok para istediler. Yardımcı olursan sevinirim. Ben Turnikeye nasıl bir veri göndermeliyimki 10 saniye kadar açık kalsın. Kısa devre yaptırmam gerekiyormuş ama hiç bilgim yok yardımcı olursan sevinirm.

  6. Semen

    merhabalar, ben seri port üzerinden enerji analizör dinleme programı yapmaya çalışıyorum fakat 250’ye yakın textbox var ve 4 groupbox var her birinde farklı sayılarda textbox var nasıl kontrol yapmam gerektiğini bilmiyorum mantığını oluşturamadım yardımcı olabilir misiniz ?

  7. Burak Özkan

    Merhabalar, bunu elektronik malzeme satan yerlere sorarsanız daha sağlıklı bilgi alabilirsiniz. Seriporttan VGA dönüştürücü var mı bilemiyorum.

  8. celil akkaş

    seri port tan vga ya döüştüren kablo lazım nasıl bulabilirim yardımınızı bekliyorum

  9. ömer özdemir

    merhabalar ben bir php programı yapacağım ama onun için yerel sunucu yapmak istiyorum 1 buton(visual studio debug butonu gibi)olaçak ona bastığımda varsayılan webbrowserda proje açılaçak eğer yapamazsanız. neleri araştırmam lazım

  10. sinan

    Tebrikler güzel bir döküman olmuş.

  11. canan

    hocam seri porttan a harifini alınırsa adınız s harfi alınırsa soyadınızı bilgisayara gönderen c programı lazım yarın ki sınavım için çok acil yardım istiyorum.ilginiz için şimdiden çok teşekkğr ederim

  12. necip hoca

    emeginize saglık. iyi çalışmalar.

  13. Mehmet Muhittin

    Yararlı paylaşımlarınız için teşekkür eder, iyi çalışmalar dilerim.

  14. büşra

    paylaştıklarınız çok yardımcı oldu emeğinize sağlık çok teşekkürler

  15. furkan95735

    İyi çalışmalar …

    Çok güzel anlatmışınız elinize sağlık yalnız ben bir şey anlayamadım daha yeni başladık C# diline 🙁

    Hocamız bize eğer serial porta 1 byte lık veri gönderip manyetik alan oluşturmam gerekiyor . Manyetik alan oluşturduğumuzda oraya bir şey bağlayacakmışız ve onuda led veya lambaya bağlıyacakmışız yanacakmış 🙂 biraz karışık oldu ama anlayıp cevap bulursanız sevinirim .

  16. Ömer

    Öncelikle merhaba. Benim bluetooth yoluyla bilgisayardan telefona baglanmam ve gelen giden kutusunu çekmem rehber üzerinden değişiklik yapabilmem gerekiyor nasıl bir yol izlemem hakkında biraz bilgilendirme yapmanız mümkün mü?

  17. yalçın şahin

    Burak kardeş merhabalar. Benim bir proje ödevim var bu portlarla ilgili. Bir tane GPS’i bilgisayara bağlayıp bu GPS’ten gelen veriyi textboxta göstermem gerekiyor. Port açma işlemlerini yapıyorum. porta veri de gönderiyorum. ama veri alma komutunu bir türlü beceremedim.

    Private Sub Buttonverial_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Buttonverial.Click
    Timer1.Start()
    Label6.Text = ” Veri Alımı Başladı”
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Timer1.Stop()
    Label6.Text = ” Veri Alımı Bitti”
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Dim gelen As String

    gelen = prt.ReadExisting()
    RichTextBoxal.Text = val(gelen)

    End Sub

    yaptığım işlemi timer aracılığıyla yapmak istedim. veri akışı daimi olduğu için akışı bir yerde durdurabilmek için böyle birşey yaptım. konuyla ilgili farklı bir bakış açısı üretebilirsen paylaşmanı isterim. birde senin projeler C dilinde benimki VB dilinde sıkıntı olurmu bilmiyom ama yinede yardımın dokunacağını düşünüyorum. Yardımını bekliyorum. Şimdiden teşekkür ederim.

  18. Burak

    Bu hatanın sebebi, cihaz ile iletişim halindeyken com noktası bağlantısının kesilmesinden kaynaklanıyor. Bağlantıyı her 3 saniye de bir açıp kapatıyorsanız da problem olabilir. Kod tarafını görmeden net bir şey söyleyemeyeceğim.

  19. erkan

    Hocam tesekkurler ancak cihaz kapalı degil ve hyperterminal den kontrol ettigimde surekli ve devam eden sekilde veri geldigi goruluyor. acaba cihaz bir yerde kesme mi yapıyordur..

  20. Burak

    Bu problem bilgisayar yazılımından kaynaklanmıyor, seri portdan veri akışı olduğu zaman veya cihazdan cevap beklenildiği zaman, cihazı kapatırsanız bu hatayı alırsınız.

    Iyi Çalışmalar,

  21. erkan

    hocam bi konuda yardım rica edecegim. com porttan bilgiyi aldım hicbi sorun yok. timeri icinde 3 sn de bi veri cekiyor. fata bi muddet sonra “Bir iş parçacığı cıkısı veya bir uygulama isteginedeniyle G/Ç işlemi iptal edildi” diye hata veriyor.. bir cok sey denedim fakat cozemedim.. bi fikriniz varmıdır acaba ?

  22. Burak

    Merhabalar,

    Yazdıklarınız anlayamadım. Rica etsem problemi bir kez daha anlatabilir misiniz?

  23. Ahmet

    komut bu şekildedir hocam.

    serialPort.ReadTimeout = 300;
    for (int x = 0; x <4; x++)
    {

    lbl_KarIdTut.Text += serialPort.ReadByte().ToString("X2");

    }

  24. Ahmet

    hocam kolay gelsin ben serialPort dan veri okutuyorum cşhar kapanıp açılınca topraklama yapıyor 2 bitlik 00 verisini gönderiyor. bilgisayara ben serialPort.ReadTimeout = 300; ile uyarı veriyor o şekilde olunca ancak gelen 00 verisini de silmek istiyorum bunun için ne yapmam lazım

  25. Burak

    Elbette yardımcı olurum. Projeniz hakkında ve yapmak istediğiniz hakkında detaylı bilgi verirseniz yardımcı olmak isterim.

    İyi Çalışmalar.

  26. qdrpro

    Merhaba Burak Bey
    Endüstriyel otomasyonda kullanılan PLC lerle ilgili c# (vs2010) ile plc arasında seri haberleşme ve ethernet haberleşmelerini yapmak istiyorum. Bu konuda yardımcı olabilir misiniz?

    abdulkadir.yavuzkan@gmail.com

  27. Irmak

    Merhaba Mehmet Bey,

    Ben pic’le bilgisayar arasında iletişim kurmaya çalışıyorum. Write yaparken herhangi bir problem yok ama hiçbir şekilde read edemiyorum. Örneğin aşağıdaki kod compile ediyor ama herhangi bir yazı göremiyorum text boxta.
    int boyut = serialPort1.BytesToRead;
    char[] okuncak = new char[boyut];
    serialPort1.Read(okuncak, 0, boyut);
    txtReco.Text = okuncak.ToString();
    Pic’in birşeyler gönderdiğinden eminim çünkü çıkışına led bağlı ve led yanıp sönüyor. Readline komutuyla da okuyamıyorum. Yardımcı olabilirseniz çok sevinirim.

  28. Burak

    Merhabalar,

    Programınızın FormLoad olayına; CheckForIllegalCrossThreadCalls = false; satırını ekleyin o hatayı almayacaksınız.

    Kolay Gelsin, İyi Çalışmalar…

  29. Ferdi Gürtekin

    hocam asagıdaki yazdıgım kodda veri geldiğinde serı porttan gelen bılgıyı alıyor ve listboxa eklıyor fakat bu lıstboxa ekleme kısmında hata verıyor nedeni sizce nedir hocam nerde hata var
    aşağıdaki resımdekı hatayı verıyor
    http://multigncl-host.googlecode.com/files/seriport%20hata.png

    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;
    namespace seriport
    {
    public partial class Form1 : Form
    {

    public Form1()
    {
    InitializeComponent();

    }

    void read()
    {
    string data= serialPort1.ReadLine();

    listBox1.Items.Add(data);
    serialPort1.Close();

    }

    void write()
    {
    if (serialPort1.IsOpen)
    {
    serialPort1.Close();
    }
    serialPort1.Open();

    serialPort1.WriteLine(textBox1.Text);

    }
    private void button1_Click(object sender, EventArgs e)
    {
    write();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    if (serialPort1.IsOpen)
    {
    serialPort1.Close();
    }

    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {

    }

    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    string veri =serialPort1.ReadLine();

    listBox1.Items.Add(veri);
    serialPort1.Close();

    }

    private void button2_Click(object sender, EventArgs e)
    {
    // read();

    }

    }
    }

  30. Fatih Yorulmaz

    Mehmet Bey teşekkür ederim. hatanın sebebi buymuş

  31. Mehmet Akif OVA

    Fatih Bey Merhaba,

    Şayet ReadTimeout değerini tanımlamamışsanız programınız veriyi okuyamadığında kilitlenir.
    Sanırım siz hem ReadTimeout değerini vermediniz hem de readLine() metodunu kullanıyorsunuz.

    Kolay gelsin.

  32. Fatih Yorulmaz

    Merhaba

    seriport’un bütün ayarları yaptım. fakat veri oku dediğimde program veriyi okumuyor. kitleniyor ve hiç bir hatada vermiyor. sizce nerde hata yapıyorum

  33. Osman EKİZ

    Dediğinizi bir nebze olsa da anladım fakat düşünün ki elimde bi picle yapılmıs bir elektronik devre.Bu devre dısarının sıcaklıgını nemini vs. ölçüyo ben de bu ölçülen sıcaklığı seriportla devreden alıp grafiğe aktaracağım bunun için binary int vs dönüşüm gerekli mi.Grafik kısmını hallettim fakat veriyi devreden alma işi sadece seriporu açıp kapama ve okuma olaylarıyla gerçekleştirilebilr mi ? Peki elimizde elektronik devre yok da pcnin cpu sıcaklığını kodlarla alabilir miyiz biostan felan(sayı olarak).İlginize teşekkürler selamlar…
    ekiz_osman90@hotmail.com

  34. Burak

    Merhabalar,
    Anladığım kadarıyla sizin probleminiz seriport’dan veri alıp göndermek değil binary türündeki bir sayıyı int türüne dönüştürmek. Bunu mikrodenetleyici tarafında da yapabileceğiniz gibi windows form tarafında da yapabilirsiniz. .Net tarafında direk binary türünden bir değişkeni int türüne dönüştürme yapılamıyor. Kendiniz bir fonksiyon ile bu problemi çok rahat halledebilirsiniz.

    Kolay gelsin, iyi çalışmalar…

  35. Osman EKİZ

    Selamın Aleyküm henüz bir uygulama yaptınız mı acaba benim çalıştığım bir uygulama var o da seri porttan alınan sıcaklıgı grafik olarak gösterme fakat sadece sıcaklığı alıp grafiğe dönüştürme yani binary i int türüne çevirmem gerekiyor bunun hakkında yardımlarınız olursa sevinirim.Mail adresimi bırakıyorum İi çalışmalar Selamlar…

  36. Burak

    En kısa sürede sitemde paylaşacağım. Bu aralar biraz yoğun geçiyor ama siteme ekleyeceklerimin arasında.

    Kolay gelsin, iyi çalışmalar…

  37. Fatih

    merhabalar bu konu ile ilgili bir örnek varsa elinizde bunu incelemem için gönderebilirseniz çok memnun olurum. Teşükkürler. iamtheeggmantheyaretheeggman@yahoo.co.uk

Bir Cevap Yazın

Your email address will not be published. Please enter your name, email and a comment.