C# ile Arduino Haberleşme
|
Merhabalar…
Bu yazıda C# ile Arduino arası iletişime değineceğiz. Bu haberleşmeyi sağlamak için Arduino’ nun seri portu ile bilgisayar üzerinde oluşturduğumuz bir sanal COM porta bağlanacağız. Bu bağlantı gerçekleştikten sonra yapabilecekleriniz artık sizin hayal gücünüzle sınırlıdır…
Arduino’ dan veri yazıp C#’ dan okuma işlemi son derece kolaydır. Ancak bunun tam tersini uygulamak diğerine göre biraz daha zor olacaktır. Bunun sebebi C#’ ın Arduino’ da kullanılan C++’ a göre çok daha gelişmiş bir dil olması ve çok daha geniş kütüphanelere ve işlevsel fonksiyonlara sahip olmasıdır.
Şimdi bağlantının nasıl gerçekleştiğine bakalım. Öncelikle C# üzerinden COM port oluşturmaya bakalım. Bu portu oluşturabilmek için iki önemli parametreye ihtiyaç vardır. Bunlardan biri Arduino’ da kullandığımız Baud Rate diğeri ise port ismidir. Baud rate int yada long değer alabilir. Ancak port ismi string olmalıdır.
serialPort1.PortName = "COM1"; //Arduino' muz COM1' e bağlı serialPort1.BaudRate = 9600; //Arduino' nun çalıştığı Baud Rate
Artık arayüzümüz Arduino’ ya bağlanmaya hazır. Bu kodları bağlan butonu içerisinde kullanırsak buton yardımı ile bağlantımızı kontrol etmiş oluruz.
Bağlanmak içinse bu fonksiyonu kullanmamız gerekli:
serialPort1.Open(); //Com porta bağlanma işlemi
Bunun yanı sıra C#’ ın Seri porta bağlı cihazları otomatik olarak bulup bağlanmasını sağlayabiliriz. Ancak burada dikkat etmeniz gereken bir döngü yardımı ile bağlı portları tarama işlemi gerçekleştireceğimiz için küçük numaralı porta öncelikle bağlanacaktır. Şimdide işlemi nasıl yaptığımızı görelim.
foreach (string port in SerialPort.GetPortNames()) { serialPort1.PortName = port; serialPort1.BaudRate = 9600; } serialPort1.Open();
Open fonksiyonunu kullanırken programımızın çökme ihtimalini en aza indirmek için bir kaç güvenlik önlemi eklememizin faydalı olacaktır.
-Örneğin biz porta bağlıyken tekrar bağlan butonunu kullanırsak bağlı olan porta tekrar bağlanmaya çalışacak ve programımızın çökmesine sebep olacaktır. Bu yüzden daha önceden porta bağlı olup olmadığımıza dair ufak bir sorgu kullanmamız bu sorunu çözmemize yardımcı olacaktır.
-Olası diğer bağlanma hatalarının önüne geçebilmek içinde try/catch yapısını kullanmalıyız.
if (!serialPort1.IsOpen) { try { foreach (string port in SerialPort.GetPortNames()) { serialPort1.PortName = port; serialPort1.BaudRate = 9600; } serialPort1.Open(); button1.Enabled = false; button2.Enabled = true; }catch(Exception ex) { MessageBox.Show(ex.Message, "HATA", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Bağlantımızı güvenli bir şekilde yaptık ve şimdi daha kolay olan Arduino’ dan veri okuma işlemini gerçekleştirelim.
Arduino’ dan veri yazma işlemi için Serial monitörden veri yazarken yaptığımız işlemlerin aynısını yapacağız. Eğer farklı bir haberleşme modülü de kullanacaksak işlemi Serial nesnesi oluşturarak da yapabiliriz.
Gönderdiğimiz veri integer tipinde 2 ayrı sayı olsun:
Serial.print(10); Serial.print("|"); Serial.print(20); Serial.println("|");
Örneğimizde iki potansiyometreden okuduğumuz analog değerleri seri porta yazalım ve C# üzerinden bu verileri okuyalım. Burada işlem tamamen sizin String parse’ leme yeteneğinize bağlıdır. Ben en kolay yöntem olan C# üzerindeki “split” fonksiyonunu kullanacağım. Bu fonksiyon string bir ifadeyi belirlene karakter ile parçalayıp diziye atamaya yarar. Kullanımı basittir.
string oku = serialPort1.ReadLine(); string[] veri = oku.Split('|');
Daha sonra split işleminden geçirdiğimiz verilerimizi istediğimiz şekilde kullanabiliriz. veri[0 ] da 10, veri[1]’ de ise 20 değeri string formatında tutulmaktadır.
Görüldüğü gibi C# ile arduino’ yu COM port üzerinden haberleştirmek bu kadar kolaydır. Şimdide aynı işlemi C# üzerinden yazarak Arduino’ dan okuyarak gerçekleştirelim.
İki tane Track Bar’ ımız olsun ve bunları aynı anda gönderip Arduino içersinde parse liyelim.
if(serialPort1.IsOpen) { serialPort1.WriteLine("#" + trackBar1.Value.toString() + "|" + trackBar2.Value.toString() + "|"); }
Bu satırı istediğiniz yerde serialPort1 nesnesi bağlı olduğu için kullanmanız mümkün. Üstteki if ile olası bağlantı kopmalarında programın çökmesini önlemiş oluyoruz.
Şimdi bu veriyi Arduino’ dan okuyalım. Arduino’ da string split fonksiyonu yoktur. Bu yüzden gelen veriyi parçalamak için 2 yöntem bulunmakta. Bunun ilk serial’ den okurken int olarak parselemek ki benim kullanacağım yöntem de o şekilde. Diğer yöntem ise daha karmaşık ancak veriyi serial’ den okumayacağınız zamanlar kullanmanız gereken yöntemdir ve substring işlemlerinden oluşur. Öncelikle bu yöntemden bahsedeyim. String substring C++’ da çokca bilinen ve kullanılan bir işlemdir. Fonksiyon iki parametre alır. Başlangıç ve bitiş indexi. Bu index leride IndexOf fonksiyonu ile almanız mümkün. Örneğin “#” işaretini nasıl parseliyeceğimize bakalım.
//gelenDeger serial den okuduğumuz string olsun int deger = gelenDeger.indexOf('#'); String veri = gelenDeger(0, deger);
Böylece “#” işaretini veri ye aktarmış olduk. Ancak aynı string üzerinde bir sonraki parse işleminde başlangıç index’ inizi bir arttırmayı unutmayın.
Şimdide serial’ den okurken kullanabileceğimiz kolay yönteme bakalım.
//pwm pinine bağlı bir led olsun int deger = Serial.parseInt(); analogWrite(led, deger);
“parseInt” fonskiyonu ile serialden okuduğumuz veriyi split işleminde yaptığımız gibi parçalamak mümkün. Ancak burada parse işleminde karakter ayrımı gözetmeyecektir. Yani tam sayı dışındaki veri “|” yada “#” olmasına göre ayrım yapılmayacaktır. Bu da veri okurken özellikle kablosuz bağlantılarda bazı aksaklıklara yol açabilir. Bu yüzden başlangıça şu şekilde bu kontrol eklemeliyiz.
char karakter = Serial.read(); if(karakter == '#') { int deger = Serial.parseInt(); int deger2 = Serial.parseInt(); }
Serialden okuduğumuz ilk değer “#” ise string’ in başındayız demektir ve parse işlemini gerçekleştirebilir.
Bu işlem de bu kadar. Arduino ile C# COM port üzerimden haberleşmesi bu şekilde.
C# ile RGB projesine buradan ulaşabilirsiniz.
Teşekkürler.
Teşekkür ederim kardeş bu örnegin bir çok şeyi geliştirmeme yardımcı oldu, yolun açık olsun
Ben teşekkür ederim. İyi Çalışmalar..
merhaba , ben c# ile arduino üzerinden 6 adet servo kontrol etmek istiyorum . İnternetteki örneklerde hep led yak söndür var . 6 adet servoya farklı farklı değerler göndermek istiyorum bunu nasıl yapabilirim ?
Merhaba, bunun için verileri ayraç kullanarak gönderermeyi deneyebilirsiniz. Yani her servo için pwm değerini başında farklı bir ayraç (#, !, % .. vs) ile gönderip bunları arduino da tekrar ayırabilirsiniz. Google da ‘c# delimited string’ ile arama yaparak ilgili örneklere ulaşabilirsiniz. İyi çalışmalar..
Selam, c# ile string veriş gönderip, arduino ile seri porttan (usb ya da bluetooth) alıp if ile sorgulamak istiyorum. char tipinde sıkıntı yok fakat kelime veya metin şeklinde bir veri alıp karşılaştırmak istiyorum.
boolean stringComplete = false; // whether the string is complete
String inputString=””; // a string to hold incoming data
int kirmizi=8;
int mavi=9;
void setup() {
// initialize serial:
Serial.begin(9600);
pinMode(kirmizi,OUTPUT);
pinMode(mavi,OUTPUT);
// reserve 200 bytes for the inputString:
// inputString.reserve(200);
}
void loop() {
while (Serial.available()) {
// get the new byte:
char inChar = Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == ‘\n’) {
stringComplete = true;
}
}
// print the string when a newline arrives:
if (stringComplete) {
if (inputString == “yeşil”)
{
digitalWrite(mavi,HIGH);
digitalWrite(kirmizi,LOW);
}
else if (inputString==”kırmızı\n”)
{
digitalWrite(kirmizi,HIGH);
digitalWrite(mavi,LOW);
}
// Serial.println(“yazılan metin “+inputString);
// clear the string:
inputString = “”;
stringComplete = false;
}
}
bu kodları tek karakter olarak ( if (inputString==”k\n”) şeklinde değiştirince çalışıyor. benim amacım alınan string değer neden == operratörü ile karşılaştırmaya çalışınca yanıt yok. hatanın nedeni inşAllah bulunur. araştırmaya devam..
Merhabalar..
Öncelikle arduino’ da Serial stream’ ı ile çalışan \n e kadar okuma yapıp String değer döndürebileceğiniz bir fonksiyon var. Serial.readStringUntik(‘\n’) şeklinde kullanablirsiniz. Karşılaştırmayı yine yapmazsa for döngüsü ile ‘\n’ karakteri gelene kadar bir diziye atayıp daha sonra onu string’ de birleştirmeyi deneyebilirsiniz. Genelde kullandığım yöntem budur. Çünkü readStringUntil fonskiyonunda gecikme oluyor.
Teşekkürler. iyi çalışmalar..
Merhaba ben c# ve arduino ile bir akıllı ev projesi yapıyorum. 4 odalı bir pencereli ev olacak. Hangi odaya hırsız girerse onu bana ekrandan haber verecek ve ona göre Alarm çalmasını istersem çalacak, ışıkları yakmak istersem ışıkları yakacak. Ya da yağmur yağdığında uyarı verecek ve pencereleri kapansın ya da açık kalsın seçenekleri olacak. Bunu nasıl yapabilirim. Yardımcı olursanız çok sevinirim.
Merhaba, bahsettiğiniz projeyi Arduino ve C# kullanarak yapmak oldukça kolaydır. Seri haberleşme ile Arduino’ yu C# ile haberleştirebilir ve istediğiniz bütün işlemleri rahatlıkla yaptırabilirsiniz. Lakin hangi kısımda yardım istediğinizi daha açık olarak anlattığınız bir mail’ i baser61061@gmail.com adresine gönderebilirseniz daha iyi yardımcı olabilirim. İyi çalışmalar dilerim…