Arduino ile Seri İletişim – 2


Önceki yazımızda Arduino ile seri iletişimin temellerini ve Arduino ile verileri nasıl göndereceğimizi görmüştük. Şimdi de Arduino’ya nasıl veri gönderebileceğimize bakacağız. Bunun için yine Serial Monitor’ü kullanacağız. Ancak Arduino’ya veri göndermek için elimizdeki tek araç bu değil. Bilgisayarımızda USB üzerinden oluşturulan ve ismi COMx şeklindeki seriporta erişebilen bütün programları Arduino’ya veri göndermek için kullanabiliriz. Seri iletişimdeki temel nokta verilerin baytlar serisi halinde gönderilmesidir. Baytlara bölebildiğiniz bütün verileri Arduino’ya rahatlıkla gönderebilirsiniz.

Serial Monitor ile Arduino’ya Veri Gönderme

Serial Monitor ile Arduino arasında veri alışverişi yapmak için Arduino geliştirme ortamından Serial Monitor butonuna basalım:

 Seria Monitor’ün üst bölümünde bir kutucuk ve sağ tarafta da “Send” butonu bulunuyor. Kutucuğa yazdığımız karakterler Send butonuna basıldığında sağ alt köşede seçilmiş olan hız değerinde Arduino’ya gönderilir. Arduino’dan bu verileri okumak için programımızda da aynı hız değerini kullanmalıyız.

 

Serial Monitor’den gönderdiğimiz veriler daha önce de bahsettiğimiz gibi baytlar halinde gönderilir. Yani kutucuğa “ARDUINO” yazdığımızda bunlar her bir karakterin ASCII karşılığı şeklinde gönderilecektir:

A 65
R  82
D  68
U 85
I  73
N 78
O 79

Bir karakterin ASCII tablosunda sayısal bir karşılığı olduğundan daha önce bahsetmiştik. Karakter dizilerinin desimal sayı karşılıklarını görüntülemek için http://easycalculation.com/ascii-hex.php adresindeki aracı kullanabilirsiniz.

Dolayısıyla Arduino’da

Serial.write(65);
Serial.write(‘A’);

komutları aynı işi yapacaktır. Tek fark birisinde karakterin sayısal karşılığını yazarken diğerinde kendisini yazıyoruz.

Seri iletişim yoluyla Arduino’ya gelen verileri okuma

Arduino’ya seri iletişim üzerinden gelen veriler belirli bir kapasitedeki bellekte (128 bayt) saklanır. Buna “tampon bellek” de denilebilir. Program içerisinde  okunana kadar veriler tampon bellekte tutulur. Bu belleğin kapasitesi sınırlı olduğundan veriler belirli bir süre içerisinde okunmazsa yeni gelen veriler eskisinin üzerine yazılabilir.

Belirli bir anda bellekte okunmayı bekleyen verilerin sayısını Serial.Avaliable() fonksiyonu ile öğrenebiliriz:

Serial.Avaliable() fonksiyonunun döndürdüğü değer sıfırdan farklı ise okunmayı bekleyen veriler var demektir.

Gelen verileri Serial.read() ile okuyabiliriz. Serial.read() fonksiyonu tampon bellekte bekleyen verilerden ilk gelmiş olanı bize verir. Yani tampon belleğe ilk gelen veri ilk okunur. Buna “ilk gelen ilk okunur – first in first out – FIFO) bellek” denilir.

Serial.read() fonksiyonu ile her seferinde bir bayt okunur ve bu bayt tampon bellekten silinir.

Şimdi örnek bir programda bu fonksiyonların kullanımını görelim:

int gelenVeri = 0;   // genel veriyi tutacak değişken
char gelenKarakter;
void setup() {
    // Seri haberleşmeyi başlatıyoruz (9600 bps hızında)
    Serial.begin(9600);
}

void loop() {

        // Veri gelmiş mi?
        if (Serial.available() > 0) {
                // gelen veriyi oku
                gelenVeri = Serial.read();
                gelenKarakter = gelenVeri;
                Serial.print("Gelen Veri: ");
                Serial.println(gelenVeri);
                Serial.print("Gelen Karakter: ");
                Serial.println(gelenKarakter);
        }
}

Programımızı Arduino’ya yükleyip ardından Serial Monitor’ü çalıştıralım. Üst bölümdeki kutucuğa “A” harfi yazıp “Send” butonuna tıkladığımızda Arduino bize aşağıdaki verileri yollayacaktır:

gelenVeri değişkeni int, gelenKarakter değişkeni ise char tipindedir. Serial.Print() ve Serial.Println() fonksiyonları kendilerine verilen parametrelerin cinsine göre çıktı üretmektedirler.

