Bilgisayar ile Arduino nasıl haberleşir?
Bu sorunun cevabı Seri İletişim protokolu. (Serial communucation protokol). Buna göre veriler tek bir hat üzerinde sırayla karakter (bit) karakter yollanılıp alınabiliyor. Tabi buna bir saat sinyali (kare dalga) eşlik ediyor.
Bilgisayardan Arduino’ya, Arduino’dan da Bilgisayara bilgiler bu yolla iletiliyor. Arduinonun üzerinde bu iletişimi sağlayan pinler dijital0 ve digital1 pinleri. Bu pinler Tx (Transmitter-verici) ve Rx (Reciever-alıcı) pinleri. Arduino nano ve üstü modellerde USB’den direk olarak bu pinlerle iletişim sağlanırken biz fark etmiyoruz ama örneğin pro mini’ye program yüklenirken bu pinleri fiziksel olarak da kullanmaktayız. “USB to TTL” dönüştürücülerde (Bunlar bilgisayardaki paralel verileri seri verilere dönüştürürler. Diğer ismi, UART: Universal Asenkron Reciever Transmitter) bulunan Tx ve Rx pinleri sırasıyla Arduino’nun Rx ve Tx pinlerine bağlanmalı. Yanı Arduino’nun alıcısı, bilgisayarın vericisine, verici bağlantısı ise bilgisayarın alıcısına bağlanıyor. Bu şekilde iletişim sağlanıyor.
Bu iletişimde ilk bit başlangıç, 8 bit veri, sonraki bir parity ve son bit ise bitiş biti olarak kodlanır ve böylece tekrar eder. Bunların sırası saat sinyali ile kontrol edilir.
Ayrıca Arduino’nun üzerinde Tx ve Rx LED’leri kullanıldıklarında yanıyor. Yani Arduino veri yollarken Tx LED’i, veri alırken Rx LED’i yanıyor. Zaten Arduino üzerinde Tx ve Rx LED’lerinin dışında bir güç LED’i (Arduinoya güç verildiğini gösteren, Arduino’nun çalıştığını gösteren) bir LED ile 13 numaralı dijital çıkışa bağlı olan toplam dört LED bulunmakta.
Kod üzerinden haberleşmek için Arduinı IDE yazılımında sağ üst köşede bulunan Seri Haberleşme Portu kullanılıyor. (Araçlar menüsü üzerinden de ulaşılabilir). Ayrıca bu port açıldığında sanki Arduino’nun üzerindeki reset butonuna basılmış gibi tüm program baştan yürütülmeye başlar.
Haberleşme başlatmak için ilk yapılacak işlem Setup kısmına
Serial.begin(9600);
yazmak. bu kod ekranda seri port ile Arduino’nun haberleşmesini başlatıyor. 9600 sayısı’na boud rate deniyor. Bu sayı bir saniyede kaç bitlik verinin alınacağı ya da yollanacağını gösterir. (Birimi bps:bit per second). Default olarak seri port ekranı 9600 olduğu için koda da aynı değeri girdik. Seri port açıldığında bu değer sayfanın altında görüntülenir. oradaki seçim ile koddaki değer aynı olmazsa seri port ekranında anlamsız karakterler gözükür.
Seri iletişimi başlattıktan sonra yapılacak şey Arduino’nun bize göndereceği yazıyı yazdırmak. Bunun için loop bölümüne yazacağımız kod:
Serial.print();
Burada parantez içine Arduino’nun seri porta ne yazacağını belirleriz. Sadece yazı yazılacaksa bu yazı çift tırnak ” “arasında olmalı ve Türkçe karakter kullanılmamalıdır. Ya da tanımlanan bir değişken tırnak işareti olmadan yazıldığında Arduino değişkenin içindeki değeri yazdırır.Değişkenler konusu programlamada başlı başına bir konudur ve ayrıca ilgilenilecektir. Ama kısaca bilinmesi gerekenler, değişken tanımları ya programın başında, ya da void loop içinde yapılmalıdır Bu örnekte iki değişken kullandık. İlki; int a=3, a isimli bir tamsayı (integer) değişkeninin içine 3 değeri atandı. İkincisi; char c. Bu c değişkenine değer atamadık, (atamak isteseydik: char b=’p’, b isimli karakter değişkenine p atardık). Bu değişken tek bitlik bir karakteri temsil eder. Neyse aşağıda birer örnek kod ve seri port ekranı görüntüsü inceleyelim:
Kod:
int a=3
char b=’p’
Serial.print(“MerhaBa”);
(Seri port ekranı : MerhaBa)
Serial.print(a);
(Seri port ekranı : 3 )
Serial.print(b);
(Seri port ekranı : p)
(Bu arada merhaBa’daki B özellikle büyük yazıldı. Tırnak içerisine ne yazarsanız aynısını çıktı olarak göreceksiniz anlamında)
Yukarıdaki Seri port ekranının birebir görüntüsü değil tek başlarına nasıl göründükleridir. Eğer kodun (loop içerisindeki) bir parçası olsalardı ekran şöyle gözükecekti:
MerhaBa3pMerhaBa3pMerhaBa3pMerhaBa3pMerhaBa3p
Alt alta yazdırmak için Serial.print () komutu Serial.println () şeklinde yazılırsa
MerhaBa
3
p
MerhaBa
şeklinde görüntülenir. Ancak loop içerisinde döngüde olduğundan sonsuza kadar yazdırılır ve bu çok hızlı olur. Eğer kodun bir kez çalıştırılması isteniyorsa bu kod setup bölümüne yazılmalıdır. Yani yukarıdaki kod void loop yerine void setup içine yazılsaydı, kod çalıştırıldığında sadece bir kez alt alta MerhaBa, 3 ve p yazdırılacaktı. Loop bölümünde tekrar edilen yazıları okuyabilmek için döngüyü yavaşlatmak gerekir. bunu yapmak için:
delay();
komutu kullanılır. Parantez içine milisaniye cinsinden zaman yazılır. Bu süre boyunca program durur, sonra alt satır derlenir. delay(1000); yazmak, o satıra geldiğinde programı 1 saniye durduracağından ekranda kayan yazıları okumak daha kolay olacaktır.her bir satır arasına bu komut yazılsaydı ekranda önce; MerhaBa, 1 saniye sonra;3, bir saniye sonra p yazılırdı. Üç Serial.println satırından sonra yazılınca bir saniyede bir alt alta MerhaBa, 3 ve p aynı anda yazılacaktır.
Karşılıklı haberleşmek istersek biz de Arduino’ya bir haber yollamalı, Arduino’da bu habere karşılık bize bir cevap yollamalıdır. Bu seri ekran üzerinden olabileceği gibi kendi çıkışları üzerinden (göz kırpma gibi) de olabilir. Böyle bir iletişimi sağlamanın yolu yine setup bölümünde seri haberleşmeyi başlattıktan sonra, void loop bölümünde:
if (Serial.available () > 0) { ….. }
kodunu yazmamız. burada seri porttan bir giriş olması halinde {} parantezleri arasındaki …. işlemlerinin yapılacağı belirtiliyor. Bu parantezler alt satıra taşınabilir. Bir de hazır yeri gelmişken istersek kodları yan yana da yazabiliriz. Arduino her nopktalı virgülü(;) satır sonu olarak işlem yapar. Bu da demektir ki her satır sonunda noktalı virgül olmalıdır! Ancak alt alta yazmak programın programcı tarafından takibini kolaylaştırdığı için genelde alt alta yazarız. Hatta kontrol için satır girintileri bile (sadece) programcı için önemlidir. Bunu şunun için hatırlattım; ({) parantezi if ile başlayan satırda da olabilir, bir alta da atılabilir. Şunu da hemen söyleyelim sadece ({ ya da } bulunan satırlar noktalı virgül ile bitmez. (bir satırda sadece { ya da } olabilir)
Kodumuza dönersek seri haberleşme mevcutsa artık Arduino’ya biz de birşeyler gönderebiliriz. Bunu yapmanın yolu seri porta istediğimiz şeyi yazmaktır. Arduino bu bilgiyi okur. Nasıl mı?
Serial.read();
komutuyla. Bu komutla seri port ekranına yazdığımız veri Arduino tarafından okunur. Bu değer bir değişkene atanmalıdır.
char c=Serial.read();
Bu kod ile okunan değer c isimli karakter(tek bit) türünde bir değişkene atandı. Şimdi biraz işlem yaptıralım. Bu işlem okuduğu değere göre olacağından bir koşul sağlanmalı . bu da yine if komutu ile yapılacak.
if (c==’e’){ ….} ya da ;
if (c==’e’){
….
}
burada okunan değerin sadece (e) olması durumunda {} parantezleri arasında işlem yapılacaktır. Bu şartta derlenecek sadece tek bir komut satırı varsa { ve } parantezlerine gerek yoktur:
if (c==’e’)Serial.println(“e yazildi”);
gibi. Burada seri port ekranında e yazdığınız zaman Arduino da size “e yazildi” diye cevap verir. e dışında yazdığınız hiçbir şeye karşılık vermez.
digitalWrite(13, HIGH);
komutu ile 13.dijital pin HIGH yapılır. Ne demekse! bu komutta; parantez içinde önce hangi çıkış olduğu, sonra da durumunun ne olduğu yazılır. Biz burada 13 dedik ama setup’tan önce bu çıkışlara isim verip, burada parantez içinde ismi de kullanabilirdik. Virgülden sonraki HIGH ya da 1, Arduino’nun o dijital çıkışını +5 volt yapar. Tahmin edeceğiniz üzere LOW ya da 0 yazmak da çıkışı 0 volta çeker. Dolayısıyla;
if (c==’e’){Serial.println(“LED yandi”); digitalWrite (13,HIGH);}
if (c==’h’){Serial.println(“LED sondu”); digitalWrite (13,LOW);}
komutları; seri port ekranına e yazdığımız zaman, ekrana ” LED yandi “yazısı yollayıp, 13.pine bağlı olan LED’i yakar, h yazdığımız zaman, ekrana ” LED sondu ” yazısını yollayıp LED’, yakar.
Ancak digitalWrite (); kullanılmadan önce bu pinlerin çıkış modunda olduğu Arduino’ya void setup içerisinde tanıtılmalıdır (tahmin edeceksiniz ki digitalRead(); için de giriş modu) Bunu yapmak için (setup içinde):
pinMode(13, OUTPUT);
yazılmalıdır. pinMode komutu parantez içerisine ilk yazılan pinin, virgülden sonra yazılan giriş ya da çıkış modunda olduğunu belirtir. Yine pin numarası yerine önceden atanmış pin isimleri kullanılabilir.
GirisPini = 8;
ataması yapılarak (unutulmasın void setup’tan önce!)
pinMode(GirisPini, INPUT);
Şeklinde tanımlama yapılabilir. Yukarıdaki örneklerde 13 numaralı pini çıkış pini, GirisPini isimli 8 numaralı pini ise giriş pini olarak tanımladık.
Özetlemek gerekirse bugün seri haberleşme hakkında biraz bilgi sahibi olduk. Seri port kullanımını, int ve char değişken tiplerini, bunlara değer atamayı öğrendik. gördüğümüz komutlar ise;
Serial.begin(9600);
Serial.print(); ve Serial.prinlnt();
delay();
if (Serial.available () > 0)
Serial.read();
digitalWrite(13, HIGH); digitalRead();
pinMode(13, OUTPUT);
Sanırım şimdilik bu kadar yeter. Hoşça kalın…
TEŞEKKÜR
BeğenBeğen
çok teşekkür ederiz emek verip bu kadar güzel ve detaylı yazdığınız için
BeğenBeğen
Rica ederim. Ben işin uzmanı değilim, öğreniyorum. Öğrenmek isteyenlere de kaynak oluşturmaya çalışıyorum. Yabancı kaynakları tarayıp doğru bilgi vermeye çalışıyorum.
BeğenBeğen
Özer Hocam selamlar.
Konunuzun altında reklam yapmak saygısızlık olurmu bilemiyorum ama 8 yaşındaki oğlumun (sizinde hemşehriniz aynı zamanda) youtube kanalında seri haberleşmeyle ilgili videoları vardı. buradan yazsam linkini ve ilgilenenler hem girip izleseler, hem de bu minik arkadaşın kanalına abone olarak ona destek olmuş olsalar hoş olmazmı 🙂
Ayrıca sizin gibi bilgili büyüklerimizin de bu miniklere desteklerini bekleriz hocam.
Selamlar.
“Emre’nin Arduino dünyası” adlı kanalının ilgili bölümü aşağıdadır:
BeğenBeğen
Teşekkür ederim desteğiniz için hocam…
BeğenBeğen
Rica ederim. Maalesef bu işlerle ilgili çok fazla takipçi (öğrenmek isteyen) olmuyor. Ama kendisini tebrik ediyorum. Teknik konularda da bilebildiğim kadarıyla bir sorusu olursa yardımcı olmaya çalışırım. Hoşça kalın…
BeğenBeğen