Arkadaşlar merhaba, bu dersimizde HC-SR04 sensörü ile ölçtüğümüz mesafeyi seri haberleşme yardımıyla anlık olarak bilgisayar üzerinden takip edebileceğimiz bir proje gerçekleştireceğiz.
Bu dersimizde aynı 2. derste olduğu gibi bir veri alma işlemi gerçekleştireceğiz.
Mesafe Ölçer Uygulaması
Dijital metre projemizdeki uygulamaya benzer bir uygulama yapacağız. Yalnızca uzaklık değerini LCD ekrandan değil de tasarladığımız arayüz üzerinden göreceğiz. Kullanacağımız sensör ile ilgili daha detaylı bilgiye de buraya tıklayarak ulaşabilirsiniz.
İlgili yazı >> Elektronik Metre Nasıl Yapılır? – (Dijital Metreyi Kendin Yap!)
Gerekli bağlantıları yaparak ve kodumuzu yükleyerek işe başlayalım.
Gerekli Malzemeler:
Arduino Kodu:
const int trigPin = 5, echoPin = 6; long uzaklik; long sure; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(5); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); sure = pulseIn(echoPin, HIGH); uzaklik = sure / 2 / 29.1; if(uzaklik > 200) uzaklik = 200; Serial.println(uzaklik); delay(100); }
C# Arayüz Tasarımı
Bu projede önceki projelerde kullandığımız araçlardan farklı bir araç kullanmayacağız. Her zaman olduğu gibi port isimlerini görüntüleyeceğimiz bir comboBox’ı , seri portu açıp kapamak için kullanacağımız 2 adet butonu ve mesafeyi anlık olarak takip edebileceğimiz bir progressBar’ı form üstüne taşıyorum. Bununla beraber form üzerinde 3 adet de label bulunuyor. Son olarak serialPort nesnesini de ekleyerek tasarımı tamamlıyorum.
Bu projede Arduino’dan veri okuyacağız. Bu yönden 2. dersteki yazımıza oldukça benziyor. Fakat bu sefer veri okumasını farklı bir yöntem kullanarak gerçekleştireceğiz. O yazıda timer kullanarak verileri almıştık. Bu sefer DataReceived eventini kullanarak seri portu devamlı olarak dinleyeceğiz. Bu sayede veri kaybı veya donma gibi sorunların yaşanma ihtimalini azaltmış olacağız. Bu anlamda timer kullanarak yapılacak bir okuma işleminden daha sağlıklı olduğunu söyleyebiliriz.
Bildiğiniz gibi bir olay(event) için kod yazmak istediğimiz zaman tasarım kısmından istediğimiz olaya çift tık yaparak kod kısmına gidiyorduk. Bu sefer bu işlemi kod içinde gerçekleştireceğiz. DataReceived olayını(eventini) tek satır kod ile tanımlıyoruz:
serialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialPort1_DataReceived);
Ardından fonksiyonumuzu yazıyoruz. Burada seri port üstünden okuduğumuz değerleri fonksiyon dışında tanımlamış olduğumuz string tipindeki değişkene eşitliyoruz. Sonrasında Invoke() içinde bir event oluşturarak bu event içerisine label ve progressBar’ın gelen değere göre değişmesini sağlayacak fonksiyonları ekliyorum. Bunları Invoke() içerisine yazmamızın sebebi ise kısaca bir çakışma yaşanmasını önlemek diyebiliriz.
Son olarak da önceki derslerden aşina olduğumuz bağlantıyı açıp kapayan butonlar için gerekli kodları yazıyorum.
Arayüzü kapattığımızda seri portun açık kalmasını önleyen kodları da ekleyerek kodu tamamlıyorum. Tüm koda aşağıdan ulaşabilirsiniz.
C# Proje Kodu
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; namespace mesafe_olcer { public partial class Form1 : Form { private string data; //data değişkenini oluştur public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { string[] ports = SerialPort.GetPortNames(); //Seri portları diziye ekleme foreach (string port in ports) comboBox1.Items.Add(port); //Seri portları comboBox1'e ekleme serialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialPort1_DataReceived); //DataReceived eventini oluşturma } private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { data = serialPort1.ReadLine(); //Gelen veriyi okuma this.Invoke(new EventHandler(displayData_event)); } private void displayData_event(object sender, EventArgs e) { label2.Text = data; //Gelen veriyi label2'ye yaz progressBar1.Value = Convert.ToInt32(data); //Gelen veriyi Int değikene döndürerek progressBar değerine eşitle } private void baglan_Click(object sender, EventArgs e) { try { serialPort1.PortName = comboBox1.Text; //Port ismini comboBox1'in text'i olarak belirle serialPort1.Open(); //Seri portu aç kes.Enabled = true; //"Kes" butonunu tıklanabilir yap baglan.Enabled = false; //"Bağlan" butonunu tıklanamaz yap label3.Text = "Bağlantı sağlandı"; label3.ForeColor = Color.Green; //Label3 yazı rengini yeşil yap } catch(Exception ex) { MessageBox.Show(ex.Message, "Hata"); //Hata mesajı } } private void kes_Click(object sender, EventArgs e) { try { serialPort1.Close(); //Seri portu kapa kes.Enabled = false; //"Kes" butonunu tıklanamaz yap baglan.Enabled = true; //"BağlanKes" butonunu tıklanabilir yap label3.Text = "Bağlantı kesildi"; label3.ForeColor = Color.Red; //Label3 yazı rengini kırmızı yap } catch(Exception ex2) { MessageBox.Show(ex2.Message); //Hata mesajı } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (serialPort1.IsOpen) serialPort1.Close(); //Seri port açıksa kapat } } }
4. dersimizin de sonuna gelmiş olduk. Umarım faydalı olmuştur. Sonraki yazıda bir mini hava istasyonu projesi gerçekleştirerek ortamdan aldığımız bazı meteorolojik verileri (sıcaklık, nem, basınç) tasarladığımız arayüzden devamlı olarak takip etmeye çalışacağız. Yorumlarınızı bekliyorum. Bir sonraki yazıda görüşmek dileğiyle, hoşça kalın. 🙂
Çok teşekkürler Bir sonraki yazıyı sabırsızlıkla bekliyorum. Çok güzel olmuş. Elinize sağlık
Çok teşekkürler 🙂
Çok teşekkürler, gerçekten güzel bir anlatım olmuş. Ancak benim şöyle bir sorunum var: Arduino karta bağlı birden fazla ultrasonik sensörden gelen veriyi C# ile form penceresine aktarmak istiyorum. Yani aynı anda iki farklı mesafeyi ölçebilir miyiz? Yardımcı olursanız çok sevinirim.
Merhaba, daha önce “hava istasyonu” yazısında aynı anda birden fazla veri gönderme örneği yapmıştık. Ona benzer şekilde verileri birbirinden ayırmak için bir ayraç kullanabilirsiniz. Ardından iki veriyi birbirinden ayırarak form üzerine yazdırabilirsiniz. Bu sayede iki uzaklık verisini tek satırda göndermiş olursunuz. Aşağıya bahsettiğim yazının linkini bırakıyorum, orada bir örneğini de bulabilirsiniz.
https://maker.robotistan.com/arduino-ve-c-sharp-hava-istasyonu/
Çok çok çok teşekkürler, meğer bir sonraki sayfada varmış aradığım çözüm. Çok kaliteli yazılar hazırlamışsınız gerçekten. Örnekler çok güzel. Elinize sağlık.
Çok teşekkürler 🙂 Başarılar
İYİ GÜNLER C# VİSUAL DA ARDUİNO DAN BİLGİYİ ALABİLMEK İÇİN VİSUAL STUDİO YA HERHANGİ BİR ARDUİNO İLE İLGİLİ BİR PROGRAM YÜKLEMESİ GEREKİYOR MU ? ARDUİNO YA YÜKLÜYORUM XBEE MODÜLLERİNİ KULLANARAK C# VİSUAL STUDİO İLE GRAFİK ÜZERİNDE VERİ AKTARIMI GERÇEKLEŞTİRMEM GEREKİYOR YARDIM EDERSENİZ TEŞEKKÜR EDERİM.
Merhaba, Visual Studio kurulumu dışında bir şey kurmanıza gerek yok. Yaptığımız işlem seri porttan okuma yapmak olduğundan herhangi bir mikrokontrolcü ile de çalışırken ekstra bir şey yüklemeniz gerekmez. İyi çalışmalar 🙂
şimdi söyle ben xbee modülleri kullanarak bu projeyi yapmaya çalışıyorum,yani verici xbee modülüm arduino ya bağlı ve alıcı xbee modülüm pc ye bağlı ,xbeelerimde haberleşiyor ,fakat visual da değer alamıyorum bu konuda yardımcı olabilir misiniz bana yarışmaya hazırlanıyorumda teşekkürler 🙂
Arduino çipli olan da sıkıntı oluyormu
Merhaba hocam, ilk derste sıkıntı çıkmadı ancak bu program çalışmıyor. COM3 yazısı çıkmıyor elle giriyorum. Elle girdikten sonra sadece Bağlantı Sağlandı yazıyor, mesafeyi göstermiyor. Arduino Seri port ekranından baktığımda orada değerler gözüküyor. Sizce nerede yanlış yapıyorum?