C Sharp ve RC-522 RFID İLETİŞİMİ

Arduino UNO ve RFID-RC522 kart okuyucu uygulamsaı gerçekleştirilmiştir. Okutulan kartın uid kodu, yani kart kimlik numarası C#'ta hazırlanmış olan uygulamaya gönderilmiştir. 

Bu uygulamada PC haberleşmesi sırasında oluşan bir durumu paylaşmak isterim. Arduino Serial haberleşme için kullanılan Serial.Print() komutu uygulandığında uygulama seri haberleşmenin bitmediğini düşünerek hata mesajı vermektedir. Gönderilen bilginin Serial.println() komutu ile gönderilmesi uygulamanın hatasız çalışmasını sağlamıştır. Ancak gelen veri satır sonu karakter koduyla geldiği için gelen verinin doüru şekilde alınması için sondaki karakterin kesilmesi gerekir. Bu görünmeyen karakter görünmese bile orada olduğu için veriler karşılaştırılırken aynıymış gibi görünen String ifadelerin aslında aynı olmadığı görülmüştür.

 

Arduino Kodları

#include <SPI.h>
#include <MFRC522.h>

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

#define RST_PIN 9
#define SS_PIN 10

int successRead;
bool blnKartOku = true;
char strGelenVeri = "";

MFRC522 mfrc522(SS_PIN, RST_PIN);

MFRC522::MIFARE_Key key;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  while(!Serial){
    //Bağlantı kurulncaya kadar bekliyor.
  }
}

void loop()
{
  if(Serial.available()){
    strGelenVeri = Serial.read();
    if(strGelenVeri == '1'){
      blnKartOku = true;
      Serial.println("Okuyucu Acildi.");
    }
    if(strGelenVeri == '0'){
      blnKartOku = false;
      Serial.println("Okuyucu Kapatildi.");
    }
  }
  if(blnKartOku){
    getID();
  }
  delay(50);
}

int getID() {
  //yeni bir kart okunmadıysa 0 döndür
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return 0;
  }
  //kartın UID'sini byte byte oku ve seri monitöre yaz
  char str[32] = "";
  array_to_string(mfrc522.uid.uidByte, 4, str); //Insert (byte array, length, char array for output)
  Serial.println(str); //Print the output uid string
  //kart okumayı durdur ve 1 döndür (okuma başarılı)
  mfrc522.PICC_HaltA();
  return 1;
}

