Arduino Programlama – Seri Port Fonksiyonları
Güncelleme 18/06/2021
Arduino Programlama Konusunu incelediyseniz bu konuya başlıya bilirsiniz
Pinlerin seri iletişimi TX / RX, TTL mantık düzeylerini kullanır (karta bağlı olarak 5V veya 3.3V).Bu pinleri bir RS232 seri portuna doğrudan bağlamayın; +/- 12V’de çalışırlar ve Arduino kartınıza zarar verebilirler.
Seri, Arduino kartı ile bir bilgisayar veya diğer cihazlar arasındaki iletişim için kullanılır.Tüm Arduino kartlarında en az bir seri bağlantı noktası (UART veya USART olarak da bilinir) vardır:
Seri, Dijital pin 0 (RX) ve 1 (TX) üzerinden ve ayrıca bilgisayar üzerinden USB üzerinden iletişim kurar. Bu nedenle, bu işlevleri kullanırsanız, dijital giriş veya çıkış için 0 ve 1 numaralı pinleri kullanamazsınız.
Bir Arduino kartıyla iletişim kurmak için Arduino ortamının dahili seri monitörünü kullanabilirsiniz. Araç çubuğundaki seri monitör düğmesini tıklayın ve begin() çağrısında kullanılan aynı baud hızını seçin.
Arduino Mega‘nın üç ek seri portu vardır: Pin 19(RX) ve 18(TX) üzerindeki Serial1, 17(RX) ve 16(TX) pinlerdeki Serial2, 15(RX) ve 14(TX) pinlerdeki Serial3. Bu pinleri kişisel bilgisayarınızla iletişim kurmak için, Mega’nın USB-to-serial adaptörüne bağlı olmadığından ek bir USB-to-seri adaptöre ihtiyaç duyacaksınız. Bunları harici bir TTL seri cihazla iletişim kurmak için kullanmak için, TX pinini cihazınızın RX pimine, RX’i cihazınızın TX pinine ve Mega’nuzun zemini cihazınızın zemine bağlayın.
Arduino Due‘nun üç ilave 3.3V TTL seri portu vardır: 19(RX) ve 18(TX) pinlerdeki Serial1; 15(RX) ve 14 (TX) pinlerdeki Serial2. 17(RX) ve 16(TX), Seri3. Pin 0 ve 1 ayrıca USB hata ayıklama bağlantı noktasına bağlı olan ATmega16U2 USB-to-TTL
Seri yongasının ilgili pinlerine bağlanır. Ayrıca, SAM3X yongasında SerialUSB olan yerli bir USB seri bağlantı noktası da var. Arduino Leonardo kartı, 0(RX) ve 1(TX) pimlerde TTL(5V) seri ile iletişim kurmak için Serial1‘i kullanıyor. Seri USB CDC iletişimi için ayrılmıştır.
if ( Serial )
Belirlenen Seri Portun hazır olup olmadığını kontrol etmemize yarar. Serial nesnelerinin mantıksal bir alan alanda kullanılması durumunda eğer belirtilen Seri Port hazır ise True eğer belirtilen Seri Port hazır değilse False değeri dönecektir.
if(Serial) örneği
void setup() { Serial.begin(9600); while (!Serial) { // Serial portun hazır olmasını bekle. ; } } void loop() { }
available ()
Serial Port’tan okuma yapmak için kullanılabilir byte( karakter )’in olup olmadığını kontrol etmemize yarar. Gönderilmiş olan veriyi byte byte değerlendirir.
available() örneği
int alinan = 0; // alınacak degeri saklamak için kullanılacak değişken void setup() { Serial.begin(9600); // Seri Portumuzu 9600 baud olarak ayarlıyoruz. } void loop() { if (Serial.available()) { // Serial Porta girdi değerinin olup olmadığını kontrol et // eğer girdi varsa oku ve yazdır. alinan = Serial.read(); // Serial Porttan değer okuma Serial.print("Alinan Deger: "); Serial.print(alinan); // integer olarak alınan değeri yazdırma Serial.print(" - Char Olarak Alinan Deger: "); Serial.println((char)alinan); // char'a dönüştürerek alınan değeri yazdırma. } }
begin ()
Arduino’dan bilgisayarımıza veya seri haberleşme portunu kullanan diğer cihazlara gönderilecek verinin hızını saniyede bit ( bit / saniye ) cinsinden ayarlar. Bir cihaz ile birlikte kullanıldığında hem Arduino’muzun hemde diğer cihazımızın veri transfer hızları aynı olmalıdır.
Kullanım Şekli:
Serial.begin(speed)
Serial.begin(speed, config)
begin() fonksiyonu bir hız parametresi ve isteğe bağlı ikinci bir parametre olarak parity veya stop biti alabilir. Arduino’muz ile bilgisayarımız arasında bir seri haberleşme gerçekleştirmek istediğimizde hız parametresi olarak 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400 veya 250000 kullanmamız gerekmektedir.
Bilgisayarımızın varsayılan hızı 9600’dür. Bu hızı değiştirmek için Arduino yazılımında yukarıda nasıl erişileceğinden bahsedilen Serial Port Ekranından aşağıdaki resimdeki gibi değiştirebilirsiniz. Kartınızın ve bilgisayarınızın hızlarının aynı olması gerektiğini unutmayınız.
Arduino Serial.begin()
void setup() { Serial.begin(9600); // veri transfer hızını 9600 olarak ayarla. Serial.println("Merhaba Dunya !"); // Seri mönitöre Merhaba dünya yaz. } void loop() { // bu örnek için loop'u kullanmadık. }
Not: Yukarıdaki örnekte düzgün çıktılar alabilmemiz için Seri Monitörümüzünde baud hızının 9600 olması gerekir.
end ()
SeriaL Portun çalışmasını devre dışı bırakır. Daha önce belirttiğimiz gibi TX ve RX pinlerini Serial Portu kullandığımızda giriş çıkış işlemleri için kullanamıyoruz. end() ile Serial Port devre dışı bırakıldıktan sorna TX ve RX pinlerini giriş çıkış işlemleri için tekrar kullanabiliriz. Serial Portu tekrar devreye almak istersek begin() fonksiyonunu kullanabiliriz.
void setup() { Serial.begin(9600); // Seri portu başlat. } void loop() { Serial.print("IMYO !"); // Ekrana IMYO yaz. Serial.end(); // Seri portu devre dışı bırak. Serial.println("Burası yazılmayacaktır."); // Seri port devre dışı olduğu için bu satır yazdırılmayacaktır. Serial.begin(9600); // tekrar seri portu devreye al delay(1000); }
find ()
Find fonksiyonu ile Serial Port üzerinden gönderilen değer içerisinde arama işleme yapılır. Eğer aranan değer gönderilen değer içerisinde varsa True, yoksa False değeri döndürür. find örneği
void setup() { Serial.begin(9600); // Seri Portu başlat } void loop() { while (Serial.available()) { // okumak için veri varmı. if (Serial.find("arduino")) { // girilen değer içerisinde arduino var mı ? Serial.println("Sensorler"); } else { Serial.println("Motorlar"); } } }
parseFloat () ve parseInt ()
parseFloat() ve parseInt() fonksiyonları Seri Porta gönderilen veri dizisi içerisindeki ondalıklı ve tam sayıları almamızı sağlar. Bu işlemi yaparken gelen veri dizisinde değişikliklerde oluşur. Bunu aşağıdaki örneğinizde görebilirsiniz.
parseFloat ve parseInt örneği
int tamSayi = 0; float ondalikliSayi = 0; void setup() { Serial.begin(9600); // Seri Portu başlat } void loop() { if (Serial.available()) { // okumak için veri varmı. tamSayi = Serial.parseInt(); // veri dizisindeki tam sayıları oku Serial.println(tamSayi); ondalikliSayi = Serial.parseFloat(); // veri dizisindeki ondalikli sayıları oku Serial.println(ondalikliSayi); } }
print () ve println ()
Her iki fonksiyonda seri haberleşmede gönderilen parametreleri ASCII‘ye uygun olarak yazdırma işlemi yapar. Diğer programlama dillerinden de alışık olduğumuz şekilde print fonksiyonu yazma işlemini gerçekleştirdikten sonra imleci yazma işleminin bittiği noktada bırakırken, println fonksiyonu yazma işlemi bittikten sonra imleci bir alt satırın başına getirir ve daha sonraki yazmaların bir alt satırdan olmasını sağlar.
Kullanım şekilleri:
Serial.print(val)
Serial.print(val, format)
Serial.println(val)
Serial.println(val, format)
Özellikleri;
Parametre olarak aldıkları veriyi seri monitor ekranına yazarlar.
C gibi dillerde kullanılan kaçış karakterleri ( \t, \n vs. ) bu fonksiyonlar içinde geçerlidir.
Ondalıklı sayılar yazdırıldığın da varsayılan hassasiyet olan virgülden sonraki 2 basamağı yazdırılır.
İkinci parametre olarak alınan format değişkeni ile yazdırma hassasiyeti veya yazdırılan sayının hangi taban aritmetiğinde olması istendiği ayarlanabilir.
Serial.println(1.23456) şekildeki kullanımda ekrana onluk tabanda 1.23 yazdırılır.
Serial.println(1.23456, 3) şeklindeki bir kullanımda ekrana 1.234 çıktısını yani, virgülden sonra üç basamağı yazdırılır. Daha farklı hassasiyetler için örnekteki 3 rakamını değiştirebiliriz.
Serial.println(123, format) kullanımında format değişkeni değer olarak BIN ( ikilik ), OCT ( sekizlik ), DEC ( ondalık), HEX ( on altılık ) değerlerini alır ve bu aldığı değerlere uygun tabanda sayı formatlandırılarak yazdırılır.
print () ve println () örnekleri
Farklı tabanlarda tam sayı yazdırma örneği
void setup() { Serial.begin(9600); // Seri Haberleşme Portunu hızını 9600 olarak ayarla } void loop() { // başlıkları yazmak için bu kod bloğu kullanılmıştır. Serial.print("NO FORMAT"); // Ekrana no format yazdır Serial.print("\t"); // bir tab kadar boşluk bırak. Serial.print("DEC\t"); // Ekrana DEC yazdır ve bir tab kadar boşluk bırak. Gerek No format taki gibi gerekse bu satırdaki gibi \t ekleyebiliriz. Serial.print("HEX\t"); Serial.print("OCT\t"); Serial.print("BIN\n"); // Ekrana BIN yazdır ve bir alt satıra in for(int x=0; x< 64; x++){ // 0'dan 64'e kadar olan tam sayıları alıp yazdırmak için bu döngü kullanılmıştır. Serial.print(x); // X değerini formatsız bir şekilde yazdırma. Varsayılan olarak DEC (onluk) tabanda yazdırılacaktır. Serial.print("\t\t"); // prints a tab Serial.print(x, DEC); // X değerini ONLUK tabanda yazdır Serial.print("\t"); // prints a tab Serial.print(x, HEX); // X değerini ON ALTILIK tabanda yazdır Serial.print("\t"); // prints a tab Serial.print(x, OCT); // X değerini SEKİZLİK tabanda yazdır Serial.print("\t"); // prints a tab Serial.println(x, BIN); // X değerini İKİLİK tabanda yazdır ve bir alt satıra in. delay(200); // 200 ms bekle. } Serial.println(); // parametresiz olarak kullanıldığında yalnızca imleci bir alt satıra indirir. }
Farklı hassasiyetlerde ondalıklı sayı yazdırma örneği
float y = 1.23456; // formatlamak için kullanacağımız değişken.
void setup() { Serial.begin(9600); // } void loop() { Serial.print("Ondalikli sayi\t"); // Ekrana ondalıklı sayı yaz ve bir tab boşluk bırak. Serial.print("Basamak Hassasiyeti\t"); Serial.println("Formatli Sayi"); // Ekrana formatlı sayı yaz ve bir alt satıra in. for (int i = 0; i < 7; i++) { Serial.print(y); // Varsayılan yazdırma şekli ile y değişkenini yazdır. Serial.print("\t\t"); // Daha düzgün bir görünüm için bir miktar boşluk bırak. Serial.print(i); // Kaç basamak hassasiyetinde olacağını yazdır. Serial.print("\t\t\t"); Serial.println(y, i); // y değişkenini i hassasiyetinde yadır ve bir alt satıra in. delay(1000); } Serial.println(); }
read ()
Seri Porttan gelen veriyi ilk byte ile başlayarak sırayla okuma işlemini gerçekleştirir ve okuduğu her değerin integer karşılığını döndürür. Bu integer değer tip dönüşümü yapılarak istenilen formda kullanılabilir. Eğer okunacak veri yoksa -1 değerini döndürür.
int alinan = 0; // alınacak degeri saklamak için kullanılacak değişken void setup() { Serial.begin(9600); // Seri Portumuzu 9600 baud olarak ayarlıyoruz. } void loop() { if (Serial.available()) { // Serial Porta girdi değerinin olup olmadığını kontrol et // eğer girdi varsa oku ve yazdır. alinan = Serial.read(); // Serial Porttan değer okuma Serial.print("Alinan Deger: "); Serial.print(alinan); // integer olarak alınan değeri yazdırma Serial.print(" - Char Olarak Alinan Deger: "); Serial.println((char)alinan); // char'a dönüştürerek alınan değeri yazdırma. } }
readBytes()
readBytes fonksiyonu Serial Porttan gelen veriyi istenilen byte adedinde okuyarak char veya byte tipinde bir diziye yazma işlemini gerçekleştirir. Bu işlemi gerçekleştirirken geriye kaç byte lık işlem yaptığını integer tipinde döndürür.
Kullanım şekilleri:
Serial.readBytes(buffer, length)
buffer : char veya byte tipinde bir dizi
length : integer tipinde kaç byte lık okuma yapılacağı
int byteSayisi = 0; char dizi[10]; // 10 boyutlu bir dizi oluştur. void setup() { Serial.begin(9600); // Seri Portu başlat. } void loop() { if (Serial.available() > 0) { // Serial Porta girdi değerinin olup olmadığını kontrol et byteSayisi = Serial.readBytes(dizi,4); // 4 byte okuma yap ve diziye yaz. Ayrıca gelen verinin kaç byte inin işlendiğini sakla. Serial.print("Dizi : "); Serial.println(dizi); // üzerine yazılmış olan diziyi ekrana yaz. Serial.println(byteSayisi); // kaç byte lık işlem yapıldığını yaz. } }
readBytesUntil ()
Bu fonksiyon readBytes fonksiyonundan farklı olarak bir char parametre daha alır ve bu aldığı char parametre gelen veri dizisi içerisinde varsa okuma işlemini sonlandırır.
Kullanım şekilleri:
Serial.readBytesUntil(character,buffer, length)
character : aramak için char tipinde karakter
buffer : char veya byte tipinde bir dizi
length : integer tipinde kaç byte lık okuma yapılacağı
int byteSayisi = 0; char dizi[15]; // 15 boyutlu bir dizi oluştur. void setup() { Serial.begin(9600); // Seri Portu başlat. } void loop() { if (Serial.available() > 0) { // Serial Porta girdi değerinin olup olmadığını kontrol et byteSayisi = Serial.readBytesUntil('.', dizi, 15); // yukarıdaki satırda 15 byte okuma yap ve diziye yazdırma, gelen verinin kaç byte inin işlendiğini saklama // ve . (nokta) işareti görülünce kaydı bitirma işleme yapılır. Serial.print("Dizi : "); Serial.println(dizi); // üzerine yazılmış olan diziyi ekrana yaz. Serial.println(byteSayisi); // kaç byte lık işlem yapıldığını yaz. for (int i = 0; i < 15; i++) { // diziyi tekrar yazmaya hazır olması için sıfırlama dizi[i] = NULL; } } }
readString ()
Bu fonksiyon Serial Porta gelen girdi dizisini satır sonuna kadar okuyarak okunan değeri String formunda geri döndürür.
String okunan; // girilecek parametreyi saklamak için String değişken void setup() { Serial.begin(9600); // Seri Portu başlat. } void loop() { if (Serial.available() > 0) { // Serial Porta girdi değerinin olup olmadığını kontrol et okunan = Serial.readString(); // Serial Porttaki girdi değerini oku ve string e ata. Serial.println(okunan); // okunan değeri ekrana yazdır. } }
readStringUntil ()
Bu fonksiyon readString fonksiyonundan farklı olarak bir char parametre daha alır ve bu aldığı char parametre gelen veri dizisi içerisinde varsa okuma işlemini sonlandırır.
String okunan; // girilecek parametreyi saklamak için String değişken void setup() { Serial.begin(9600); // Seri Portu başlat. } void loop() { if (Serial.available() > 0) { // Serial Porta girdi değerinin olup olmadığını kontrol et okunan = Serial.readStringUntil('.'); // yukarıdaki satırda Serial Porttaki girdi değerini okunur ardından string e atanır // ve eğer . (nokta) karakterine rastlanırsa okumayı sonlandır.s Serial.println(okunan); // okunan değeri ekrana yazdır. } }
setTimeout ()
Bu fonksiyon ile Seri Porttan gelecek olan verinin maksimum ne kadar bekleneceği mili saniye cinsinden ayarlanır. readBytes, readBytesUntil, parseFloat veya parseInt gibi fonksiyonların varsayılan bekleme süreleri 1000 ms’dir.
void setup() { Serial.begin(9600); Serial.setTimeout(10000); // bekleme zamanını 10.000 ms (10 sn) olarak ayarla. } void loop() { Serial.println("Bekleme zamani ornegi icin giris bekleniyor."); int alinan = Serial.parseInt(); // tam sayı alma. Serial.print("Alınan deger : "); Serial.println(alinan); }
Not: Bu örnek kod çalıştırıldığında parseInt fonksiyonuna sıra geldiğinde 10 sn beklendiği görülecektir.
write ()
Bu fonksiyon print fonksiyonuna benzer bir işlev görür. Tek byte büyüklüğündeki değerleri yazdırmakta, String değerler ve char veya byte tipinde dizileri yazdırmakta kullanılır. Alacağı ikinci bir parametre ile de yazdırılan String veya dizinin kaç elemanının yazdırılacağı ayarlanabilir. Ayrıca write fonksiyonu geri dönüş değeri olarak üzerinde işlem yapılan byte sayısı döndürür.
write örneği
char dizi[] = {'.','c','o','m'}; // yazdırmak üzere hazırladığımız char tipindeki dizi void setup() { Serial.begin(9600); // Seri Portu başlat. } void loop() { Serial.write(77); // 77 = M yazdır. Serial.write("Arduino Dersleri",9); // String'in ilk dokuz karakterini yazdır. int byteSayisi = Serial.write(dizi); // diziyi yazdır ve kaç byte lık işlem yapıldığını sakla Serial.print("\ndizi'den okunan byte sayisi: "); Serial.println(byteSayisi); // kaç byte lık işlem yapıldığını yazdır. delay(10000); }