Mock Kavramı ve GoogleMock (gMock) Nedir/Nasıl Kullanılır?

Birim (Unit) testleri yazarken sadece kendi içerisinde statik olarak uygulanan algoritmalarla çalışmayız, hatta çoğu zaman bu şekilde çalışmayız. Onun yerine diğer objelerle sürekli etkileşimde olan, gerçek zamanlı (real time) olarak işlemler gerçekleştiren şekilde tasarımlar yaparız. Benzer sistem tasarımlarının testlerini yazarken de her zaman gerçek objeler üzerinde çalışamayız. İşte tam olarak burada karşımıza kurtarıcı niteliğinde bir kavram çıkıyor, Mocking.

Mock kavramı anlamı itibarı ile taklit objeler oluşturmamıza izin vermektedir. Gerçek zamanlı testlerde karşılaşacağımız objelerin taklit edilen hallerini oluşturarak testimize dahil etmemize yarar. Bu yazıda üzerinde işlem gerçekleştireceğimiz Mock framework‘ü ise GoogleMock (gMock) olacak. Yazı içerisindeki anlatımların bir çoğunu YouTube kanalımda anlattığım GoogleTest video serisi içerisinden de ulaşabilirsiniz (Henüz yayınlanmadı).

Mock objeleri ile diğer diller üzerinde çalışırken sizin için işin bir kısmını otomatikleştiren araçlar olduğunu görebilirsiniz. GoogleMock (gMock) da C++ dili özelinde bu işi yapan bir araç olarak Google tarafından tasarlanmıştır. Kullanılacak olan komponentin arayüz üzerindeki davranışlarını tespit etmek için kullanılırlar.


GoogleMock Nasıl Kullanılır?

Bu konudaki en özenle hazırlanmış ve detaylı kaynak olarak Google‘ın kendi dokümantasyonunu örnek verebiliriz. İlgili linklere “Kaynaklar” kısmında ulaşabilirsiniz.

Bir örnek üzerinden anlatmaya çalışacağım ancak öncesinde bilmemiz gerekenlerden kısaca bahsetmek istiyorum. Mock nesneleri içerisinde MOCK_METHOD fonksiyonu ile tanımlamalar yapacağız. Fonksiyonun aldığı parametreler:

  • MOCK_METHOD(void, FonksiyonAdi_1, (), (override));
  • MOCK_METHOD(void, FonksiyonAdi_2, (int parameter_1, int param_2), (override));
  • MOCK_METHOD(int, FonksiyonAdi_3, (), (const, override));

Böyle bir yazımda şunu ifade etmektedir; ilk parametre sizin taklit objeniz üzerinde test etmek için oluşturduğunuz fonksiyonunuzun geri dönüt tipi, ikinci parametre fonksiyon adınız, 3. parametre eğer fonksiyonumuz içerisine bir parametre gönderiyorsak o parametrelerin verilmesi gerekiyor, eğer girilmiyor ise boş gönderilebilir. 4. parametrede ise fonksiyonunuz sabit metot ile kullanılıyorsa belirtilmesi gerekir. Eski versiyon kullanımlarda MOCK_METHOD yerine tercih edilen bir diğer kullanım daha vardır:

  • MOCK_METHOD0(FonksiyonAdi_1)
  • MOCK_METHOD1(FonksiyonAdi_2, void(int parameter_1)) // sadece bir parametre aldığı zaman kullanılır
  • MOCK_METHOD2(FonksiyonAdi_2, void(int parameter_1, int parameter_2)) // sadece iki parametre aldığı zaman kullanılır
  • MOCK_CONST_METHOD1(FonksiyonAdi_2, void(int parameter_1)) // const metodu içerdiği zaman kullanılır

5 parametre alan bir fonksiyon için MOCK_METHOD5 makrosu kullanılmalıydı yani kaç parametre varsa sondaki sayı onunla değişmeliydi ancak eğer 10+ parametre alan bir fonksiyonumuz varsa yalnızca MOCK_METHOD10 makrosu kullanılırdı. Yazının ilerleyen bölümlerinde yeni makroyu kullanacağım.

Mock kullanımı esnasında karşımıza ON_CALL ve EXPECT_CALL makroları çıkıyor. ON_CALL makrosu bir testin kaç kez yapıldığı sizin için önemli değilse kullanabileceğiniz bir makro ancak prototip ve kullanım itibari ile EXPECT_CALL ile aynı yapıya sahiptir, EXCEPT_CALL’dan farklı olarak sadece With() ve WillByDefault() fonksiyonları ile birlikte kullanılabilir.

