İlginizi Çekebilir
  1. Ana Sayfa
  2. C Sharp

C# Seri Port RS232 Veri Okuma

Bu yazıda C# ile Seri Port (Com Port) üzerinden RS232 ile terazi ve kantar gibi cihazlardan veri okuma işlemi anlatılmaktadır.

C# Seri Port RS232 Veri Okuma
C# Seri Port RS232 Veri Okuma
+ - 10

Merhabalar, C# Seri Port RS232 Veri Okuma yazım ile C# eğitim setine devam ediyorum. Bu yazıda sadece seri porta (com) bağlanarak gelen veriyi okuma işlemi yapacağız. Yani seri porta veri yazma işlemine bu yazıda değinmeyeceğim. Seri port cihazım olmadığı içinde nasıl çalıştığını gösteremeyeceğim. Bu sebeple sadece kodları olacak. Gelin seri port rs232 okuma işlemini nasıl yaptığımıza bakalım.

C# Seri Port RS232 Veri Okuma

Giriş kısmında belirttiğim gibi sadece seri port rs232 veri okuma yapacağız. Veri yazma işine hiç ihtiyacım olmadığı için hiç kullanmadım dolayısı ile o kodları veremeyeceğim. İnternetten bakıp yazabilirim böyle diye ama prensip meselesi çalıştığını görmediğim kodları paylaşmıyorum.

Ayrıca bu porta Com Port ‘ta denebilmektedir. Com, communication yani haberleşmeden geliyor. Bilgisayarımızdaki Com Portlar otomatik olarak genellikle COM1, COM2 şeklinde isimlendirilmiş olur.

Seri port’u bilmeyen arkadaşlar için, seri port aşağıdaki gibi VGA’ya benzeyen ama iki sıra pini olan bir prottur ve genellikle kantar ve terazilerden veri alırken kullanırız.

C# Seri Port RS232 Veri Okuma

Burada şuna bir ayrım getirelim. Seri Port ile RS232 aynı şeyler değillerdir arkadaşlar. Seri Port yukarıda gördüğünüz görseldeki gibi bağlantısı olan bir bağlantı şeklidir. RS232 ise Telekomünikasyonda RS-232, DTE ile DCE arasındaki seri ikili tek sonlu veri iletimi ve sinyalleme için kullanılan seri iletişim standardının genel adıdır. Bu konu hakkında daha detaylı bir yazı ileride yapabilirim.

( Güncelleme 09.04.2022)

Arkadaşlar burada bir güncelleme yapmam gerekiyor.  Normalde bundan yazılarımda bahsederim ama bu yazıda gözden kaçmış. Bir dostumuz instagramdan bana ulaşarak sorun yaşadığından bahsetti. Yazıyı incelediğimde gerçekten anlaşılması zor olduğunu fark ettim. O yüzden araya bir güncelleme gireceğim.

Aşağıdaki kodlar bir class yani sınıf içerisindedir. Bu sınıfta hiyerarşik bir klasör içerisinde yer alıyor. Kodları büyük bir projemde kullandığım için tüm sınıflar birbirlerinden ayrı ve ayrı klasörlerde yer alıyor.

Yazının devamında sorun yaşamamak için lütfen önce şu adımları harfiyen gerçekleştirin. Gerekirse daha sonra düzeltirsiniz.

Solution Explorer kısmında Project Name üzerinde sağ tık yapıp Add > New Folder diyelim.

C# Seri Port RS232 Veri Okuma

Bu klasörün adına da Cls diyelim.

Sonra Cls klasörün üzerinde sağ tık yapalım ve Add > New folder diyelim.

C# Seri Port RS232 Veri Okuma

Bu klasöre de Global diyelim.

Aşağıdaki class’ı yani sınıfı bu Global klasörü içinde açacağız. Şimdi Global klasörü üzerinde sağ tık yapalım Add > Class… diyelim.

C# Seri Port RS232 Veri Okuma

Açılan ekranda class adının RS232_Connect olduğundan emin olun.

Son olarak emin olmanızı istediğim bir şey var.

C# Seri Port RS232 Veri Okuma

2. Nolu alandaki sarı alan içerisinde yazan isim sizin projenizin adı olacaktır. Kırmızı alan içerisinde yazan kısım da yukarıdaki görselde gördüğünüz gibi olmalıdır. Bundan emin olun. Klasör yolu 1. nolu kısımda gördüğünüz gibi olsa da 2. nolu alandaki kırmızı alan içerisinde yazıldığı gibi değilse hata alacaksınız. C# ve VS,  bir sınıfın nerede olduğunu 2 nolu alandaki kırmızı alan içerisinde yazan kısımdan bilir.

Şimdi yazıya devam edebilirsiniz. Artık Cls ve Global noktasında sorun yaşamamalısınız.

 