void array_to_string(byte array[], unsigned int len, char buffer[])
{
   for (unsigned int i = 0; i < len; i++)
   {
      byte nib1 = (array[i] >> 4) & 0x0F;
      byte nib2 = (array[i] >> 0) & 0x0F;
      buffer[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
      buffer[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
   }
   buffer[len*2] = '';
}

 

 

C# Programı

Program için Visual Studio Community 2019 kullanılmıştır. Ücretsiz olarak bilgisayarınıza kurup kendi programlarınızı yazabilirsiniz. Arduino'dan gelen bilgileri okuyup listeleyen program aşağıdaki gibidir.

Port listesi kısmından Arduino UNO'nun bağlı olduğu port seçiliyor. "Bağlan" butonu ile Arduino ve Program arasında iletişim hattı kuruluyor. Eğer Arduino IDE'nin Seri Port Ekranı açık ise bağlantı kurulamıyor. Öncelikle Arduino'nun seri haberleşmesini gerçekleştiren diğer ekranlardan çıkmak gerekiyor. Bağlantı kurulup da RFID kart okutulduğunda gelen bilgi "Seri Haberleşme Satırına" yazılıyor ve "Veri Yığını alanına ekleniyor. Seri haberleşme satırı en son gelmiş olan veriyi yalın bir şekilde görmemizi sağlıyor. "Veri Yığını" alanı ise bağlantı boyunca Arduino'dan gelmiş olan verileri depoluyor. "Okuyucuyu Aç/Kapat" butonu ile Arduino'ya "1" veya "0" bilgisi gönderiliyor. "1" bilgisi gelince Arduino Kart okuma işlemlerini aktif hale getiriyor. "0" bilgisi gelince kart okuma işlemlerini pasif hale getiriyor ve artık Arduino RFID kart okuma işlemini yapmıyor. "Mevcut Durum" butonu, program içindeki değişkenlerin içeriğini görmemizi sağlıyor. Programın çalışmasını test ederken kullandığım bir buton, olmasa da olur. "Temizle" butonu ise program içinde gelen verilerin değerlerini ve aynı zamanda "Veri Yığını" alanı ile "Seri Haberleşme Satırı" içeriklerini temizliyor. "Sonlandır" butonu ise Arduino ile progam arasındaki iletişim hattını sonlandırıyor.

Progam Kodları

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Arduino_to_PC_v01
{
    public partial style Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string strGelenVeri = "";
        string strGelenVeriYigini = "";
        bool blnYeniVeriDurumu = false;
        bool blnKartOkuyucuDurumu = true;

        private void AktifPasif(bool baglan, bool bglSonlandir, bool gonder)
        {
            btnBaglan.Enabled = baglan;
            btnSonlandir.Enabled = bglSonlandir;
            btnGonder.Enabled = gonder;
        }

        private void AktifPasif(bool baglan, bool bglSonlandir, bool gonder, bool txtGonderiTemizle, bool txtVeriYiginiTemizle)
        {
            btnBaglan.Enabled = baglan;
            btnSonlandir.Enabled = bglSonlandir;
            btnGonder.Enabled = gonder;
            if (txtGonderiTemizle)
            {
                txtGonderi.ResetText();
            }
            if (txtVeriYiginiTemizle)
            {
                txtVeriYigini.ResetText();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            AktifPasif(false, false, false, true, true);
            string[] strArrPortlar = SerialPort.GetPortNames();
            foreach(string strPortlar in strArrPortlar)
            {
                cmBxPortListesi.Items.Add(strPortlar);
            }
            if(cmBxPortListesi.Items.Count > 0)
            {
                cmBxPortListesi.SelectedIndex = 0;
                AktifPasif(true, false, false);
            }
            else
            {
                txtGonderi.Text = "Port Bulunamadı!";
            }

            txtVeriYigini.Text = "Veri Yığını Penceresi Aktif-Ters Bölü- n";
            timer1.Start();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            cmBxPortListesi.Items.Clear();
            cmBxPortListesi.ResetText();
            AktifPasif(false, false, false, true, true);
            string[] strArrPortlar = SerialPort.GetPortNames();
            foreach (string strPortlar in strArrPortlar)
            {
                cmBxPortListesi.Items.Add(strPortlar);
            }
            if (cmBxPortListesi.Items.Count > 0)
            {
                cmBxPortListesi.SelectedIndex = 0;
                AktifPasif(true, false, false, true, true);
            }
            else
            {
                txtGonderi.Text = "Port Bulunamadı!";
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                serialPort1.BaudRate = 9600;
                serialPort1.PortName = cmBxPortListesi.Text;
                serialPort1.Open();
                AktifPasif(false, true, true, true, true);
            }
            catch
            {
                txtGonderi.Text = "Bağlantı Hatası";
            }
        }

        private void btnSonlandir_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            strGelenVeri = "";
            strGelenVeriYigini = "";
            txtVeriYigini.ResetText();
            txtGonderi.ResetText();
            blnYeniVeriDurumu = false;
            AktifPasif(true, false, false, true, false);
        }

        private void btnGonder_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                if (blnKartOkuyucuDurumu)
                {
                    serialPort1.Write("0");
                    blnKartOkuyucuDurumu = false;
                }
                else
                {
                    serialPort1.Write("1");
                    blnKartOkuyucuDurumu = true;
                }
            }
        }

        private void btnYiginTemizle_Click(object sender, EventArgs e)
        {
            txtVeriYigini.ResetText();
            txtGonderi.ResetText();
            strGelenVeri = "";
            strGelenVeriYigini = "";
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            strGelenVeri = serialPort1.ReadLine();
            strGelenVeriYigini += strGelenVeri;
            strGelenVeriYigini += Environment.NewLine;
            blnYeniVeriDurumu = true;
            //MessageBox.Show("Veri Geldi : " + strGelenVeri + "-Ters Bölü- n -Ters Bölü- n" + strGelenVeriYigini);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (blnYeniVeriDurumu)
            {
                txtVeriYigini.Text = strGelenVeriYigini;
                txtGonderi.Text = strGelenVeri;
                blnYeniVeriDurumu = false;
            }
        }

        private void btnDurum_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Gelen Veri String : " + strGelenVeri + "-Ters Bölü- n" + "Boolen Durumu : " + blnYeniVeriDurumu.ToString() + "-Ters Bölü- n-Ters Bölü- n" + "Veri Yığını String : -Ters Bölü- n" + strGelenVeriYigini);
        }
    }
}