EXPECT_CALL tanımlaması kullanacağımız mock testlerinin vazgeçilmezidir. Ve:

  • With(multi-argument-matchers)
  • Times(cardinality)
  • InSequence(sequences)
  • After(expectations)
  • WillOnce(action)
  • WillRepeatedly(action)
  • RetiresOnSaturation();

fonksiyonları ile birlikte kullanılır. Tanımlamasını yaptığımız fonksiyon çağırıldığında nasıl tepki vereceğini belirtmemizi ister. Yani aşağıdaki gibi bir kullanım yaptığımız zaman;

EXPECT_CALL(obje_adi, getValueFromObject())
    .Times(10)
    .WillOnce(Return(130))
    .WillOnce(Return(140))
    .WillOnce(Return(150))
    .WillRepeatedly(Return(200));

getValueFromObject() fonksyionunu 10 kez çağıracak, ilk çağırmada 130, ikincisinde 130, üçüncüsünde 150 ve sonrasında her seferinde 200 değerini döndürmesini bekliyoruz. Ana hatları ile kullanılacak olan fonksiyonların ne yaptığına bakacak olursak;

  • With(): içerisine girilecek parametre fonksiyonu da yapılacak işleme dahil eder
  • Times(): çalışması beklenen fonksiyonun kaç kez çalıştırılacağını belirtir
  • InSequence(): belirtilen çağrıların istediğiniz sıraya göre yapılmasını istiyorsanız bir sekans oluşturup ardından fonksiyon içerisinde belirtmeniz gerekmektedir
  • After(): çalışma sonrasında beklenen çıktı için kullanılır
  • WillOnce(): 1 kez çalışması sonucunda ortaya çıkacak çıktıyı belirtir
  • WillRepeatedly(): sürekli çalışması sonucunda ortaya çıkacak çıktıyı belirtir
  • RetiresOnSaturation(): istenilen çıktı oluşmadı ancak fonksiyon çalışabileceği en maksimum noktaya kadar çalıştıysa – saturasyon noktası – fonksiyonu sonlandırır

Burada yazılanlar GoogleMock sisteminin ana yapısını oluştursa da bir miktar havada kaldığının farkındayım. Onun için bu özelliklerin birkaç tanesini bir örnek üzerinde kullanarak daha rahat anlamanızı sağlamaya çalışacağım.

Örnek üzerinde GoogleMock

Aşağıda yer alan örnekte basit bir UserInterface sınıfı oluşturarak onun üzerindeki get/set fonksiyonlarını test edecek bir taklit sınıfı oluşturduk. Bu sayede bir arayüze ihtiyac duymadan otomatik olarak testlerimizi gerçekleştirmiş olduk.

Kodlara bakacak olursak ilk olarak test edilmesini istediğimiz sınıfımızı oluşturduk, daha sonra da bu sınıftan türemiş bir mock sınıfı oluşturduk. Ardından get/set fonksiyonlarımızın nasıl çalıştığını görmek için bir DataReminder sınıfı oluşturduk ve bunlara bağlı testlerimizi yazmaya başladık.

EXPECT_CALL içerisinde çağırdığımız fonksiyonlarımız sayesinde DataReminder içerisinde tutulmasını beklediğimiz veriyi oluşturmuş olduk. Son olarak da kontrollerimizi yaparak testin başarıyla tamamlandığını görmüş olduk.

Kaynaklar

https://github.com/google/googletest/blob/master/googlemock/docs/for_dummies.md

https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md

http://donsoft.io/gmock-presentation

Richard Wells – Test-Driven Development in C++/ https://www.linkedin.com/learning/test-driven-development-in-c-plus-plus/add-items-add-item-prices-and-calculate-the-current-total

Kapak Görseli: C++ Unit Testing: Google Test and Google Mock / Udemy – https://www.udemy.com/course/cplusplus-unit-testing-google-test-and-google-mock/

Yazılımda test de neymiş?

Yazılımda test kavramı sadece kelimelerle aşina olduğum bir durumdu ancak daha öncesinde hiç üzerine araştırma yapmamış, hiç bir yerde kullanma ihtiyacı hissetmemiştim – ne salakmışım. Bir sistemi kafanda kurguluyorsun, kağıt üzerinde adım adım her şey çalıştırıyorsun, oturup kodunu yazıyorsun ama sonra canlıya çıkınca bir bakıyorsun patır patır dökülüyor.