İlk işimiz her zamanki gibi bir class açmak olacak. Ben adına RS232_Connect diyorum. Siz istediğiniz ismi verebilirsiniz. Sonrasında Seri Port ile çalışmak için projemize

using System.IO.Ports;

Namespace ‘ini (isim uzayı) eklememiz gerekiyor. Namespace’i ekledikten sonra

 public static SerialPort comPort = new SerialPort();

diyerek seri port tanımlamasını yapıyoruz.

Bilgisayardaki mevcut com portların bir listesini alalım.

 public static string[] ports = SerialPort.GetPortNames();

Sonrasında seri port veri okuma hızını belirteceğimiz baud rate’leri hazırlıyoruz.

private static int[] brate = new int[] { 2400,4800,9600,19200,38400 };

Baud rate tanımı veri iletim hızı olarak bilinir ve genellikle 9600’dür. Şahsen 9600’dan başka bir baud rate kullanmadım. Büyük ihtimalle hep terazi kantar gibi cihazlardan veri okuduğum içindir. Ek olarak burada cihazımızın desteklediği hızları bilmemiz gerekiyor. Bilmiyorsak hızları tek tek deneyerek sağlıklı veri aldığımız hızı bulabiliriz.

Seri Port Bağlantısı 

Eğer sürekli baud rate ve com port değiştirmeye gerek yok ise yani geliştirdiğiniz uygulama için alınan cihazların hepsi aynı ise yukarıdaki dizileri kullanmanıza gerek yoktur. Ben uygulamalarımda hiç değiştirme gereği duymadım. Seri Port adını (COM1, COM2 vs ) adını ve baudrate’ini bildiğim için hep sql tablosunda tutarım bu bilgileri. Parametre şeklinde okur ve kullanırım.

Sıra geldi bağlantımızı açmaya… Öncelikle bağlantı açık ise kapatacağız. Kapalı ise açacağız.

        public static void PortOpen(string port_name, int baudrate)
        {
            if (comPort.IsOpen) comPort.Close();

            if (!comPort.IsOpen)
            {
                try
                {
                    comPort.PortName = port_name;
                    comPort.BaudRate = baudrate;
                    comPort.Open();
                    comPort.Handshake = Handshake.None;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.GetType().Name + Environment.NewLine + ex.Message);
                }
            }
        }

Buraya kadar ki kısmı bir class dosyası içindedir.  Bir çok deneme yapmama rağmen veriyi sürekli olarak okuyan kodları class’ta kullanamadım. Buradan sonra vereceğim kodlar ilgili formların içerisinde yer almaktadır.

Diyelim ki KantarForm adında bir formumuz olsun ve teraziden gelen KG bilgisini bu ekranda bir nesneye yazacak olalım. KantarForm’umuzu açıyoruz ve Load eventinde seri port bağlantısını açıyoruz. Portu açtıktan sonra da verileri alacak olan eventimizin atamasını gerçekleştiriyoruz.

            Cls.Global.RS232_Connect.PortOpen("COM1",9600);
            Cls.Global.RS232_Connect.comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);

Bu iki satır kod seri port bağlantısını ne zaman başlatacaksanız orada kullanabilirsiniz.

Verileri Okumak

Portu açtık ve dinlemeye başladık. Şimdi bir string değişken tanımlıyoruz. Ben bu değişkene Gelen adını verdim. Değişkeni tanımladıktan sonra DataReceived eventi tanımlıyoruz.

        public string Gelen = "";
        private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                Gelen = Cls.Global.RS232_Connect.comPort.ReadLine();
            }
            catch (System.IO.IOException) { Gelen = ""; }
            catch (InvalidOperationException) { Gelen = ""; } // bağlantı kapalı olduğunda çıkıyor

            try { base.Invoke(new EventHandler(this.DisplayText)); }
            catch (FormatException) { } // hatalı format
            catch (InvalidOperationException) { } // Pencere işleyicisi oluşturuluncaya kadar denetim üzerinde Invoke veya BeginInvoke çağrılamaz.
            catch (IndexOutOfRangeException) { } // Dizin, dizi sınırlarının  dışındaydı.
        }

Buradaki kodları biraz açıklamam gerekiyor. Öncelikle neden direk textbox’a veya başka bir nesneye yazmıyoruz derseniz bu metot içerisinde textbox vb. bir nesneye atama yapamıyorsunuz. Özellikle veriyi değişkene almak ve DisplayText gibi farklı bir metot ile bir nesneye yazabiliyorsunuz.

        private void DisplayText(object sender, EventArgs e)
        {
            calc_miktar.EditValue = RS232_Connect.Gelen_Bilgi_Formatlama(Gelen);
        }