Yazıyla ilgili yorumlarını aşağıda yapabilirsiniz. Bir sonraki yazıda Arduino ile Seri haberleşme işlemlerini nasıl yapacağımızı görmeye devam edeceğiz…

Coşkun Taşdemir

Elektronik mühendisi, gömülü sistemler meraklısı, Arduino kitabı yazarı

17 comments

  1. Yalçın dedi ki:

    Meraba.Serial monitörden ne gönderirsem alttaki hatayı veriyor.Windows xp ve arduino leonardo kullanıyorum.Şimdiden yardımlarınız için teşekkür ediyorum.

    java.io.IOException: Input/output error in writeArray
    at gnu.io.RXTXPort.writeArray(Native Method)
    at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1124)
    at processing.app.Serial.write(Serial.java:517)
    at processing.app.Serial.write(Serial.java:540)
    at processing.app.SerialMonitor.send(SerialMonitor.java:200)
    at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
    at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
    at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
    at javax.swing.JTextField.postActionEvent(JTextField.java:705)
    at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
    at java.awt.Component.processEvent(Component.java:6040)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4630)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
    at java.awt.Component.dispatchEventImpl(Component.java:4502)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Window.dispatchEventImpl(Window.java:2475)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    java.io.IOException: Input/output error in writeArray
    at gnu.io.RXTXPort.writeArray(Native Method)
    at gnu.io.RXTXPort$SerialOutputStream.write(RXTXPort.java:1124)
    at processing.app.Serial.write(Serial.java:517)
    at processing.app.Serial.write(Serial.java:540)
    at processing.app.SerialMonitor.send(SerialMonitor.java:200)
    at processing.app.SerialMonitor.access$100(SerialMonitor.java:32)
    at processing.app.SerialMonitor$3.actionPerformed(SerialMonitor.java:89)
    at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
    at javax.swing.JTextField.postActionEvent(JTextField.java:705)
    at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
    at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
    at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
    at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
    at java.awt.Component.processEvent(Component.java:6040)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4630)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
    at java.awt.Component.dispatchEventImpl(Component.java:4502)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Window.dispatchEventImpl(Window.java:2475)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

    • Ahmet Alpat dedi ki:

      Compiler hataları genellikle Arduino’yu tanıtamamak ve IDE problemlerinden kaynaklanır. Arduino driverını doğru kurduğunuza emin olun. Aygıt yöneticisinden kontrol edebilirsiniz.

  2. Yalçın dedi ki:

    Cevabınız için teşekkür ediyorum.Ne yaptıysam olmadı.Windows 7 kurdum artık serial monitör kullanabiliyorum.

  3. hamzaoztas dedi ki:

    merabalar ahmet hocam, konuyla biraz alakasız olacak ama bişey sormak istiyorum bi proje için çift taraflı double servo kullanmama gerekiyor, bana önerecebileceğiniz arduino mega ve motor sürücü ile kullanacabileceğim çift taraflı servo varmı acaba? şimdiden teşekkürler..

    • Coşkun Taşdemir dedi ki:

      Sorularınızı forum bölümümüzde sorarsanız daha hızlı cevap alabilirsiniz. Teşekkürler.

  4. Cem dedi ki:

    Çoşkun hocam kitabınız için çok çok teşekkürler, sevgi vede ilgi ile okuyorum. ufak bir sorunum var yukarıda yazdığınız prog u leonardoma yükledim.

    mesela 1 gönderiyorum

    Gelen Veri: 49
    Gelen Karakter: 1

    veya a gönderiyorum
    Gelen Veri: 97
    Gelen Karakter: a

    sonuçları geliyor lakin 65 gönderiyorum

    Gelen Veri: 54
    Gelen Karakter: 6
    Gelen Veri: 53
    Gelen Karakter: 5

    gibi bir sonuç geliyor yani 6 ve 5 i teker teker algılıyor sizce sorun nedir?

    birde yeri bura değil ama sormak istediğim bir konu daha var. serial ekranını arduino çalıştığında açık halde tutmanın bir yolu yokmu, ufak bi program yazdım i=0, delay 1000ms i++ print i gibi, serial ekranını açabildiğimde i çoktan 5 veya 6 olmuş oluyor, serial açıkken resete basıyorum hiçbirşey göstermiyor, yeniden serial ekranını açıp kapamak gerekiyor, void setup kısmına delay koydum 10 sn hani o beklerken ben ekranı açarım diye onuda yemedi varmı bir çözüm? teşekkürler

  5. murat öztürk dedi ki:

    merhabalar ;
    seri haberleşme yazılarınızı okuyarak denemeler yaptım bunun için öncelikli tesekkür ederiö.
    Ama konu ile ilgili bir soru sormak istedim.
    pc den arduinoya gönderdiğim verileri tampon belleğer yazıyor ben bunları pc den 5 tane farklı değer gönderdikten sonra tek satırda sırası ile aynı anda okuyabılırmıyım.

    örneğin a, b,c ,d,e hrflerini ssırası ile arduinoya göndermek ve sonrasında biilgiyi tek satırda a,b,c,d,e olarak görmeni bir yolu varmı

    şididen tesekkur eerım.

  6. Ömer Koman dedi ki:

    bilginin satır olarak gelmesinin seri iletişimle alakası yok seri iletişim programınız a b c d e bilgilerini yollarken arkasından CRLF yani hex 0x13 0x10 karakterlerini yolluyordur bu kodlar terminalde satırbaşıona dön ve bir satır alta geç demektir. yolladığınız komut println ise mutlaka sonuna bu işaretlerini koymuştur ondan satır satır satır görüyorsunuz print komutunda ise bu bilginin sonuna crlf karakterleri konmaz. okuma programınızda bu karakterleri ayıklarsanız satırlar oluşmaz… Serial.print(‘\r\n’); komutu satır atla komutu yollarken Serial.println(‘abc’); komutu abc den sonra otomatik olarak kendi kendine koyar.

  7. hasan şişik dedi ki:

    benimde bi sorum olacak forum da sıkıntı var sanırım giremedim sorum bu konu ile alakalı oldupundan bu konuya yazacam led küp yaptım sıkıntısız çalışıyor fakat bilgisayardan gireceğim bi yazıyı yazdırabilirmiyim yani arduinoya tek tek yüklemeyecem örnek olarak bilgisayardaki textbox’a hasan yazacam led küpte hasan yazacak yani sıkıntım arduino ile pc yi online bağlamak farklı bi yazılım dili ile olursa onuda söylerseniz sevinirim kolay gelsin.

    • Ömer Koman dedi ki:

      sitede c# yazıları var onlardan faydalanabilirsiniz. bilgisayar seri portundan arduinoya c# ile veri yollayıp veri okuyabilirsiniz.

  8. Yasin Arslan dedi ki:

    Kolay gelsin hocam. Arduino ile Raspberry arasında bilgi göndermek istiyorum string gönderemiyorum yardımcı olur musunuz ?

    • Ömer Koman dedi ki:

      foruma gelin. arduinodan bir stingi serialmonitore gondermeyi deneyin arduino içindeki hello orneğini yapın çıktıyı görürseniz arduino rx pini raspi tx pinine ve arduino tx pini raspi rx pinine ve gnd ler hızlar aynı olduktan sonra haberleştirmemenız için sebep kalmıyor.

  9. selman dedi ki:

    Merhabalar benim iki sorum olacak
    ilki ben sensörden aldığım verileri serial monitörüne nasıl yazdırabilirim
    ikincisi aldığım bu verileri farklı bir dosyada tutabilir miyim
    Şimdiden teşekkürler. . .

  10. Ozan ERBASAN dedi ki:

    Hocam iyi akşamlar. Seri port ekranından örneğin “:)” yazınca tetiklenen bir fonksiyonu herhagi bir pinden “hıgh” gelmesine nasıl koşullarız? Yardımlarınız için şimdiden teşekkürler.

    • Ömer Koman dedi ki:

      once bir pini high yapan kodu yazın, daha sonra seriportu okuyan kodu da ekleyin daha sonra bu kodu forumda paylaşın.

  11. Mustafa Şahin dedi ki:

    Merhabalar,
    Şöyle bir soru sormak istiyorum,Bir gsm modül kullanıyorum ve seri port ile iletişim yapıyor. AT komutları ile haberleşme yapılıyor.örn ben AT komutu gönderdiğimde gsm modül OK olarak cevap veriyor.. fakat ben bu OK okumutu arduino ile okumak istediğimde muhtemelen buffer dan dolayı AT OK olarak hem gönderdiğim komutu hemde cevabı aynı anda alıyorum.data 2 yada daha fazla defa yolladığımda ise buffer dolana kadar yazılan tüm dataları okumuş oluyorum. okuma yaparken buffer i temizleme veya farklı bir varmı acaba ?

    • Ömer Koman dedi ki:

      gms ayarlarınızda local echo kapalı/disable olması lazım bununla ılgılı bır komut vardır modemın datasheetıne ve AT komutlarına bır bakın.
      modemler yolladıgınız komutun yanı sıra kendı cevaplarını da döndürür ve “OK” ile sonlandırır bu gelen karakterleri bir dizide biriktirip dönmesi gereken yada beklediğiniz veriyi buffer ıcınde arayarak işlem yapmanızda fayda var.

E-posta adresiniz gösterilmeyecek. Gerekli alanlar * ile işaretlidir.

*



Sosyal Ağlar