20 10 2011

Seri Port PC Haberleşmesi - C#

Not: Bu yazıda anlatılanlar, okuyucunun temel programlama bilgisine sahip olunduğu varsayılarak anlatılmaktadır. Bu yazıda bilgisayar ara yüzünü tasarlamak için yazılım dili olarak C# seçilmiştir.

Selam Geçler;

Bir mikro denetleyiciyle haberleşen bilgisayar programının yazılması zor gibi görünebilir ama hiçte görüldüğü kadar zor değildir. Bilgisayar ile haberleşmek için en temel haberleşme birimi Seriport (RS232) dur. Bu haberleşme protokolü hemen hemen her mikro denetleyici tarafından da desteklenmektedir. Bu yazımızda RS232 üzerinden bilgisayar programı tarafından kontrol edilen bir devre için PC programı nasıl yapılır anlatılacaktır.


Yazılan PC programının kontrol edeceği devrenin çalışma mantığını bilmemiz gerekmektedir. Devre Seriport üzerinden 5 saniye de bir üzerinde bulunan iki ledin durumlarını göndermektedir. Gönderim formatı şu şekildedir: "10-21". Bu gelen verinin anlamı 1. led sönük 2. led yanık demekdir. Biz PC programımızda bu gelen veriyi kullanarak kullanıcıya yapabileceği işlemleri sunacağız ( çok büyük işlemeler değil tabi bunlar led yanıyorsa söndürme komutunu göndermek gibi ).  Bu özelliği dışında devre birde seri port üzerinden gelen komuta göre ledlerin durumunu değiştirebilmektedir. Ledlerin durumunu değiştirmek için gönderilmesi gereken komut şu şekildedir "1-1". Bu verinin anlamı 1. ledi yak.

Devremizin nasıl çalıştığını öğrendiğimize göre artık çalışmamıza başlayabiliriz.

Çalışmamıza bilgisayar masa üstü programının görsel tasarımı ile başlayalım. Görsel tasarımın, çalışmanın her hangi bir evresi için kritik bir önemi arz etmemekle birlikte önceden yapılması bir programlamacı için ayak bağı olan bir mevzuyu aradan çıkartmakla ilgilidir. Tavsiyemdir önce görsel tasarımı bitirin.

Program Görüntüsü

Görsel Tasarım ile ilişiğimizi kestiğimize göre şimdi sıra kodlama işlemlerini tamamlamaya geldi. Önce bilgisayarın COM portlarını bulalım ve ComboBox içerisinde kullanıcıya seçmesi için listeleyelim.


Portların Listelenmesi

Yukarıdaki kod parçasının çalışabilmesi için “System.IO.Ports” namespace’nin uygun yere aşağıdaki gibi eklenmesi gerekmektedir.


Programı bu hali ile çalıştırdığımızda aşağıdakine benzer bir ekran görüntüsü elde ederiz.


COM Listesinin Gösterilmesi

Şimdi sırada bağlantının kurulması var. Bunu yapabilmek için öncelikle uygulamamıza “SerialPort” nesnesi eklememiz gerekmektedir. C# ta “ToolBox” menüsünden yararlanarak bu nesneyi projemize ekleyelim. Sonrada Görsel tasarımızda bulunan “Bağlan” butonuna iki kere tıklayarak buton görevini yazalım.


Burada dikkat edilmesi gereken “serialport” nesnesinin sadece bağlantı noktası olan “PortName” özelliğini değiştirdik. Bir seri port bağlantısının baudRate, StopBit sayısı, Parity v.b. birçok özelliği daha vardır. Bu uygulamada nesnenin başlangıç değerleri kullanılacağı için değiştirilmedi. Siz isterseniz daha fazla liste kullanarak, kullanıcıya daha fazla ayarı değiştirme olanağı tanıyabilirsiniz.

Seri Portu açma işlemini de gerçekleştirdiğimize göre sırada veri gönderme ve alma işlemleri kaldı.  Veri gönderme işlemleri için “Led-1 Yak” ve “Led-2 Yak” butonlarına tıklayarak aşağıdaki kodları yazalım.


Şimdi de gelen verilere göre işlem yapmak için SeriPort nesnesinin DataRecieved methodunu aktif edelim (bu işlem için SerialPort Nesnesi seçildikten sonra Properties pencersinden methotları seçelim ( yıldırım şeklinde olan yer) ve DataRecieved methodunun yanına çift tıklayalım) ve aşağıdaki kodları yazalım.

Buraya kadar sıkılmadan takip ettiyseniz ve anlatılanları anladığınızı düşünüyorsanız artık bilgisayar ile haberleşen devrelerinizi denemek için Hyper Terminal, Putty vb. programlara ihtiyaç duymadan istediğiniz gibi çalışabileceksiniz.

Ya ama benim öyle devrem yok. Yapmak istiyorum ama çokta bilmiyorum bir yardım diyorsanız. Biraz daha bekleyin. Bu kodların çalıştırdığı devrenin çalışmasını da en kısa sürede paylaşacağım.

kendinize iyi davranın.