Burada gördüğünüz gibi ReadLine() metotu ile gelen veriyi satır olarak okuduk ve gelen veriyi bir değişkene aldık. Bu işlemi yaparken iki farklı hata alabiliyoruz. Program kırılmasın diye bu hataları try catch ile ele aldım ve umursama devam et dedim.

Verileri almakla bitmiyor. Alınan veriyi de bir yere yazmamız gerekiyor. Yazma işlemi içinde DisplayText eventimizi  kullanıyoruz. Yine aynı event yani veri okuma eventi içerisindeyiz. Başka bir bir kaç try kontrolü ile DisplayText adlı eventimizi tetikletiyoruz. Burada da bir kaç hata alabildiğimiz durumlar olduğu için o hataları da umursama diyoruz.

Try Catch ‘ı burada ve burada anlattım

NOT: comPort_DataReceived metodu sürekli çalışıyor arkadaşlar. Yani bir timer nesnesi gibi sürekli portu dinleyerek oradan gelen bütün verileri alıyor.

Son olarak DisplayText eventi içerisindeki Gelen_Bilgi_Formatlama metodu da çok önemli değil. Çünkü terazi gibi cihazların çoğundan sadece Kg bilgisi gelmiyor. Dara bilgisi vs gibi bir çok veri gönderdikleri için içerisinden sadece KG kısmını almak gerekiyor. Bu sebeple de gereksiz verileri temizlemek gerekiyor. Formatlamayı bu sebeple kullanıyorum. Tabi ki bu hazır bir kod değil. Onu da siz yazacaksınız.

 


C# Seri Port RS232 Veri Okuma yazımda bu kadar arkadaşlar.

Bu kodları bir çok projemde teraziden veri okuma amacı ile aktif olarak kullanıyorum. Yani çalıştığından %1000 eminim :D

Diğer yazılarımda görüşmek üzere. Umarım faydalı olmuştur. Aşağıdaki linklerden eğitim seti sayfasına ve github projesine ulaşabilirsiniz. C Sharp Eğitim Seti eğitimi sayfasına gitmek için tıklayınız.  Derslerime özel olarak hazırladığım Github Projeme buradan ulaşabilirsiniz…  Ayrıca bu yazının PDF’ine buraya ve ya buraya tıklayarak ulaşabilirsiniz.

Sağlıcakla ve kodla kalın….

Bu yazıya tepkiniz ne oldu?

Yazar Hakkında

Lise Ağ Sistemleri ve Yönetimi bölümü, üniversite Bilgisayar Programcılığı bölümü Ön Lisans, Yönetim Bilişim Sistemleri Lisans öğrenimi aldım. Askerlik görevimi tamamladım. Uzmanlık alanım; C# ve SQL Programlama dilleri ile müşteri odaklı, kullanıcı dostu ERP ve CRM gibi sistemleri geliştirmektir. Ayrıca şuanda PHP ve MYSQL alanında projeler geliştirmekteyim. C++, Phyton, Xamarin, MVC gibi konuları öğrenmek ve kendimi geliştirme çabası içerisindeyim. Discord için: https://discord.gg/FBxZeHu9

Değerli yorumlarınızı bekliyorum. :)

Yorumlar (10)

Popüler Yorumlar
  1. Merhaba kontrol etmeniz gereken şeyler;
    1 – Baudrate ‘i kontrol edin. Bağladığınız cihazın verdiği hız nedir? Cihazlar genelde 9600’ü kullanır
    2 – Kullandığınız seri kabloda sorun olup olmadığını kontrol edin.
    3 – Bağladığınız cihaz sürekli veri gönderme yapıyor mu? Özellikle tartı ve terazilerde sürekli gönderme veya tuş ile gönderme gibi ayarları vardır.
    4 – Cihazın veri göndermesinde sorun olup olmadığını kontrol edin.

  2. boş geliyor veriyi okumuyor