Bunun hepimizin öncesinde karşılaştığı bir problem olduğunu düşünüyorum. Kimse yoktur ki “Benim yazdığım kod tek seferde babalar gibi çalışır, kafamda oluşturduğum yapı Nikola Tesla’nın yansılarında oluşturduğu gibi kusursuz çalışır halde olur” diyebilsin. İşte bu problemleri, kodu yazdıktan sonra debug etme süresini, oluşabilecek ekstra senaryoları ve projenin ilerleyen süreçlerinde yapılacak ekleme çıkartmaların yazdığınız koda etkisini görebilmek için test yazmak çok büyük önem arz ediyor. Hele bir de gömülü sistemler gibi yazdığınız kodun çıktılarını görsel olarak alamayabileceğiniz bir alanda çalışıyorsanız bu debug süreci zaten alıyor başını gidiyor.

Yazılım testini gömülü sistemlerde nasıl kullanabiliriz sorusuna cevap aramaya başladığım dönemde bir yazılımın geliştirme süreçleri üzerine de bilgiler edindim. Çünkü normal bir yazılımı test etmek için sadece test methodları yeterli olabilirdi, ancak burada bahsettiğimiz konuda işin içerisine dahil olan bambaşka bir şey daha var: Donanım. Gömülü yazılımlar donanım üzerine koşan yazılımlardır, yani yazdığın sistemin fonksiyonel tarafını soyutlayabilirsiniz, bunun testlerini yapabilirsiniz ancak işin içerisine donanım üzerindeki fonksiyonlar da girince biraz tuhaflaşıyor gibi geliyor insana. Ancak bu konu üzerine de çalışmalar yapılmış tabii ki, bkz: Mock, Stubs, Fakes. James W. Grenning’in “Test Driven Development for Embedded C (Pragmatic Programmers)” kitabını okumanızı şiddetle öneriyorum. Zaten benim de bu işin ucundan tutmama vesile olan kitaptır kendisi. Bu öneri için Burak Kirazlı‘ya teşekkür ederim.

Yaklaşık 3-4 yıldır C dili ile projeler geliştirmeye çalışıyorum. 3 ay kadar denilebilecek bir sürede test yazılımları üzerine çalışmaya başladım ve daha önceden oluşturmuş olduğum basit algoritmaları ve bazı veri yapıları kütüphanelerimi testlerini yazarak yeniden oluşturmaya başladım. Bu süreçte o kullandığım kütüphanelerde yaptığım hataları, eksikleri görme fırsatım oldu. Bana kazandırdığı bakış açısı sayesinde olayı çoklu bir şekilde bakabilmeyi öğrendim diyebilirim. Yavaş yavaş da donanım üzerinde çalışan kısımların testleri nasıl yapılır onlar üzerine kafa yormaya başlıyorum. Ve bu öğrenme sürecimin sonunda ortaya çıkan çıktıları YouTube üzerinde Google Test özelinde anlatmaya çalışıyorum. Bahsettiğim konuların şu an için Unit Test – Birim Testi kapsamında olduğunu da belirtmek istiyorum. Umarım ilerleyen dönemlerde diğer test kavramlarına (Integration Test, System Test, Performance Test vb.) değinme fırsatı bulabilirim.

Bu kavramlarla tanıştığım sırada Nordic Semiconductor firmasının “Senior Software Test Engineer” ilanını görüp “Olmaz ya, yine de şans bu” diyerek başvurumu tamamladım ve bir hafta sonrasında Test Takım Lideri ile 1 saat süren bir görüntülü görüşme yaptık ve sonucunda bir test ödevi verdiler. İşte bu ödevi yapabilme dürtüsüyle giriştiğim araştırmalar sonucunda yaptığım bir şeylerin yanlış olduğunu, bu tekniğin çok daha sistematik bir kod yazmak, dokümantasyon oluşturmak için faydalı olduğunun farkına vardım. Beni bu deneyime iten tecrübe bu buldu, eğer sizi bir şekilde bu yazımla daha geniş bir bakış açısına tetikleyebildiysem ne mutlu bana. Tabii deneyimleyip yararlı veya yararsız olduğuna karar verecek olan yine sizsiniz.