9 yorum:

  1. blogunuzu begendim yazmaya devam edin lütfen :)

    YanıtlaSil
  2. Bu yorum yazar tarafından silindi.

    YanıtlaSil
  3. yorumu sildim yanlışlıkla :)hocam bu projenin devresini mümkünse bana gönderebilir misiniz?

    YanıtlaSil
    Yanıtlar
    1. Merhaba İzzet Bey;

      Biraz Geç oldu cevap için galiba :D.

      Ben devresini geliştirme kiti üzerinden yapmıştım o vakit. Bir devre şeması yok maalesef.

      İlginiz için teşekkürler.

      Sil
  4. İyi günler,
    C# üzerinde bir seri haberleşme programı yapıyorum. Veriler 5 ' er sn arayla sürekli olarak geliyor. Gelen verileri richtextbox üzerinde online görebiliyorum. Ancak ben veri geldiğinde tasarladığım arayüz üzerinde birtakım değişiklikler olmasını istiyorum. Örneğin; 00000001 verisi geldiğinde çalışıyor butonunun rengi değişsin, 00000011 verisi geldiğinde yayında butonunun rengi değişsin gibi. Veriyi aldığım methodun içinde if ile bunu kontrol ediyorum ancak sadece program ilk çalıştığı sırada örneğin 00000001 verisi gelidiyse çalışıyor butonunun rengi değişiyor, program çalışmaya devam ederken seri porttan gelen veri 00000011 olduğunda çalışmıyor butonunun rengi değişmiyor yani senkronize olarak bu değişimi sağlayamıyorum. gelen verilere göre programda buton renkleri değişsin istiyorum. Bunun için önerebileceğiniz birşey var mıdır? Yardımcı olursanız çok sevinirim. Ek-te Proje kodlarım ve Ekran görüntüsü yer almaktadır.
    Saygılarımla

    YanıtlaSil
    Yanıtlar
    1. Merhaba Meryem Hanım;

      5 sn aralıklarla gelen verilerin alınmasını engelleyecek bir durum yoktur. Siz zaten gelen verileri RTB da görebiliyormuşsunuz. Bu da demek oluyor ki veri alma konusunda bir sıkıntı yok. O zaman problem gelen verinin işlenmesi ile alakalıdır. Ekte diye bahsettiğiniz proje dosyası maalesef gözükmemektedir. Eğer karar verme algoritmanızı paylaşabilirseniz belki bir yorum yapabilirim. Şimdilik söyleyebileceğim tek şey hatanın karar verme algoritmasında olma olasılığı diğer olasılıkların çok üstünde.

      Saygılarımla

      Sil
  5. Cevap yazdığınız için teşekkür ederim. verileri Readexisting komutu ile okuduğum için portun buffer'ında o an ne kadar bilgi varsa onu okuyormuş. Yani ben
    if (mesaj=="00000001") button1.backcolor=color.red;
    dediğimde bufferda o an 0000000100 varsa onu alıyormuş oyüzden if satırı çalışmıyor. Haberleşme konusunda acemi olduğum için sonradan farkettim.
    Ancak şimdi başka sorunum var PIC üzerinden gönderilen 3 farklı bilgi var 1 3 5 şeklinde decimal olarak gönderiliyor. Ancak ben Readbyte komutuyla bilgiyi okuduğumda ekranda 127 126 125 sayılarını görüyorum. readexisting ile okuduğumda } gibi karakterler görüyorum. Hyper terminal ile görüntülediğimde alakasız karakterler görüntülüyor. Bu neden kaynaklanıyor olabilir. yani ben neden gelen veriyi ekranda 1 3 5 şeklinde göremiyorum. Readbyte komutuyla alakalı olabilirmi eğer oyüzden ise veriyi nasıl okuyabilirim.
    public frmTerminal()
    {
    comport.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
    }

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    if (!comport.IsOpen) return;
    int data = comport.ReadByte();
    Log(data);
    }

    private void Log(int msg) //gelen veriyi görüntüle
    {
    if (msg == 127)
    {
    button1.BackColor = Color.Green;
    button2.BackColor = Color.White;
    button3.BackColor = Color.White;
    }
    else if (msg == 126)
    {
    button2.BackColor = Color.Yellow;
    button1.BackColor = Color.White;
    button3.BackColor = Color.White;
    }

    else if (msg == 125)
    {
    button3.BackColor = Color.Red;
    button1.BackColor = Color.White;
    button2.BackColor = Color.White;
    }

    rtfTerminal.Invoke(new EventHandler(delegate
    {
    rtfTerminal.AppendText(msg.ToString());
    }));
    }

    YanıtlaSil
  6. Kardeşim paylaşım için teşekkür ediyorum,bir hata alıyorum yardımcı olursan çok sevinirim.
    serialPort1.Write("1-1");
    serialPort1.Write("1-0");
    serialPort1.Write("2-1");
    serialPort1.Write("2-0");

    Butona bastığım taktirde yukarıdaki kısımlarda hatalar alıyorum.Paremetre hatalı yazıyor.

    YanıtlaSil