Arduino programlamada değişkenler, program çalışırken ihtiyaç duyduğumuz bilgileri saklamak için kullanılır. Sensörlerden okunan değerler, LED’in açık veya kapalı olması, motorun çalışma hızı ve ekrana yazdırılacak metinler değişkenler aracılığıyla yönetilebilir.
Bu derste değişkenlerin ne olduğunu, nasıl tanımlandığını, değişken isimlendirme kurallarını ve Arduino’da sık kullanılan veri tiplerini öğreneceğiz.
Değişkenleri, arduino ram belleğinde veri saklamak için kullandığımız isimlendirilmiş alanlar olarak düşünebiliriz.
Örnek olarak arduinoyu bir dolap olarak düşünelim. Dolap içerisinde farklı şeyler saklayacağız. Bu dolabın rafları bizim ram belleğimiz olsun. Örneğin kum saklamak istersek bu kumu dolabın rafına öylece boşaltamayız. Öncelikle onu tutabilecek bir kaba ihtiyaç duyarız bu kabımız bizim değişkenimizdir.
Veri tipleri ise değişkenin içerisinde tutulabilecek malzeme tipimizdir. Örneğin kumu bez torba ile saklayabiliriz ancak aynı bez torbada su saklayamayız. Çünkü bez torba suyu tutmayacaktır. Bunun için plastik ya da cam şişeye ihtiyacımız var.
Tabi her değişken tanımlarken o değişkene de bir isim vermeliyiz, yani dolaba koyduğumuz her kabın üzerine bir etiket yapıştırarak içinde ne olduğunu belirtmek gibi.
Her maddenin bir boyutu olduğu gibi her değişkenin birde veri tutma kapasitesi var.
Bir değişken tanımlarken temel olarak iki bilgi belirtiriz:
Değişkene ilk değerini tanımlama sırasında verebiliriz. Buna başlangıç değeri atama (ilklendirme) denir.
Örneğin:
int sicaklik = 25;
Bu satırda:
Değişkeni başlangıçta değer vermeden de tanımlayabiliriz:
int sicaklik;
sicaklik = 25;
Ancak bu örnekteki gibi yerel değişkenleri, değerlerini okumadan önce mutlaka geçerli bir değerle başlatmalıyız.
Değişken isimleri, programın okunabilirliğini artıracak şekilde seçilmelidir. Örneğin motorHizi ismi, x ismine göre değişkenin neyi temsil ettiğini daha iyi anlatır.
C++ tabanlı Arduino programlamada değişken isimleri için temel kurallar şunlardır:
Türkçe karakterler ve diğer ASCII dışı karakterler konusunda derleyiciye ve araç zincirine bağlı farklılıklar olabileceğinden, taşınabilir kod yazmak için değişken isimlerinde İngilizce harfler kullanmak önerilir.
Doğru örnekler:
|
1 2 3 |
int motorHizi = 120; int sensor_degeri = 450; int pin2 = 7; |
Yanlış örnekler:
|
1 2 |
int 2motor = 120; // Rakamla başlayamaz int motor hizi = 120; // Boşluk içeremez |
Veri tipi, bir değişkende hangi türden değerlerin tutulacağını ve bu değerlerin nasıl yorumlanacağını belirler.
Örneğin tam sayılar için int , ondalıklı sayılar için float , mantıksal durumlar için bool kullanabiliriz.
Arduino kartlarının işlemci mimarileri farklı olabildiği için bazı veri tiplerinin boyutları karttan karta değişebilir. Aşağıdaki örneklerde özellikle klasik Arduino Uno ve Arduino Due arasındaki farklara dikkat edilmelidir.
İşte arduino programlarken kullanacağımız değişkenler ve tutabildiği veri tipleri:
bool veri true (doğru) veya false (yanlış) olmak üzere iki mantıksal değeri tutabilir. LED’in açık olup olmadığını, bir alarmın etkinliğini veya bir koşulun gerçekleşip gerçekleşmediğini takip etmek için kullanılabilir.
|
1 2 |
bool ledAcik = true; bool alarmAktif = false; |
Not: bool, mantıksal olarak iki değer taşısa da bellekte mutlaka bir bit yer kapladığı anlamına gelmez. Yaygın Arduino C++ uygulamalarında bir bayt kullanır.
Karakter türünde veri tipidir. char tipi değişken, tek bir karakteri veya küçük bir sayısal değeri saklamak için kullanılır.
|
1 2 3 |
char karakter = 'a'; char karakter2 = 'B'; char karakter3 = 99; |
Tek bir karakter tek tırnakla yazılır. Birden fazla karakterden oluşan metinler için çift tırnak kullanılır.
|
1 2 |
char harf = 'A'; char metin[] = "Arduino"; |
char değişken tipi genellikle bir bayttır. Ancak işaretli veya işaretsiz olması uygulamaya bağlı olabileceğinden, her kartta aynı sayısal aralığı sağladığı varsayılmamalıdır.
Ayrıca char, Unicode karakterleri genel olarak tek başına saklayan bir tür değildir. Türkçe karakterler gibi bazı karakterler UTF-8 kodlamasında birden fazla baytla temsil edilir.
Sayı türü değişken tipidir. Bir byte yani 8 bit işaretsiz tam sayı türünden verileri tutabilir. 0 ile 255 arasındaki sayıları tutmak için kullanılır.
|
1 2 3 |
byte seviye = 0; byte pwmDegeri = 128; byte maksimum = 255; |
byte, özellikle 8 bitlik değerlerle çalışırken kullanışlıdır.
Örneğin 0–255 aralığındaki bir PWM değerini saklamak için uygundur. Ancak kullanılacak fonksiyonun ve kartın gereksinimleri de dikkate alınmalıdır.
int, tam sayıları saklamak için kullanılan temel veri tiplerinden biridir.
Klasik Arduino Uno gibi ATmega tabanlı kartlarda int 16 bittir ve −32.768 ile 32.767 arasındaki değerleri tutabilir.
Arduino Due gibi 32 bitlik bazı kartlarda ise int 32 bittir ve −2.147.483.648 ile 2.147.483.647 arasındaki değerleri tutabilir.
|
1 2 3 |
int sensorDegeri = 512; int sicaklik = -10; int pinNumarasi = 13; |
Önemli: Bir değişkene tutabileceği aralığın dışında değer atamak doğru sonuç vermeyebilir. Bu nedenle kullanılacak kartın veri tipi özellikleri dikkate alınmalıdır.
Örneğin klasik Arduino Uno’da int sayac= 65535; şeklinde kullanım uygun değildir. Bu değer için Arduino Uno’da unsigned int kullanılabilir: unsigned int sayac = 65535;
unsigned int, negatif olmayan tam sayıları saklar. int ile arasındaki temel fark, negatif değerler yerine daha geniş bir pozitif değer aralığı sağlamasıdır.
Klasik Arduino Uno’da 16 bittir ve 0 ile 65.535 arasındaki değerleri tutabilir.
|
1 2 3 |
unsigned int sayac = 0; unsigned int darbeSayisi = 1000; unsigned int maksimumDeger = 65535; |
Ancak unsigned int her Arduino kartında aynı boyutta değildir. Örneğin 32 bitlik Arduino Due üzerinde bu tip 32 bittir.
Negatif değerlerin gerekli olmadığı ve hedef kartın veri tipi aralığının bilindiği durumlarda kullanılabilir.
Arduino’da word, işaretsiz bir tam sayı türüdür. Yaygın Arduino çekirdeklerinde unsigned int ile aynı temel türü ifade eder.
Klasik Arduino Uno üzerinde 16 bitliktir ve 0 ile 65.535 arasında değer tutabilir.
|
1 2 |
word adcDegeri = 1023; word sayac = 500; |
long, daha büyük tam sayılarla çalışmak için kullanılır. Yaygın Arduino platformlarında 4 byte yani 32 bittir ve −2.147.483.648 ile 2.147.483.647 arasında değer tutabilir.
|
1 2 3 |
long sayac = 0L; long toplamDarbe = 150000L; long sicaklikFarki = -25000L; |
Sayıların sonuna L veya l eklenmesi, sayısal sabitin long türünde değerlendirilmesini sağlar. Ancak her long değişkenine değer atarken bu son eki kullanmak zorunlu değildir.
Örneğin; long sayac = 100000; gibi kullanım da geçerlidir.
unsigned long, negatif olmayan büyük tam sayıları saklamak için kullanılır. Yaygın Arduino platformlarında 32 bittir ve 0 ile 4.294.967.295 arasında değer tutabilir.
|
1 2 |
unsigned long gecenSure = 100000UL; unsigned long zamanDamgasi = 4294967295UL; |
UL son eki, sayısal sabitin işaretsiz long türünde değerlendirilmesini sağlar.
Bu veri tipi, Arduino’daki millis() gibi zaman fonksiyonlarının sonuçlarını saklamak için de yaygın olarak kullanılır.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
unsigned long oncekiZaman = 0; void setup() { Serial.begin(9600); } void loop() { unsigned long simdikiZaman = millis(); if (simdikiZaman - oncekiZaman >= 1000UL) { oncekiZaman = simdikiZaman; Serial.println("Bir saniye gecti."); } } |
Bu örnek, delay() kullanmadan yaklaşık bir saniyelik aralıklarla mesaj yazdırır. Zaman hesabında çıkarma yöntemi kullanıldığı için millis() sayacının taşması da bu yaklaşımda doğru şekilde ele alınabilir.
short, yaygın Arduino platformlarında 16 bitlik işaretli tam sayı türüdür. −32.768 ile 32.767 arasındaki değerleri tutabilir.
|
1 2 3 |
short sayi = 0; short sicaklikFarki = -150; short offsetDegeri = 250; |
short ve int aynı boyutta olsa bile iki ayrı veri tipi adıdır. Hangi türün seçileceği, kodun okunabilirliğine ve uygulamanın gereksinimlerine bağlıdır.
float, ondalıklı sayıları yaklaşık olarak temsil etmek için kullanılır. Sensör kalibrasyonu, gerilim hesabı, sıcaklık dönüşümü ve matematiksel işlemler için yararlıdır.
Yaygın Arduino platformlarında 32 bittir ve yaklaşık 6–7 anlamlı basamak hassasiyeti sağlar.
|
1 2 3 |
float gerilim = 4.75; float sicaklik = 23.6; float katsayi = 1.125; |
Ondalıklı sayılar tam olarak temsil edilemeyebilir. Bu nedenle iki float değeri doğrudan eşitlik operatörüyle karşılaştırmak bazı durumlarda beklenmedik sonuçlar verebilir.
Örnek:
|
1 2 3 4 5 |
float olculen = 9.0 / 0.3; if (olculen > 29.99 && olculen < 30.01) { // Deger 30'a yeterince yakin } |
Tam sayılarla yapılan bölme işlemlerinde de dikkatli olunmalıdır:
|
1 2 3 4 5 |
int a = 1; int b = 2; float sonuc1 = a / b; // Sonuç: 0 float sonuc2 = (float)a / b; // Sonuç: 0.5 |
İlk örnekte bölme işlemi tam sayılar arasında yapıldığı için kesirli kısım kaybolur. İkinci örnekte işlem öncesinde tür dönüşümü yapılır.
double, ondalıklı sayıları temsil etmek için kullanılan bir veri tipidir. Ancak sağladığı hassasiyet Arduino kartının mimarisine bağlıdır.
|
1 |
double hesaplananDeger = 123.456789; |
Daha yüksek hassasiyet gerektiğinde hedef kartın double desteği kontrol edilmelidir. Sadece double yazmak, her Arduino kartında daha hassas hesaplama yapılacağı anlamına gelmez.
Arduino’da String, metinlerle çalışmayı kolaylaştıran bir sınıftır. Metinleri saklamak, birleştirmek ve karşılaştırmak için kullanılabilir.
|
1 2 |
String mesaj = "Merhaba Arduino"; String durum = "Motor calisiyor"; |
Metinler çift tırnakla yazılır. String ile string aynı yazım değildir; Arduino’nun yaygın String sınıfının adı büyük S harfiyle başlar.
Örnek:
|
1 2 |
String ad = "Arduino"; String mesaj = "Merhaba " + ad; |
String kullanımı özellikle küçük ve orta ölçekli uygulamalarda pratiktir. Bununla birlikte, dinamik bellek kullandığından bellek kapasitesi sınırlı kartlarda uzun süre çalışan ve sık metin oluşturan uygulamalarda bellek parçalanması gibi sorunlara dikkat edilmelidir.
Metinleri saklamanın bir diğer yolu karakter dizileri kullanmaktır.
|
1 |
char mesaj[] = "Merhaba Arduino"; |
Bu örnekte metin, karakterlerden oluşan bir dizi içinde tutulur. C tarzı metinlerde sonlandırıcı ‘\0’ karakteri de bulunur.
Karakter dizileri, bellek kullanımını daha açık kontrol etmek istediğimiz uygulamalarda yararlı olabilir.
Örnek: char durum[] = "Hazir";
String sınıfı ile char[] karakter dizileri farklı yaklaşımlardır. Hangisinin kullanılacağı, programın ihtiyaçlarına, bellek kapasitesine ve metin üzerinde yapılacak işlemlere göre belirlenmelidir.
Aşağıdaki tablo, klasik Arduino Uno ve Arduino Due gibi kartlarda sık kullanılan veri tiplerinin genel özelliklerini özetler.
| tipi | Arduino Uno | Arduino Due | Kullanım amacı |
|---|---|---|---|
| bool | Mantıksal tür | Mantıksal tür | Doğru/yanlış durumları |
| char | Genellikle 1 bayt | Genellikle 1 bayt | Karakter ve küçük sayısal değerler |
| byte | 1 bayt | 1 bayt | 0–255 aralığı |
| int | 2 bayt | 4 bayt | Tam sayılar |
| unsigned int | 2 bayt | 4 bayt | Negatif olmayan tam sayılar |
| word | Genellikle 2 bayt | Genellikle 4 bayt | İşaretsiz tam sayılar |
| short | 2 bayt | 2 bayt | Kısa tam sayılar |
| long | 4 bayt | 4 bayt | Geniş aralıklı tam sayılar |
| unsigned long | 4 bayt | 4 bayt | Geniş aralıklı işaretsiz tam sayılar |
| float | 4 bayt | 4 bayt | Ondalıklı sayılar |
| double | 4 bayt | 8 bayt | Ondalıklı sayılar; karta bağlı hassasiyet |
| String | Değişken | Değişken | Metin işleme |
| char[] | Dizi uzunluğuna bağlı | Dizi uzunluğuna bağlı | Karakter dizileri |
Bu tablo yaygın kart örneklerini gösterir; tüm Arduino kartları için genel bir boyut tablosu değildir.
Değişkenler ve veri tipleri, Arduino programlamanın temel yapı taşlarındandır. Doğru veri tipini seçebilmek için saklanacak değerin türünü, alabileceği en küçük ve en büyük değerleri, hassasiyet gereksinimini ve kullanılacak kartın özelliklerini bilmek gerekir.
Bu derste değişken tanımlamayı ve Arduino’da yaygın olarak kullanılan veri tiplerini öğrendik. Bir sonraki derste Arduino’nun dijital giriş ve çıkış fonksiyonlarını inceleyerek LED yakma uygulaması yapabiliriz.