SPI Nedir ve Nasıl Çalışır?

Seri haberleşme ve Paralel haberleşme arasındaki farktan daha önceki yazılarımda bahsetmiştim. Seri haberleşmelerin en çok kullanılanlarından birisi olan SPI yani Serial Peripheral Interface haberleşme protokolünden bahsedeceğiz.

SPI haberleşme protokolü master/slave yapısını baz alarak çalışır ve full-duplex işleme izin verir. SPI haberleşmesi gerçekleştirebilmek için 4 pin gereklidir. Bunlar;

  • MOSI (SDO) (Master Out Slave In)
  • MISO (SDI) (Master In Slave Out)
  • CS (SS) (Chip Select)
  • Clock (SCL, CLK)

Burada bulunan MOSI ve MISO veri aktarımını gerçekleştirdiğimiz pinlerdir. CS pini ile hatta bulunan herhangi bir slave aygıtı seçmemiz sağlanıyor. Clock pini ise seri haberleşme gereği olarak verilerin iletilmesini sağlıyor.

Veri iletimi 8-bit olarak gerçekleşir. CS pinini kullanarak slave seçimini yaptıktan sonra master cihazından göndermek istediğiniz veriyi MOSI pinini Lojik 0 ve Lojik 1 şeklinde binary olarak değiştirerek hatta yazarsınız. Her bir bit için CLK pinini 0 – 1 yapmanız yeterlidir. Aşağıdaki resimde daha net bir şekilde görülmektedir.

Kaynaklar:

http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all

https://ondergormez.files.wordpress.com/2015/01/spi-iletim-yapisi.png

UART Nedir ve Nasıl Çalışır?

Daha önce Seri Haberleşme Protokolleri (UART, SPI, I2C) yazımda küçük bir değinme ile bahsettiğim haberleşme protokollerine biraz daha detaylı olarak girmeye başlayacağımız serimizin ilk yazısı olan “UART Nedir (USART Nedir) ve Nasıl Çalışır?” yazısı ile karşınızdayım.

UART (Universal Asynchronous Receiver Transmitter), bilgisayar ve mikrokontroller veya mikrokontroller ve çevre birimler arasında haberleşmeyi sağlayan haberleşme protokolüdür. Asenkron olarak çalıştığı için herhangi bir “clock” ihtiyacı duymaz. USART (Universal Synchronous Asynchronous Receiver Transmitter) ise hem senkron hem de asenkron olarak çalışabilir. UART’a göre daha gelişmiş bir protokoldür. Haberleşme mantıklı aynı şekilde çalışır ancak USART aynı zamanda senkron haberleşmeleri de gerçekleştirebilir. Yeni çıkan bir mikroişlemcinin datasheet’ine baktığınız zaman bu birimleri genelde USART birimi olarak görüyoruz çünkü USART aynı zamanda UART’ı da kapsayan bir birim olarak tasarlanmıştır.

USART, 5 ve 9 bit arası data uzunluğuna sahip veriyi taşıma özelliğine sahiptir. Ancak genel olarak 8 veya 9 bitlik kullanımlar tercih edilir.

UART – USART Haberleşmesi

UART haberleşmesini gerçekleştirirken ilk olarak baudrate (veri taşıma hızı) ayarlanması gerekir. Veri taşıma hızı çok çeşitli aralıklarda olabilir ancak piyasada yaygın olarak kullanılan baudrate’ler 4800, 9600, 57600, 115200 ve mikroişlemciler için çok fazla tercih edilmese de 921600. (921600 genelde hızlı işlem gerektiren yerlerde kullanılır.) Baudrate bizim verimizin saniyede ne kadarlık byte’ını taşıyacağını belirlememize yarar. Örneğin veri taşıma hızımızı 115200 seçersek bu bizim için saniyede yaklaşık olarak 11520 byte veri iletimi sağlayacaktır.

Veri iletimi için aşağıdaki görseldeki gibi bir yapı kullanılır. Yani haberleşme işlemimiz bir başlangıç bitinden sonra data bitleri, ardından parity biti ve son olarak da bitiş biti gönderilerek sonlandırılır. Bu işlem sırasında data uzunluğu ve parity biti opsiyonel olarak değişkenlik gösterebilir.

