Arduino DHT11 Kütüphane İncelemesi -2- dht.h Dosyası
İşin donanım kısmını bitirdiğimize göre kütüphaneyi enine boyuna inceleyebiliriz. Bunun için Arduino için en sık kullanılan kütüphane olan Adafruit’in DHT kütüphanesini kullanacağım. Donanımı ve yazılımı bildiğime göre istersem ben de şimdi bir kütüphane yazabilirim. Ama her zaman hazır yazılmış kütüphaneleri alıp incelemekte fayda vardır. Sizin gözünüzden kaçan noktaları o kütüphanelerde görebilirsiniz. Adafruit’in DHT kütüphanesini aşağıdaki bağlantıdan indirip hep beraber inceleyelim.
https://github.com/adafruit/DHT-sensor-library
Dosyayı indirip çıkardığımızda klasörün içinde farklı farklı dosyaların olduğunu görürüz. Burada bizi ilgilendiren DHT.h ve DHT.cpp dosyalarıdır. Diğerlerini dikkate almadan bu iki dosyayı inceleyelim. Kütüphane incelemesine her zaman .h uzantılı dosyadan başlamamız gereklidir. Kütüphane dosyaları yeterince uzun olduğu için olduğu gibi buraya kopyalamayacağım. Burada yazdığım kodları sizin kod üzerinde takip etmeniz gereklidir. O yüzden Notepad++ veya Sublime Text ile bu kodları açıp ekranın bir köşesinde takip etmelisiniz.
1 2 |
#ifndef DHT_H #define DHT_H |
Temel C programlama derslerinde söylediğimiz üzere tekrar tanımın önüne geçmek için böyle bir kod bloku kullanılmaktadır. Dosyanın aynı anlattığımız gibi #endif ile bittiğini görmekteyiz. Siz de kütüphane başlık dosyası oluştururken #ifndef DOSYAADI_H şeklinde başlayan bir blok tanımlamanız gereklidir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* Uncomment to enable printing out nice debug messages. */ //#define DHT_DEBUG #define DEBUG_PRINTER Serial /**< Define where debug output will be printed. */ /* Setup debug printing macros. */ #ifdef DHT_DEBUG #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } #else #define DEBUG_PRINT(...) {} /**< Debug Print Placeholder if Debug is disabled */ #define DEBUG_PRINTLN(...) {} /**< Debug Print Line Placeholder if Debug is disabled */ #endif |
Burada kütüphanede hata ayıklama fonksiyonunun da olduğunu görmekteyiz. Karşımıza gelen hazır kodları kullansaydık bu hata ayıklamadan pek de haberimiz olmayacaktı. Çünkü bu hata ayıklama özelliğini ancak .h uzantılı dosyadaki kodu değiştirerek kullanabiliyoruz. Bunun gibi pek çok kütüphane başlık dosyalarını ayarlamak için açıp incelememiz gerekebilir. Normalde Arduino’da eklediğimizde bitse de gerçek programcılıkta belki .cpp uzantılı dosya ile işimiz olmasa dahil .h uzantılı dosyayı çok iyi bilmemiz gerekir. C dilinde çalışırken de pek çok zaman konfigürasyon yapmak için uğrarız. Arduino C++’nın sınıf yapısını kullandığı için buna çok gerek kalmamaktadır.
Burada değer //#define DHT_DEBUG satırındaki komutu kaldırırsak #ifdef DHT_DEBUG bloku içinde yer alan komutu çalıştırmış oluruz. Burada DEBUG_PRINT() ve DEBUG_PRINTLN() adında makrolar bulunmaktadır. Bu makroları .cpp dosyasında ilgili yerlerde kullandıklarını görmekteyiz. Yani bu hata ayıklama mesajlarını program içinde bize mesaj vermek için önceden hazırlamışlar. Burada #define DEBUG_PRINTER Serial tanımı ile istersek print() ve println() fonksiyonlarını kullanan farklı birimleri seçebiliriz. Örneğin Serial yerine SPI veya wire olabilir. Bu sizin seçiminize bırakılmıştır.
1 2 3 4 5 6 |
/* Define types of sensors. */ #define DHT11 11 /**< DHT TYPE 11 */ #define DHT12 12 /**< DHY TYPE 12 */ #define DHT22 22 /**< DHT TYPE 22 */ #define DHT21 21 /**< DHT TYPE 21 */ #define AM2301 21 /**< AM2301 */ |
Bu kütüphane sadece DHT11 algılayıcısı için yazılmadığı için DHT’yi tanımlayacağımız sabitler burada belirlenmiştir. Biz tanımlarda DHT11, DHT12, DHT22 şeklinde yazmaktayız bunu program ise 11, 12, 22 olarak algılamaktadır.
1 2 3 4 5 6 7 8 9 10 11 |
class DHT { public: DHT(uint8_t pin, uint8_t type, uint8_t count=6); void begin(uint8_t usec=55); float readTemperature(bool S=false, bool force=false); float convertCtoF(float); float convertFtoC(float); float computeHeatIndex(bool isFahrenheit=true); float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true); float readHumidity(bool force=false); bool read(bool force=false); |
Burada class anahtar kelimesini görmekteyiz. Aslında Arduino’nun C++’yı genelde sadece sınıflar için kullandığını görürüz. Sınıfların olması kafanızı asla karıştırmasın. C programcısıysanız sınıfları fonksiyonlu yapılar olarak düşünebilirsiniz. public yapı dışından erişilebilen kısım private ise yapı fonksiyonlarının erişebildiği kısım olarak düşünülebilir. Duruma böyle baktığınızda oldukça basit olduğunu göreceksiniz.
public kısmına baktığımızda fonksiyonlar listesinden ibaret olduğunu görebiliriz. Normalde biz C dilinde fonksiyonları açık bir şekilde listelerken bunlar bir sınıfın içerisinde tanımlamıştır. Burada DHT’nin tanım fonksiyonu olup tanımlama sırasında çalıştırılacağını görüyoruz. Burada pin, type ve count adında üç değer almakta. pin ve type verilerini biz versek de count değişkenine ilk değer 6 olarak verilmiştir.
Fonsiyon adlarına baktığımızda begin, readTemperature, concertCtoF, convertFtoC, computeHeatIndex, readHumidity ve read fonksiyonlarının olduğunu görmekteyiz. Bunun çevirisini yaptığımızda az çok ne işe yaradığını anlasak da .cpp kodunu incelemeden kesin bir şey söylememiz zordur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private: uint8_t data[5]; uint8_t _pin, _type; #ifdef __AVR // Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask // for the digital pin connected to the DHT. Other platforms will use digitalRead. uint8_t _bit, _port; #endif uint32_t _lastreadtime, _maxcycles; bool _lastresult; uint8_t pullTime; // Time (in usec) to pull up data line before reading uint32_t expectPulse(bool level); }; |
Burada özel verilerin olduğunu görmekteyiz. Açıklamalar kısmı hariç elimizde çok fazla ipucu yok. Bunların nasıl kullanıldığını yukarıdaki fonksiyonların içerisinde göreceğiz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class InterruptLock { public: InterruptLock() { #if !defined(ARDUINO_ARCH_NRF52) noInterrupts(); #endif } ~InterruptLock() { #if !defined(ARDUINO_ARCH_NRF52) interrupts(); #endif } }; #endif |
Bu sınıf kesmeleri kilitleme görevini üstlenmektedir. Uygulanışını .cpp dosyası içerisinde göreceğiz. Burada ayrıntıya girmemiz çok da mümkün değil.
.h dosyasını incelediğimize göre bir sonraki yazıda .cpp dosyasını inceleyeceğiz. .h ve .cpp dosyaları birbirinden bağımsız incelenemez. O yüzden de bir yandan .h dosyasına bakmanızı tanımlanan verilerin tiplerini, tanımlanan fonksiyonların döndürdüğü değeri ve diğer bilgileri kontrol etmenizi tavsiye ediyorum.
Bizi Facebook grubumuzda takip etmeyi unutmayın. Bilgili ve öğrenmeye hevesli bir topluluk oluşturmak istiyoruz.
https://www.facebook.com/groups/1233336523490761/
UYARI!!
Bu sitede yayınlanan yazılar orjinal içerik olup faydalanılan kaynaklar belirtilmiştir. Yazarın izni olmaksızın tamamen alıntı yapılamaz, kopyalanamaz. Kaynak göstermek kaydıyla (Yazının adı, yazar adı ve link) kısmen alıntı yapılabilir.
Son Yorumlar