Merhaba bu yazımızda Arduino için bir kütüphane oluşturmayı anlatacağım. Oluşturacağımız kütüphane bir nevi zamanlayıcı (timer) olacak fakat kesmeleri (interrupt) kullanmayacağım. ona başka bir yazımızda değineceğim. Bu kütüphane başlangıçtan belirli aralıklarda kontrol edip istenilen durum oluştuğunda belirli bir fonksiyonu çağıracak.
Kütüphane oluşturmaya başlamak için ilk önce Arduino IDE’den oluşturduğumuz kodların nereye kayıt edildiğiniz öğrenmemiz gerekecek. Bunun için “Dosya>Tercihler>Eski Defteri Konumu” bölmesinden dosyaların kayıt edildiği yeri almamız gerekecek.
Dosya Gezgini’nde ilgili klasörü açıp içindeki “libraries” klasörüne girmek gerekiyor. Daha sonra burada yeni bir klasör oluşturmamız lazım. Klasörün ismi kütüphanemizin ismi ile aynı olmalı. Ben “Zamanlayici” olarak adlandıracağım.
Daha sonra yeni oluşturduğumuz klasörün içine aynı isimde .h ve .cpp dosyaları oluşturmamız lazım. Bu örneğimiz için “Zamanlayici.h” ve “Zamanlayici.cpp” olacaktır.
Burada “.h” ve “.cpp” dosyalarını ne için kullanıyoruz açıklamak gerekecek:
.h dosyaları kullanacağınız sınıfın fonksiyonlarının prototiplerinin olduğu dosyadır. .cpp dosyaları ise .h dosyasındaki prototiplerin içindeki kodların yazıldığı dosyadır. Kütüphanemizde ilk önce bir yapıcı metot tanımlayalım. Metodun bir parametresi tetiklenmesi sıklığı olsun, bir diğeri de hangi fonksiyonun tetikleneceği olsun. Kütüphanenin diğer fonksiyonları başlatma, durdurma ve tekrarları kontrol etme fonksiyonu olsun.
#ifndef Zamanlayici_h
#define Zamanlayici_h
#include "Arduino.h"
class Zamanlayici
{
public:
Zamanlayici(unsigned long ms, void (*f)());
void begin();
void stop();
void loop();
private:
unsigned long _ms;
void (*func)();
bool Baslat;
unsigned long _stMillis;
};
#endif
Burada #ifndef önişlemci (Preprocessor) komutu kafanızı karıştırmış olabilir. Bunun nedeni eğer yazdığınız kodda kullandığınız kütüphane birden fazla eklenirse uygulamanız hata verecektir çünkü aynı fonksiyonlar ve sınıflar tekrardan eklenmeye çalışacaktır. Ayrıca yapıcı metodunda bulunan “void (*f)()” ifadesi de kafanızı karıştırmış olabilir. Burada da bir fonksiyon işaretçisini (pointer) parametre olarak aldım. Böylece zamanlayıcı tetiklendiğinde çalışacak olarak fonksiyonu kullanıcının belirlemesine olanak sağladım.
“public:” ifadesinde tanımlanan fonksiyon ve değişkenlere oluşturduğumuz objelerden erişebiliyoruz fakat “private:” ifadesinde tanımlanan fonksiyon ve değişkenlere ise sadece oluşturduğumuz “.cpp” uzantılı dosyadan erişebiliriz.
Bu kütüphanenin en karmaşık fonksiyonları Zamanlayici ve loop fonksiyonlarıdır. Zamanlayici fonksiyon aşağıdaki gibi:
Zamanlayici::Zamanlayici(unsigned long ms, void (*f)())
{
_ms = ms;
func = f;
Baslat = false;
}
Tanımlama fonksiyonunda bulunan “Zamanlayici::” ifadesi “.h” dosyası içinde tanımladığımız sınıfın bir parçası olduğunu belirtmek için kullanıyoruz. Fonksiyon tanımında bulunan milisaniye cinsinden zaman aralığı ve tetiklenecek fonksiyonun adresi. Eğer ilgili fonksiyonun bir parametre almasını isterseniz. “void (*f)()” yerine “void (*f)(ParametreTipi1, ParametreTipi2, …)” (void (*f)(int, char, …)) şeklinde bir tanımlama yapmanız gerekiyor. Kodun tam hali aşağıdadır:
#include "Zamanlayici.h"
#include "Arduino.h"
Zamanlayici::Zamanlayici(unsigned long ms, void (*f)())
{
_ms = ms;
func = f;
Baslat = false;
}
void Zamanlayici::begin()
{
if(!Baslat)
{
_stMillis = millis();
}
Baslat = true;
}
void Zamanlayici::stop()
{
Baslat = false;
}
void Zamanlayici::loop()
{
if(!Baslat) return;
unsigned long _curMillis = millis();
if(_curMillis - _stMillis >= _ms)
{
func();
_stMillis = millis();
}
}
İlgili geliştirmeleri yaptıktan sonra Arduino IDE’nizi kapatıp açarsanız “Eskiz>Kütüphane Ekle> Eklenmiş Kütüphaneler” kısmına gelmiş olacaktır.
Örnek olarak yazdığımız kodda derleme aşamasında hata verdi. Test fonksiyonuna ulaşamadığınız söylüyor. Bunun sebebi kullandığımız dile ile alakalı. Daha “Test” fonksiyonu tanımlanmadan kullanmaya çalıştığımız için derleyici bunu bilemiyor o yüzden hata veriyor. Bunun önüne geçmek için 2 tane yöntem var. Ya “Test” fonksiyonunu “zaman1” değişkenini tanımlamadan önce tanımlayacağız ya da fonksiyonunun bir prototipini “zaman1” değişkeninden önce tanımlamamız gerekecektir.
#include <Zamanlayici.h>
void Test()
{
Serial.println("Test");
}
Zamanlayici zaman1(1000, Test);
void setup() {
Serial.begin(9600);
zaman1.begin();
}
void loop() {
zaman1.loop();
}
Eğer programın loop fonksiyonuna herhangi bir kod eklersek uygulamanın loop fonksiyonuna tekrar girmesi zaman alacağından her zaman istenilen aralıklarla fonksiyon çalışmayacaktır. Fakat delay fonksiyonunu kullanarak tüm programı durdurmaktansa bu gecikmeler işinize yarayabilir. Eğer tam zamanında çalışmasını istiyorsanız kesmeleri (interrupt) kullanabilirsiniz. Daha sonraki yazılarımızda da bu konu ile bu sorunu nasıl çözeceğimiz anlatacağım.
Yazımı okuduğunuz için teşekkür ederim, umarım yardımcı olabilmişimdir.