Bu haberleşme tipini kullanabilmemiz için alıcı ve vericinin veri taşıma hızlarının (baudrate) aynı olması gerekiyor (veya birbirine çok yakın değerler olması gerekiyor.) Bunun sebebi ise aktarım sırasında oluşabilecek hataları minimuma indirmek. Hata payları tolere edilebilir seviyede olması taktirde bir sorun yaratmayacaktır (~%1-3)

Yukarıdaki görselde gördüğünüz gibi haberleşme gerçekleşmesi için ilk önce verici tarafında logic 1 (HIGH) seviyesinde bulunan iletişim hattı iletişimin başlaması için logic 0 (LOW) seviyesine çekilir ve bu bizim Başlangıç Bit’imizi (Start Bit) temsil eder. Ardından göndermek istediğimiz verileri başlangıç bitinin arkasına ekleriz. Eğer parity bitine sahipsek onu da ekledikten sonra son olarak iletişime sonlandırmak için gerekli olan bitiş bitini (stop bit) HIGH seviyesine çekerek iletişimin sonlandığını alıcıya bildiririz. Biz verici kısmında bu işlemleri yaparken alıcı da aynı şekilde işlem yapar ve sadece bizim gönderdiğimiz dataları kendi UART Data Register’ına yazar.

Nasıl Kullanabiliriz?

USART haberleşmesi yapabilmek için mikroişlemcimizdeki daha önceden tanımlanmış olan pinleri kullanarız. Bunun için ya USB-TTL dönüştürücü ya da RS232 modülü kullanırız. Her iki modülü de RX-TX pinleri mikroişlemcimizin RX-TX pinleri ile ters olarak bağlanacak şekilde bağlantısını yaptıktan sonra iletişimi başlatabiliriz. (Yani mikroişlemci TX —> Modül RX, mikroişlemci RX —> Modül TX). RS232 ile daha ayrıntılı bilgi için ilgili yazımı ( RS232 Nedir? ) inceleyebilirsiniz.

Kaynaklar:

http://enderunix.org/docs/hard_soft-uart.pdf

https://learn.sparkfun.com/tutorials/serial-communication/uarts

https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter

http s://www.slideshare.net/canezgiaydemir/uart-ve-seri-haberleme

http://www.mcu-turkey.com/wp-content/uploads/2012/11/maximsoftuartfig1.jpg

http://www.bb-elec.com/Images/whitepaper-images/DataByte.aspx

C dili BCD to Decimal – Decimal to BCD çevirimi

Yapmakta olduğumuz bir projede kullanacağımız RTC modülü için zaman verilerini decimal değerden BCD (Binary Coded Decimal) formatına çevirmemiz gerekiyordu. Bunun için araştırma yaparken değişik yöntemler gördüm. Bizim projemiz için en uygun yapıyı ise bulamadık. Biz de kalem kağıdı elimize alıp sıvadık kolları.

Bu işlemi itoa() fonksiyonunu kullarak da kolayca yapabiliyorsunuz, ama mikrokontroller ile çalıştığımız için bize en az boyuta sahip kod lazım oluyor. O yüzden bir arayış içerisine girdik.

Projede bize lazım olan yapı için 2 basamaklı sayıların dönüşümünün yapılması yeterli olacaktı. Biz de bu yüzden kodu şişirmeden, sadece işimize yarayacak kadar olan yapıyı oluşturduk. Eğer size kullanmak istediğiniz yerde 2’den fazla basamaklı sayılar için dönüşüm yapmak isterseniz küçük matematik hesaplamaları ile bunu yapabilirsiniz. Biz bu yapı için daha büyük sayılara göre denemelerimizi yaptık ve düzgün sonuçlar aldık.

Aşağıdaki kodu kullanarak Decimal to BCD (Binary Coded Decimal) dönüşümünü yapabilirsiniz.

https://gist.github.com/d72fdcf96426f1b235453513e71101ab

Aşağıdaki kodu kullanarak BCD to Decimal dönüşümünü yapabilirsiniz.

https://gist.github.com/adb3353092c3394d1c5217a05540f2d9

C ve C++ dillerini kullanarak Decimal to BCD ve BCD to Decimal dönüşümlerini yapmanız bu kadar kolay.

cJSON ile JSON Oluşturma

Staj gördüğüm yerde geliştirdiğimiz bir proje için çeşitli cihaz ve sensörlerden alınan verinin belirli bir JSON formatına çevrilerek şirketin Bulut’una (Cloud) aktarılarak oradan düzenlendikten sonra farklı bir şekilde çekilerek görselleştirme işlemi yapmam gerekiyor.