Yapılan Yorumlar
  1. boş geliyor veriyi okumuyor

    • Merhaba kontrol etmeniz gereken şeyler;
      1 – Baudrate ‘i kontrol edin. Bağladığınız cihazın verdiği hız nedir? Cihazlar genelde 9600’ü kullanır
      2 – Kullandığınız seri kabloda sorun olup olmadığını kontrol edin.
      3 – Bağladığınız cihaz sürekli veri gönderme yapıyor mu? Özellikle tartı ve terazilerde sürekli gönderme veya tuş ile gönderme gibi ayarları vardır.
      4 – Cihazın veri göndermesinde sorun olup olmadığını kontrol edin.

  2. 2 sene önce

    Selamlar.
    Dijital kumpas var elimde, seri porttan veri geliyor fakat ayrıştıramadım, ya siliyor, ya da 90 milimden sonra hataya düşüyor.
    Çok acil.
    Seri porttan gelen veri bu = 01A+00030.97 = yani 30.97mm,
    bunu textboxa 30.97 mm olarak aktarmam lazım.
    Teşekkürler.

    • Selamlar,
      Bu veriyi alıp Replace veya Split kullanarak ayrıştırabilirsiniz. Bende genelde bu şekilde kullanıyorum. Örneğin sizin verdiğiniz değer için şöyle yapabilirsiniz.

      string value = "01A+00030.97";
      double mm = Convert.ToDouble(value.Split('+')[1])

      Burada değeri + ifadesinden parçalık. Böylece elimizde iki parça oldu. Biri 010A diğeri ise 00030.97. Bizde 1. index yani ikinci parçayı aldık. Soldaki sıfırlar matematikte anlamsız olduğu için 00030.97 değerini double’a çevirdiğimizde elinizde şu değer olacaktır. 30.97

      Eğer ölçümlere göre + kısmı kayboluyorsa kumpasın ölçebileceği minimum ve maksimum aralıkları dahil ederek 5, 6 gerekirse 10, 15 örnek ölçüm yapın ve her ölçümde ortak bir nokta arayın. O noktayı kullanarak parçalama işlemlerini yapın.

      Yada kumpas’ın üreticisi ile iletişime geçerek nasıl sadece ölçüm bilgisini alabileceğinizi sorun. Örneğin terazilerde çeşitli ayarlar vardır. Dara vs bilgisi de gönderir ama sadece KG bilgisini göndermesi için ayaları vardır.

      İyi Çalışmalar.

  3. 1 sene önce

    Merhaba, Teraziden gelen veri
    ST,GS 14.72kg
    U.W. 530.276 g
    PCS 28pcs
    bu şekilde 2 problemim var öncelikle çok seri veri geliyor bunu nasıl yavaşlatabilirim ikincisi ise sadece PCS kısmı gerekli bana bu bölümü almak için nasıl bir yol izleyebilirim ?

    • Merhaba, Çok seri veri gelmesi olması gereken şey. Yavaş gelmemesi lazım zaten. Teraziden iki türlü veri gelir. 1. sürekli akış, 2. Bir tuşa basılınca gönderme.
      İlk olarak hızlı gelmesi iyi. Hızlı gelir ve siz o hızda okursunuz problem değil. Yani bu bir sorun değil olması gereken durumdur.

      İkinci olarak
      1 – Terazinin üreticisi ile görüşün ve sadece PCS kısmını gönderebilmek için herhangi bir ayarı var mı diye sorun. Eğer böyle bir ayarı varsa tarif ederler. Böylece uğraşmadan çözersiniz.
      2 – Split gibi metotlar ile gelen veriyi parçalara ayırarak sadece istediğiniz veriyi ayrıştırabilirsiniz.

      string gelenVeri = “ST,GS 14.72kg
      U.W. 530.276 g
      PCS 28pcs”;
      // 1 – Bu değişkende kaç tane boşluk var önce onu saymak gerekiyor.
      // 2 – Bu boşlukların yerleri her zaman aynı mı kalıyor= Örneğin 14.72kg burada sayı ile kg arasında boşluk yokken, 530.276 g burada sayı ile g arasında boşluk var. Tahminimde burası kg olduğunda boşluk olmayacaktır.
      // 3 – Tüm ihtimallere göre çalışacak şekilde gelen veriyi aşağıdaki gibi parçalara ayırarak sadece pcs değil kg ve g bilgilerini de alabilirsiniz.

      string[] gelenVeriler = new string[7]; // her boşluğa göre ayıracağımız yukarıdaki veri 7 parça oluyor.
      gelenVeriler = Split(‘ ‘, gelenVeri );
      double pcs = replace(“pcs”,””,gelenVeriler[6]); // 7. parça 6. index olur. 28pcs ifadesindeki pcs için replace yaparak siliyoruz.

      Şuanda pcs değişkeninde 28 değeri olacaktır.

      NOT kodları kafadan yazdım. metotlara verilen parametrelerin yerlerinde hata olabilir.

  4. merhaba Com port bağlantısını aynı pcdeki iki farklı barkod programında kullanmak mümkün mü

    • Merhaba, 1 comport sadece bir bağlantı sunabilir. Farklı bağlantılar farklı comportlar üzerinden olabilir. Bir bilgisayarda iki barkod programı kullanılancaksa iki comport olması lazım

  5. 2 ay önce

    Merhaba Ankara Üniversitesi Hidroket topluluğunda hidromobil araç geliştiriyoruz. Kullandığımız yakıt pilinden veri okumamız gerekiyor. Bu işlemi yaparken yakıt pilini bilgisayara nasıl bağlayabiliriz ve seri port açma işlemini nasıl gerçekleştirebiliriz? Bu işlemi yaparken RS-232 kullanacağız.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.