Serial Port tüm Arduino kartlarda en az bir adet
mevcuttur ve Arduino kartımız ile bilgisayar veya diğer cihazların
haberleşmesinde kullanılır. Arduino UNO kartında bir adet Serial Port vardır.
Birden fazla Serial Port kullanmak isteyen kullanıcıların Arduino MEGA veya
Arduino DUE gibi toplamda 4 adet Serial Porta sahip olan kartları tercih etmesi
gerekmektedir.
Arduino UNO kartında dijital 0 (RX) ve dijital 1
(TX) pinleri Serial Port’u için ayrılmıştır. PC’nin seri portu ile
haberleşmek için bu iki pini kullanabildiğimiz gibi, Arduino kartımız ile
bilgisayarımız arasındaki USB bağlantısını da kullanarak haberleşme
sağlayabiliriz. Arduino USB üzerinden iletişim için bu pinleri kullanır. Ayrıca
bu pinleri dijital giriş/çıkış için de kullanabilmemiz için dışarıya
çıkarılmıştır. Arduino’ya program yüklerken yada seri
monitör kullanırken bu pinlerin boş olması gerekir. Yoksa usb iletişiminde yada
bu pinlere bağlanan komponentlerin çalışmasında sorunlar çıkabilir.
Arduino kart üzerinde bulunan iki adet uyarıcı ledin yardımı ile çalışma esnasında Serial Port’un o anki çalışma durumunu takip edebiliriz.
ÖNEMLİ: Arduino TX/RX pinlerindeki seri
iletişim TTL mantık seviyelerini kullanır (karta bağlı olarak 5V veya 3.3V). Bu
pinleri doğrudan bir RS232 seri portuna bağlamayın. RS232: -12V(1), +12V(0) şeklinde çalışır ve Arduino
kartına zarar verebilir.
Arduino Seri Port Komutları
Arduino
IDE’sindeki seri port ekranı ile Arduino’nun PC’ye bağlandığı USB portundan
Arduino ile iletişime geçebilir, ona klavyeden
seri olarak data gönderebilir ve ondan seri olarak data alabiliriz.
a. Serial.begin();
Bu fonksiyon
Arduino UNO için 0 ve 1 numaralı pinlerinde bulunan fiziksel seri haberleşme
özelliğini aktif eder. Bu fonksiyonumuz “seri haberleşme hızı, iletilecek
bilginin bit sayısı, parity (eşlik) biti ve stop biti” olmak üzere 4 adet
parametre alır.
Serial.begin(baudRate,
yapılandırma);
baudRate: Bu özellik olmazsa
olmaz olan seri portun saniyede göndereceği ve alacağı bit sayısını belirler.
Seri portun haberleşeceği cihaz ile aynı olmak zorundadır. 300, 600, 1200,
2400, 4800, 9600, 19200, 38400, 57600, 115200 değerleri alabilir.
yapılandırma: SERIAL_XYZ
X = Data
Bit değeridir. Bu özellik seri porttan gönderilecek her bir verinin kaç bitten
oluşacağını belirler. 5 ile 8 bit arasında bir değer alabilir.
Y = Parity
yani eşlik biti değeridir. Parity biti gönderilen 8 bitlik veri içindeki
1’lerin toplamının çift yada tek olduğunu belirtir. Alabileceği değerler; N,O
ve E değerleridir.
·
“N” değeri
“None” yani Parity biti gönderilmeyecek demektir.
·
“O” değeri
“One” yani tek sayı demektir. Parity biti “1” olur.
·
“E” değeri
“Even” yani çift sayı demektir. Parity biti “0” olur.
Alıcı gelen veriyi kontrol eder. Gelen verideki
bitlerin toplamına ve parity değerine bakar. İkisi birbiriyle uyuyorsa doğru
olarak kabul eder.
Z = Gönderilecek
verinin sonuna eklenecek olan Stop Biti sayısını temsil eder. 1 ve 2 değerini
alabilir. Aldığı değer kadar gönderilen verinin sonuna stop biti ekler.
Varsayılan değeri “1”dir.
Örnek: Serial.begin(9600, SERIAL_8N1);
Arduino IDE’ye Serial.begin(9600); yazdığımızda yapılandırma otomatik olarak SERIAL_8N1 değerini kullanır.
b. Serial.end();
Seri portu kapatır ve seri port arabelleğindeki
tüm veriler silinir. Seri portu devredışı bırakarak RX ve TX pinlerini dijital
giriş/çıkış olarak kullanılmasına izin verir. Bu fonksiyondan sonra tekrar seri
portu etkinleştirmek için Serial.begin() fonksiyonu kullanılır. Serial.end() fonksiyonu
herhangi bir parametre almaz ve geriye değer döndürmez.
a. Serial.print();
Bu fonksiyon gönderilecek olan verinin ASCII
standartlarında gönderilmesini sağlar. Yani veriyi karşıya direkt karakter
olarak gönderir. Bu fonksiyon ile
gönderilen veriler makina tarafından ekrana basılabilir ve insan tarafından
okunabilir.
İzin verilen format değerleri; BIN (Binary yani 2
tabanlı veri), OCT (Octal yani 8 tabanlı veri), DEC (Decimal yani 10 tabanlı
veri) veya HEX (Hexadecimal yani 16 tabanlı veri) olarak gönderilebilir.
Örneğin;
Serial.print(78, BIN); //
"1001110" gönderir
Serial.print(78, OCT); //
"116" gönderir
Serial.print(78, DEC); //
"78" gönderir
Serial.print(78, HEX); //
"4E" gönderir
Serial.print(1.23456, 0); // "1" gönderir
Serial.print(1.23456, 2); // "1.23" gönderir
Serial.print(1.23456, 4); // "1.2345" gönderir
Serial.print("merhaba\t");
// merhaba yaz bir tab kadar
boşluk bırak
Serial.print("merhaba\n"); // merhaba
yaz bir alt satıra in
b. Serial.println();
Serial.println() fonksiyonu Serial.print() fonksiyonu ile
tamamen aynı işlemi yapar, ancak bu fonksiyon gönderdiği her verinin sonuna
Satır Başı (ASCII 13 veya ‘\r’) karakteri ve ardından Yeni Satır(ASCII 10 veya
“\n”) karakterini ekler. Böylelikle gönderilen her veride alıcı cihaz alt
satırdan devam eder.
Seri Porttan
Veri Alma İşlemi
PC’den veri bitleri gönderilmeye başlandığında
Arduino’daki UART, 8 bitin her birini 1 bayta toplar ve bu baytları seri port
ara belleğine kaydeder. Seri port ara belleği en çok 64 bayt depo edebilir. Serial.read() komutu verileri
ara bellekten bayt bayt okuyarak istediğimiz bir değişkene atar. Okunan bayt
silinir.
Burada dikkat edilmesi gereken bir nokta vardır.
PC’den veri gönderildiğinde çoğu zaman iletimin sonuna karakter eklenir. Yani seri arabelleğine 1 baytlık karakter
fazladan eklenir. Bu karakter satır sonu(\n) gibi bir şeydir. Bunun sebebi veri alırken
programımızın iletimin ne zaman biteceğini bilmesi içindir. Hatta bu karakter 2
baytlık da olabilir.
Arduino seri monitör üzerinden veri gönderiyorsak
sağ altta satır sonu karakteri (‘\n’) ekleme seçeneklerini görebiliriz.
Aşağıdaki resimdeki gibi:
“Satır sonu yok” u seçersek sadece istediğimiz
karakterleri göndeririz. Satır sonu karakteri
(‘\n’)
gitmez. Diğer seçeneklerden birini seçersek gönderdiğimiz her 1 bayt
karakterin arkasına 1 bayt da satır sonu karakteri ekler.
Yaptığımız uygulamanın birinde “satır sonu yok” u
seçtik. Çünkü diğer türlü, gönderdiğimiz karakterlerden sonra seri port ekranında
satır başı yapıyor ve uygulamanın hatalı çalışmasına neden oluyordu.
Gönderdiğimiz verinin bittiğini Serial.available()
komutu ile tespit etmemize rağmen bu satır
sonu karakteri (‘\n’) verinin arkasına eklendiği için, kullandığımız
şartlı ifadenin yanlış çalışmasına sebep oluyordu.
“satır sonu karakteri” seçili olsa dahi, istersek
komutlarda yapacağımız bir değişiklik ile bu satır sonu karakterini devre dışı
bırakabiliriz. Bunun için if ile bir
şart koyarız. Ara bellekteki bilgi istediğimiz bilgi mi yoksa satır sonu karakteri
mi onu tespit edebiliriz. Diğer uygulama
bu şekilde yapıldı. Aşağıdaki gibi:
NOT: Seri
porttan alınan-gönderilen veriler char
türündedir. Biz veriyi okurken int türündeki bir değişkene atarsak karakterin ascii’deki
decimal karşılığını görürüz. Örneğin klavyeden “m” harfini gönderdik. Bu veriyi
char türünde değil de int
türündeki bir değişkene atarsak verinin ascii’deki karşılığı olan decimal 109
sayısını görürüz.
a. Serial.available();
Serial.available() fonksiyonu
seri port ara belleğindeki(buffer) byte sayısını verir. Biz seri porta gelen
veriyi almadan önce bu veriler seri port arabelleğine kayıt edilir. Seri port
arabelleği 64 byte değerindeki veriyi saklayabilecek kapasitededir. Biz Serial.available() fonksiyonu
ile ara bellekteki verinin kaç byte’dan oluştuğunu öğrenebiliriz. Fonksiyon,
herhangi bir parametre almaz ve gelen verinin byte sayısını integer cinsinden değer olarak bize
verir.
Bu fonksiyonu seri porta veri gelip gelmediğini
anlamak için de kullanabiliriz.
b. Serial.read();
Serial.read() fonksiyonu,
seri porta gelen verileri okumak için kullanılır. Seri Porttan gelen veriyi ilk
byte’tan başlayarak sırayla byte byte okuma işlemini gerçekleştirir. Okuduğu
her değerin integer karşılığını
döndürür. Okunan bu verileri bir değişkene atayarak kullanabilirsiniz. Eğer
okunacak veri yoksa -1 değerini döndürür. Serial.read() ile veri okuduğumuzda okuduğumuz alandaki veri
silinir.
c. Serial.readBytes();
Seri porttan gelen veriyi byte byte istenilen byte
adedinde okuyarak char veya byte tipinde bir diziye yazma işlemini
gerçekleştirir. İki adet parametre alır. Birinci parametre verilerin
aktarılacağı dizi, ikinci parametre ise seri porttan kaç byte veri okunacağını
bildirir.
Serial.readBytes(verilerin_aktarılacağı_dizi,okunacak_byte_sayısı);
Örneğin; Serial.readBytes() komutu ile seri portun ara belleğinden 6 baytlık
veri okumak istiyoruz ama ara bellekte 12 bayt veri varsa okuma işlemi
aşağıdaki gibi olur:
İlk 6 baytı okuduktan sonra işlemi bitirmeyip okumaya
devam edersek okuma işlemi yukarıdaki gibi olur.
a. Serial.readBytesUntil();
Seri porttan gelen verileri belli bir karaktere
kadar okumaya yarar. Belirlenen karaktere ulaşıldığında okuma işlemi sona erer
ve belirtilen karakter arabellekten temizlenir.
Serial.readBytesUntil(karakter, dizi, byte_sayisi);
karakter :
Hangi karakter gelince okuma sona ersin. Veri türü char.
dizi : Okunan verinin aktarılacağı dizi. Veri türü byte ya da char.
bayt_sayisi :
Okunacak byte sayısı. Veri türü int.
b. Serial.readString();
Bu fonksiyon seri porta gelen girdi dizisini satır
sonuna kadar okuyarak okunan değeri String(metin)
formunda geri döndürür. Okunan bu verileri bir değişkene atayarak
kullanabilirsiniz.
c. Serial.readStringUntil()
Bu fonksiyonumuz seri porttan gelen verileri
belirlenen karaktere kadar okur. Bu fonksiyon readString fonksiyonundan farklı olarak bir char parametre daha
alır. Veri dizisinin okunduğu esnada bu char parametre ile karşılaşıldığında
okuma işlemi sonlandırılır. Okunan bu verileri bir değişkene atayarak
kullanabilirsiniz.
Serial.readStringUntil(‘karakter’);
d. Serial.write();
Bu fonksiyon print()
fonksiyonuna benzer bir işlev görür. 1 byte büyüklüğündeki char veya byte türündeki
veriyi yada bu türdeki dizileri göndermekte kullanılır. Dizinin kaç elemanının gönderileceği
ayarlanabilir. Ayrıca write() fonksiyonu
geri dönüş değeri olarak üzerinde işlem yapılan byte sayısı döndürür.
NOT: Bir sayının rakamlarını temsil eden karakterleri
göndermek için bunun yerine print() komutunu
kullanın.
Serial.write(77); à
77 decimal sayısının char karşılığı olan M harfini gönderir.
Serial.write(dizi); àdizi’yi
gönderir.
Serial.write(dizi, 3); àdizi’nin
ilk 3 elemanını(3 bayt) gönderir.
bayt_sayisi = Serial.write(dizi); àdizi’yi
gönderir ve gönderdiği eleman sayısını(kaç baytlık işlem yapıldığını) değişkene
atar.
a. Serial.availableForWrite();
Seri port ile veri gönderme işlemini engellemeden,
seri port arabelleğindeki veri yazılabilecek kaç bayt(karakter)’lık alan
olduğunu bildirir.
alan = Serial.availableForWrite();
b. Serial.find();
Arduino seri portuna gelen veri içinde belirlenen
karakteri arar. Char türü parametre
alır. Eğer karakteri bulursa TRUE,
bulamazsa FALSE sonucu döndürür. Geriye
dönüş değeri bool türündendir.
yazi= Serial.find(‘G’); yazi= Serial.find(“MERHABA”);
c. Serial.flush();
Bu fonksiyon gönderilen seri veri iletiminin
tamamlanmasını beklemek için kullanılır. Herhangi bir parametre almaz ve geriye
değer döndürmez.
Bu komut kullanıldığında tüm verinin seri port
üzerinden gönderildiğinden emin olunur ve seri veri akışını temizleyerek iletim
arabelleğini(buffer) bir sonraki veriyi göndermeye hazır hale getirir. Yani
seri port üzerinden gönderilen verilerin temizlenmesini de sağlamış olur.
Serial.flush(), kullanıcı programında hemen devam etmek yerine, verilerin
gönderilmesini beklemenin bir yoludur. Yani Serial.flush()'ı çağırdıktan sonra tüm verilerin gönderildiğinden
ve iletim arabelleğinin(buffer) boş olduğundan emin olabilirsiniz.
Serial.flush(), birçok kişinin düşündüğü gibi "gelen"
tamponunu boşaltmaz. İletim tamponunu boşaltılırken programınızı duraklatır.
Serial.print()'i çalıştırdığınızda, bu fonksiyon nerdeyse anında
geri döner. Dize iletilene kadar beklemek yerine, print() dize için bir tampon ayarlar ve ardından kesmeler yoluyla
her seferinde bir karakter iletir. Arka planda iletim gerçekleşirken program çalışmaya
devam eder. Kodunuzun, bir seri dizenin gönderiminin bitirilmesini beklemesini
istiyorsanız, Serial.flush()
kullanmanız gerekir. Ancak; Serial.print()'lerle
kullandığımız kritik zamanlamanız varsa, zamanlamanızın değişebileceğini
aklınızda bulundurmanız gerekir.
a. serialEvent()
Bu bir fonksiyondur. Seri porta veri geldiğinde
otomatik olarak bu fonksiyon çalışır. Bir nevi seri port kesmesi gibi davranır.
Bu işlemi loop() döngüsünden bağımsız olarak yapar. Yani loop() döngüsünde kodlarımız çalışırken, seri porta bir
veri geldiğinde, serialEvent() fonksiyonumuz
çalışır.
serialEvent() fonksiyonu her Arduino kartında çalışmaz.
Çalıştığı kartlar; UNO R3, Nano, Mega 2560 Rev3 ve
Due’dir. Seri port sayısı birden fazla olan Mega 2560 Rev3 ve Due
kartlarında fonksiyon serialEvent1(),serialEvent2()………
gibi olur.
Bu fonksiyon yerine Serial.available(); komutu da kullanılabilir.
Eğer arabellekte 1 bayt veri varsa veriyi okumak
için yukarıdaki programı kullanabiliriz ama arabellekten 1 bayttan fazla veri
okuyacaksak programı aşağıdaki gibi yazmamız daha uygun olacaktır.
_____________________________________________________________________________________________________________________________________________________