Ben şu an için işin biraz daha başında sayılırım. Ama 3 gündür üzerinde çalıştığım C dili üzerinde verileri JSON formatına çevirme kütüphanelerinden birisi olan cJSON ile yaptığım çalışmayı sizinle paylaşmak istedim. Kütüphane, DaveGamble isimli Github kullanıcısı tarafından paylaşılmış. Dokümantasyonu içerisinde neredeyse her şeye yanıt veriyor. Yanıt vermediği şeyleri de cJSON.h içerisinden rahatlıkla bulduğumu söylemek istiyorum.

Öncelikle yapacağımız işlem için birden fazla cihazımız olacak, bu cihazlara bağlı birden fazla sensörler olacak ve bu sensörler bize veri gönderecek. Genel yapımız bu şekilde olacak.

İlk olarak gerekli kütüphaneleri dahil ederek başlıyoruz. <stdio.h> kütüphanesi standart giriş ve çıkışlar sağladığımız kütüphanemiz, <conio.h> kütüphanesi DOS destekli giriş çıkışları sağladığımız kütüphanemiz (biz sadece getch(); fonksiyonu ile işlem bittiğinden klavyeden bir tuşa basılmadıkça ekranın kapanmamasını sağlamak için kullanıyoruz.), <time.h> rastgele değerler üretirken, bu değerlerin programı çalıştırdığımız andaki zamana bağlı olarak değişmesi için kullanıyoruz ve son olarak <cJSON.h> bizim JSON olayımızı gerçekleştireceğimiz kütüphanemiz.

https://gist.github.com/abeab9281903dd97e2fb2fe5d74e87de

Yukarıdaki kod bloğunu kullanarak ortaya çıkarttığım çıktı şekli ise:

Gördüğünüz üzere kodumuz çoklu cihaz ve çoklu sensör destekler halde. Bunların sayısını istediğiniz kadar artırmak sizin elinizde. Bu projeme bitbucket üzerinden de ulaşabilir ve gerekli dosya ve dokümanları indirebilirsiniz.

C ve JSON ile Cihaz Veri İstasyonu

Kütüphanenin Github adresi

Arduino nRF24L01 ile Joystick Kontrollü Araba

Bir önceki yazımda, nRF24L01 modülünü nasıl daha kolay kullanırız ve nasıl toplu veri göndeririz onu anlatmıştım. O yazıyı yazarken aklıma, daha önce Bluetooth ile kontrol ettiğimiz aracımızı acaba nRF24L01 ve Joystick kullanarak kontrol etsem nasıl olur fikri geldi.

Aracım şase olarak zaten elimin altında duruyordu. O yüzden aracı nasıl yaptığımı bu yazıda anlatmayacağım. Aracın yapımına ve kodlara L298N Motor Sürücü Entegresi Kullanımı yazımdan ulaşabilirsiniz. Ben sadece aracın bağlı olduğu Arduino’ya bir adet modül ekledim. Diğer tarafta ise yine bir Arduino ve bir Joystick Shield kullandım. Joystick shield’in buton pinleri arka tarafında yazıyor, bu yüzden direk onları tanımlayarak başladım, ardından verilerini okuma işlemini gerçekleştirdim. Son olarak bu verileri göndereceğim dizi içerisine atarak gönderme işlemini yaptım.

Alıcı tarafında ise yapılan tek değişiklik motorların hızının gelen verilerdeki joystick verilerine göre değiştirilmesi oldu. O yüzden onu da kolaylıkla anlayacaksınızdır. Tabi joystick shield’den gelen verilerin tamamını okuyarak daha çok çeşitli şeyler yapılabilir ama ben şu an sadece örnek olması bakımından hız kontrolünü gerçekleştirdim.  Sorularınızı yorum olarak belirtirseniz elimden geldiği kadar yardımcı olmaya çalışacağım.

Kodların tamamına Github profilim üzerinden ulaşabilirsiniz.

Verici Modül Kodları:

https://gist.github.com/a74d2b6c892fc1356daa9e69db2d87b6

Alıcı Modül Kodları:

https://gist.github.com/f51be7950b2cc8187e4626151a7840bf

Arduino nRF24l01 Kablosuz Haberleşme

Arduino ile kablosuz haberleşme üzerine çalışmalar yapıyorum ve bir projemde her hangi bir ağa bağlanmadan, sadece 2 cihaz arasında (2 Arduino) haberleşmeyi sağlamam gerekti ve bunun için en uygun modülün nRF24l01 olduğuna karar verdim. Ama yaşadığım başka bir sıkıntı vardı, göndermem gereken verileri sadece karakter olarak gönderebiliyordum.

Bu sorunu çözmek için uzun araştırmalar yaptım. Ama modülün kendi örnekleri ve modül hakkında yazılan blog yazıları hem göndermem gereken mesajı bir ‘integer’ dizi olarak göndermiyor, hem de karmaşık yollar ile çözüme gitmeye çalışıyor ve bu benim işime yaramıyordu. O yüzden, okuması ve kullanması oldukça basit ve tek seferde birden fazla veriyi – tipi (int, float…) önemli değil – bir dizi halinde göndererek 2 modül arasında haberleşmeyi sağlayabileceğimiz bir hale getirdim.

Modülleri, alıcı ve verici için aynı şekilde bağlıyoruz.

Arduino nRF24L01 Modülü Bağlantısı
(Görsel: Turkcell Geleceği Yazanlar)

Bunu için öncelikle gerekli olan RF24 kütüphanesini kurmanız gerekiyor. (Kütüphaneye, Github sayfamdan ulaşabilirsiniz.)

Kodların içerisine gerekli olan açıklama satırlarını eklediğim için ayrıntılı olarak buradan açıklamayacağım.

Kodlara ve kütüphaneye Github profilim üzerinden ulaşabilirsiniz. Yaşadığınız sorunları yorum olarak belirtirseniz elimden geldiği kadar yardımcı olmaya çalışacağım.

Verici Modülünün Kodları:

https://gist.github.com/ea473be9404efc4b1b1eb7165926647a

Alıcı Modülünün Kodları:

https://gist.github.com/2aebd28bb2eda0ed538c02029565b8b3

Arduino ile Araba Kontrol Kütüphanesi

Daha önce L298N entegresinin nasıl kullanıldığını ve Arduino ve Android cihaz kullanarak arabamızı nasıl kontrol edeceğimize dair yazılar yazmıştım. Bu yazımda ise o projeleri biraz daha geliştirip herkesin hemen ve kolaylıkla kullanabileceği bir kütüphane yazdım ve paylaşmak istiyorum.

Kütüphane kullanmamızın avantajları ve dezavantajları olabilir. Avantajlarından bazıları, fonksiyonları tek tek elimizle yazmak yerine hazır olarak ulaşılabilir bir şekilde elde ederiz. Dökümantasyonlarını inceleyerek hangi fonksiyonların ne işe yaradığını öğrenebiliriz. Dezavantajları ise kullandığımız programda sadece bir fonksiyonu kullanmak varken, kütüphaneyi dahil ederek tüm fonksiyonları dosyamıza çağırmış oluruz ve bu da fazladan boyuta yol açar.

Kullanmaya Başlayalım

Benim bu kütüphaneyi yazmamdaki amaç, sadece motor pinlerinin girilmesi ile harekete hazır bir arabamızın olmasıdır. Bunun için kütüphanemizi dahil ettikten sonra bir Araba nesnesi oluşturmamız gerekiyor. Daha önce kütüphaneler kullandıysanız nesnelerin nasıl oluşturulacağını az çok biliyorsunuzdur. Kütüphane eklendikten sonra ilk eklemeniz gereken kod aşağıdaki gibidir.

Araba calistir(3, 4, 7, 8, 5, 6);

Bu kod artık kütüphane içerisindeki kodlarımızı “calistir” nesnesi ile birlikte kullanabileceğimizi ifade eder. Nesnemizin parametreleri ise şu şekilde.

Pin 3 ---->  Sol Motorun 1. Çıkışı
Pin 4 ---->  Sol Motorun 2. Çıkışı

Pin 7 ---->  Sağ Motorun 1. Çıkışı
Pin 8 ---->  Sağ Motorun 2. Çıkışı

Pin 5 ---->  Sol Motorun Enable (Hız Kontrolü Yapacağımız) Çıkışı
Pin 6 ---->  Sağ Motorun Enable (Hız Kontrolü Yapacağımız) Çıkışı

Burada dikkat etmemiz gereken nokta motorların enable (hız kontrol) pinlerinin PWM sinyali verebilecek pinler olmasıdır. PWM sinyali veren pinler Arduino Uno‘da 3, 5, 6, 9, 10, 11. pinlerdir. Çeşitli Arduino modelleri için farklılık gösterebilir.

Fonksiyonlar ve Kullanımları

Motor tanımlamamızı yaptıktan sonra kullanabileceğimiz fonksiyonlara geçebiliriz. Kütüphane içerisinde şu an kullanıma hazır 8 fonksiyon bulunuyor. Fonksiyonların listesi ve kullanım talimatları aşağıdaki gibidir.
https://gist.github.com/f1fce472f8ba5423f2009601c01d4ed3

Örnek kullanım dosyası

Fonksiyonların kullanımları bu şekilde. İsterseniz örnek bir kodla nasıl kullanıldıklarını görelim.
https://gist.github.com/91a9aeb15da291b720be41f83e709d9e

Bağlantılarınızı yaptıktan sonra fonksiyonları test ederken Seri Monitörü kullanarak fonksiyonların çalışıp çalışmadığını kontrol edebilirsiniz. Her fonksiyon kendine özgü değerleri ekrana bastırıyor.

Her şeyi uygun yaptığınızı düşünüyorsanız ama yine de araçtan bir tepki alamıyorsanız ilk önce bağlantınızı, daha sonra da kod içerisinde nesne oluştururken belirtmiş olduğunuz pinlerin doğru şekilde olup olmadığını tekrar kontrol edin. Yine çözemezseniz, yorum bölümünden ve ya iletişim sayfamdan benimle iletişime geçebilirsiniz.

Projedeki gelişmeleri takip etmek için: Github — Arduino Araba Kontrol Kütüphanesi

ESP8266 ile Server üzerinde RGB Led Kontrolü

ESP8266 RGB Led Server

Bir önceki NodeMCU ile DHT11 Kullanımı yazımda da belirttiğim gibi ESP8266 kullanarak bir şeyler öğrenmeye devam ediyorum. Bu yazımda ise Arduino‘muza bağlı olan ESP8266 modülü ile server üzerinden, bizim vermiş olduğumuz değerler ile yanacak bir RGB led kontrolü yapacağız.

İnternetteki bir çok kaynaktan bulabileceğiniz server kurma kodlarını yazarak vakit kaybetmek istemiyorum. Ben öncelikle RGB ledim için küçük bir renk fonksiyonu yazarak başlamak istiyorum.

https://gist.github.com/erenkeskin/5ad3207a1ee6db9bb609123233d29951

Bu kodları gerekli yerlere yerleştirdikten sonra geriye sadece RGB led’imiz için değer göndermek kalıyor. Unutmayın! RGB bacaklarınızı PWM sinyali veren pinlere takmalısınız.

Serverdan değerleri almamız için ben GET methodunu kullandım. Sanırım POST methodu ile de yapılabiliyor ama henüz o konuda net bir bilgiye ulaşamadığım için GET methodunu kullandım. Bunun için öncelikle bir HTML formu içerisinde değerler ile göndermemiz gerekli. Gönderme işleminin ardından sayfa adresi “/kirmizi=90&yesil=130&mavi=240” gibi bir hal alıyor. Bizim yapmamız gereken ise bu satırdan sayısal verileri alarak integer’a çevirmek ve ardından bu integer değerleri renkAyarla() fonksiyonuna göndererek ledi yakmak.

C’de URL parçalamak için çok kolay bir yol bulamadım. O yüzden kısmen uzun bir yol izleyerek tek tek parçaladım ve stabil sonuç elde edebildim. Eğer siz daha kısa ve kolay bir yol biliyorsanız benimle paylaşırsanız sevinirim.

Aşağıdaki kodlar ile HTML sayfanızı oluşturup RGB ledinizi kontrol edebilirsiniz.

Loop fonksiyonu içerisinde HTML olarak server yapısı oluşturduğum kod:

https://gist.github.com/e9ded39eaaf7e80900876f5c8650f59b

URL’yi parçalamak (split) ve Led’i yakmak için ise aşağıdaki kodu kullanıyorum.

https://gist.github.com/e3409dd51e52052324916a5d201086b4

Herhangi bir soru ve sorununuz olursa elimden geldiği kadar yardımcı olmaya çalışırım, yorum olarak belirtmeniz yeterli.