Temeller · 12 dk okuma

Arduino Komutları ve Anlamları: Örnekli Temel Komut Listesi

Arduino komutları ve anlamları: pinMode, digitalWrite, analogRead, analogWrite, millis, Serial, map, tone, pulseIn, attachInterrupt; örnekler ve sık hatalar.

Arduino komutları, karta ne yapacağını söyleyen hazır fonksiyonlardır: bir pini çıkış yapan pinMode(), LED yakan digitalWrite(), sensör okuyan analogRead() ve bilgisayara mesaj gönderen Serial.println() bunların en bilinenleridir. Arduino programlarının büyük bölümü aslında yirmi kadar temel komutun farklı biçimlerde bir araya gelmesinden oluşur. Bu komutları ve anlamlarını bir kez iyice öğrendiğinde LED yakmaktan robot arabaya kadar gördüğün her kodu okuyabilir, kendi projeni de sıfırdan yazabilirsin.

Bu rehberde en çok kullanılan Arduino komutlarını dört grupta topladık: giriş-çıkış, zaman, matematik ve haberleşme. Her komut için söz dizimini, parametrelerin ne anlama geldiğini, Arduino Uno'da derlenip çalışan kısa bir örneği ve yeni başlayanların en sık düştüğü hatayı bulacaksın. Son bölümlerde aynı komutların ESP32'de nasıl farklı davrandığını ve Raspberry Pi Pico'daki MicroPython karşılıklarını da göreceğiz.

Arduino Uno kartı, dijital ve analog pinleri
Arduino Uno: 0–13 numaralı dijital pinler, A0–A5 analog girişleri ve ~ işaretli PWM pinleri bu yazıdaki bütün komutları denemek için yeterlidir.

Arduino komutu nedir, program nasıl çalışır?

Arduino kodu C/C++ dilinin üzerine kurulmuştur; "komut" dediğimiz şeylerin çoğu aslında Arduino çekirdeğinin sana hazır sunduğu fonksiyonlardır. Bir fonksiyon parantez içinde parametre alır (örneğin pin numarası ve değer), bazıları da geriye bir sonuç döndürür: digitalRead() pinin durumunu, millis() geçen süreyi verir. Her Arduino programında iki zorunlu fonksiyon vardır: setup() kart açıldığında ya da resetlendiğinde yalnızca bir kez çalışır, loop() ise ardından sonsuza kadar tekrar eder. Pin ayarları ve Serial.begin() gibi hazırlıklar setup() içine, sürekli yapılacak işler loop() içine yazılır.

Arduino (C++)
1// Her Arduino programı bu iki fonksiyondan oluşur / Every Arduino sketch has these two functions
2void setup() {
3  // Açılışta ya da resetten sonra bir kez çalışır / Runs once at power-up or after reset
4  pinMode(13, OUTPUT);      // dahili LED pini çıkış / built-in LED pin as output
5}
6
7void loop() {
8  // Sonsuza kadar tekrar eder / Repeats forever
9  digitalWrite(13, HIGH);   // LED'i yak / turn the LED on
10  delay(500);               // 500 ms bekle / wait 500 ms
11  digitalWrite(13, LOW);    // LED'i söndür / turn the LED off
12  delay(500);
13}

Üç kurala baştan dikkat etmek seni birçok derleme hatasından kurtarır: komutlar büyük-küçük harfe duyarlıdır (digitalwrite yazarsan "'digitalwrite' was not declared in this scope" hatası alırsın), her ifade noktalı virgülle biter ve metinler çift tırnak, tek karakterler tek tırnak içine yazılır. Değişken türleri, if ve for gibi yapılar için Arduino programlama temelleri yazısına göz atabilirsin.

Arduino komutları listesi: kategorilere göre tablolar

Aşağıdaki dört tablo, günlük projelerde kullanacağın komutların neredeyse tamamını özetliyor. İlk grup giriş-çıkış komutlarıdır; pinlerin görevini belirler, pinlere gerilim verir ya da pinlerden değer okurlar. Kartındaki pin numaralarını Pinout aracında görebilirsin.

KomutSöz dizimiNe işe yarar?Örnek
pinModepinMode(pin, mod)Pini giriş ya da çıkış yaparpinMode(13, OUTPUT);
digitalWritedigitalWrite(pin, değer)Pini HIGH (5 V) ya da LOW (0 V) yapardigitalWrite(13, HIGH);
digitalReaddigitalRead(pin)Pinin HIGH mı LOW mu olduğunu okurint b = digitalRead(2);
analogReadanalogRead(pin)0–5 V gerilimi 0–1023 sayısına çevirirint v = analogRead(A0);
analogWriteanalogWrite(pin, değer)0–255 arası PWM sinyali üretiranalogWrite(9, 128);
analogReferenceanalogReference(tip)analogRead'in referans gerilimini seçeranalogReference(INTERNAL);
tone / noTonetone(pin, frekans, süre)Kare dalgayla ses üretir, noTone durdururtone(8, 440, 500);
pulseInpulseIn(pin, değer, zamanAşımı)Bir darbenin süresini µs olarak ölçerpulseIn(10, HIGH, 30000);
shiftOutshiftOut(veriPin, saatPin, sıra, bayt)Bir baytı bit bit gönderir (74HC595 gibi)shiftOut(11, 12, MSBFIRST, 255);
attachInterruptattachInterrupt(kesme, fonksiyon, mod)Pin değişince fonksiyonu anında çağırırattachInterrupt(digitalPinToInterrupt(2), say, FALLING);

İkinci grup zaman komutlarıdır. Bekleme yapan delay() ile süre ölçen millis() ve micros() arasındaki farkı anlamak, akıcı çalışan bir program yazmanın anahtarıdır.

KomutSöz dizimiNe işe yarar?Dikkat
delaydelay(ms)Verilen milisaniye kadar beklerBu sürede program durur
delayMicrosecondsdelayMicroseconds(us)Mikrosaniye düzeyinde bekler3–16383 µs arasında doğrudur
millismillis()Açılıştan beri geçen milisaniyeyi verirunsigned long; yaklaşık 49,7 günde sıfırlanır
microsmicros()Açılıştan beri geçen mikrosaniyeyi verirUno'da 4 µs adımlarla artar, yaklaşık 70 dakikada sıfırlanır

Üçüncü grup matematik komutlarıdır; sensörden gelen sayıyı başka bir aralığa çevirmek, sınırlamak ya da rastgele sayı üretmek için kullanılırlar. Dördüncü grup olan haberleşme komutları ise kartın bilgisayarla ve başka cihazlarla veri alışverişi yapmasını sağlar.

KomutSöz dizimiNe işe yarar?Örnek sonuç
mapmap(x, eskiAlt, eskiÜst, yeniAlt, yeniÜst)Bir aralığı başka bir aralığa ölçeklermap(512, 0, 1023, 0, 255) → 127
constrainconstrain(x, alt, üst)Değeri iki sınır arasında tutarconstrain(300, 0, 255) → 255
min / maxmin(a, b) / max(a, b)Küçük ya da büyük olanı verirmin(7, 3) → 3
absabs(x)Mutlak değerabs(-12) → 12
pow / sqrt / sqpow(taban, üs), sqrt(x), sq(x)Üs alma, karekök, karepow(2, 10) → 1024.0
randomrandom(min, max)Rastgele tam sayı (max dahil değil)random(1, 7) → 1 ile 6 arası
randomSeedrandomSeed(tohum)Rastgele dizinin başlangıcını değiştirirrandomSeed(analogRead(A3));
KomutNe işe yarar?Örnek
Serial.begin(hız)Seri portu verilen baud hızında açarSerial.begin(9600);
Serial.print(veri)Veriyi yazar, aynı satırda kalırSerial.print(sicaklik);
Serial.println(veri)Veriyi yazar ve alt satıra geçerSerial.println("Merhaba");
Serial.available()Okunmayı bekleyen bayt sayısını veririf (Serial.available() > 0)
Serial.read()Bir bayt okur, veri yoksa -1 döndürürchar c = Serial.read();
Serial.readStringUntil(k)Belirli bir karaktere kadar metin okurString s = Serial.readStringUntil('\n');
Serial.parseInt()Gelen metinden tam sayı ayıklarint n = Serial.parseInt();
Serial.write(bayt)Ham bayt gönderirSerial.write(65); // 'A'
Wire.begin()I2C hattını başlatır (Wire.h)Wire.begin();
SPI.begin()SPI hattını başlatır (SPI.h)SPI.begin();

pinMode(): pinin görevini belirlemek

pinMode(pin, mod) bir dijital pinin giriş mi çıkış mı olacağını söyler ve genellikle setup() içinde bir kez yazılır. Üç mod vardır: OUTPUT pini çıkış yapar (LED, buzzer ya da röle sürmek için), INPUT pini yüksek empedanslı giriş yapar (dışarıda pull-up ya da pull-down direnci olan devreler için), INPUT_PULLUP ise pini giriş yapıp içerideki yaklaşık 20–50 kΩ'luk direnci 5 V'a bağlar. Analog pinler (A0–A5) de pinMode ile dijital pin gibi kullanılabilir; örneğin pinMode(A0, OUTPUT) geçerli bir komuttur.

pinMode(pin, OUTPUT) yazmayı unutup digitalWrite(pin, HIGH) kullanırsan pin çıkış olmaz; Uno'da bu komut yalnızca dahili pull-up direncini açar. Sonuçta LED yanar ama çok sönük görünür, çünkü akım 20–50 kΩ'luk dirençten geçmek zorunda kalır. LED'in sönük yanıyorsa ilk bakacağın yer setup() içindeki pinMode satırıdır.

digitalWrite() ve digitalRead(): dijital çıkış ve giriş

digitalWrite(pin, HIGH) çıkış pinini Uno'da 5 V'a, digitalWrite(pin, LOW) ise 0 V'a çeker. Bir pinden en fazla 20 mA çekmek güvenlidir (mutlak sınır 40 mA); LED'i her zaman bir dirençle bağla, uygun değeri LED direnci hesaplama aracıyla bulabilirsin. digitalRead(pin) ise pindeki gerilime bakar ve HIGH ya da LOW döndürür; Uno'da yaklaşık 3 V üzeri HIGH, 1,5 V altı LOW sayılır. Aşağıdaki örnekte D2'ye bağlı butona basıldığında dahili LED yanar:

Arduino (C++)
1const int BUTON_PIN = 2;   // buton: bir ucu D2, diğer ucu GND / button: one leg to D2, the other to GND
2const int LED_PIN = 13;    // dahili LED / built-in LED
3
4void setup() {
5  pinMode(BUTON_PIN, INPUT_PULLUP);   // dahili pull-up direnci açık / internal pull-up resistor enabled
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  int durum = digitalRead(BUTON_PIN); // HIGH ya da LOW döner / returns HIGH or LOW
11  if (durum == LOW) {                 // pull-up ile basılı = LOW / with pull-up, pressed = LOW
12    digitalWrite(LED_PIN, HIGH);
13  } else {
14    digitalWrite(LED_PIN, LOW);
15  }
16}

INPUT_PULLUP kullandığında mantık terstir: buton serbestken pin içerideki direnç sayesinde HIGH okunur, basıldığında GND'ye bağlandığı için LOW okunur. Butonu dirençsiz ve INPUT modunda bağlarsan pin havada kalır ve digitalRead() rastgele değerler döndürür; elini yaklaştırman bile sonucu değiştirebilir. Butonun zıplaması (bounce) ve doğru bağlantı şekilleri için Arduino'ya buton nasıl bağlanır? yazısına bakabilirsin.

analogRead() ve analogWrite(): analog okuma ve PWM

analogRead(pin), A0–A5 pinlerindeki 0–5 V arası gerilimi 10 bitlik dönüştürücüyle (ADC) 0–1023 arası bir sayıya çevirir. Bir okuma yaklaşık 100 µs sürer, yani saniyede yaklaşık 10.000 ölçüm yapılabilir. Okunan sayıyı gerilime çevirmek için değer × 5,0 / 1023 formülü kullanılır; örneğin 512 okuması yaklaşık 2,5 V demektir. Referans gerilimi analogReference() ile değiştirilebilir: INTERNAL seçeneği Uno'da 1,1 V'luk iç referansı kullanır ve küçük gerilimlerde hassasiyeti artırır. Çözünürlük ve referans konusunun ayrıntıları ADC ve analog-dijital dönüşüm yazısında.

analogWrite(pin, değer) adına rağmen gerçek bir analog gerilim üretmez. Pini çok hızlı açıp kapatarak PWM sinyali üretir: 0 her zaman kapalı, 255 her zaman açık, 127 ise yaklaşık yarı yarıya açık demektir. LED'in gözümüze yarı parlak görünmesi ve motorun yavaş dönmesi bu ortalamadan gelir. Uno'da yalnızca kartın üzerinde ~ işareti olan 3, 5, 6, 9, 10 ve 11 numaralı pinler PWM verir; frekans çoğu pinde 490 Hz, 5 ve 6 numaralı pinlerde 980 Hz'dir. analogWrite() pini kendisi çıkış yaptığı için pinMode zorunlu değildir. Aşağıdaki kod potansiyometreyle LED parlaklığını ayarlar ve okunan değeri gerilimle birlikte Seri Monitör'e yazar; duty cycle ve frekansın ayrıntıları PWM nedir? yazısında.

Arduino (C++)
1const int POT_PIN = A0;   // potansiyometrenin orta bacağı / potentiometer wiper
2const int LED_PIN = 9;    // ~9 PWM pini + 220 ohm direnç / ~9 PWM pin + 220 ohm resistor
3
4void setup() {
5  Serial.begin(9600);
6}
7
8void loop() {
9  int ham = analogRead(POT_PIN);         // 0-1023 arası / between 0 and 1023
10  float volt = ham * (5.0 / 1023.0);     // sayıyı gerilime çevir / convert the reading to volts
11  analogWrite(LED_PIN, ham / 4);         // 0-1023 -> 0-255 PWM parlaklığı / 0-1023 -> 0-255 PWM brightness
12
13  Serial.print(F("Ham / raw: "));
14  Serial.print(ham);
15  Serial.print(F("  Gerilim / voltage: "));
16  Serial.print(volt, 2);                 // 2 ondalık basamak / 2 decimal places
17  Serial.println(F(" V"));
18  delay(200);
19}
PWM olmayan bir pinde analogWrite() ara değer üretemez: 128'in altındaki değerlerde pini LOW, 128 ve üzerinde HIGH yapar. Uno'nun A0–A5 pinleri de PWM vermez ve klasik Uno R3'te gerçek analog çıkış (DAC) yoktur; analogWrite(A0, 100) yazmak 2 V üretmez. Gerçek analog gerilim gerekiyorsa DAC'lı bir kart (örneğin A0'ında DAC bulunan Uno R4) ya da PWM çıkışına eklenen bir RC filtre kullanılır.

delay(), millis() ve micros(): zaman komutları

delay(ms) verilen milisaniye kadar bekler ve bu sürede loop() içindeki hiçbir satır çalışmaz; delay(1000) bir saniyelik tam bir duraklamadır. Mikrosaniye düzeyindeki kısa beklemeler için delayMicroseconds() vardır ve 3 ile 16383 µs arasında doğru sonuç verir. millis() ise beklemez; kart açıldığından beri geçen süreyi milisaniye olarak döndürür. Sonucu her zaman unsigned long türünde bir değişkende saklamalısın: int kullanırsan Uno'da değer 32.767'yi geçtiği anda, yani yaklaşık 33 saniye sonra taşar ve zamanlamalar bozulur. millis() yaklaşık 49,7 günde bir sıfıra döner; aşağıdaki çıkarma yöntemi bu taşmada bile doğru çalışır.

Arduino (C++)
1const int LED_PIN = 13;
2const unsigned long ARALIK = 500;   // yanıp sönme aralığı (ms) / blink interval (ms)
3unsigned long oncekiZaman = 0;      // son değişim anı / time of the last toggle
4
5void setup() {
6  pinMode(LED_PIN, OUTPUT);
7}
8
9void loop() {
10  unsigned long simdi = millis();
11  if (simdi - oncekiZaman >= ARALIK) {               // taşmada da doğru çalışır / safe across overflow
12    oncekiZaman = simdi;
13    digitalWrite(LED_PIN, !digitalRead(LED_PIN));    // LED'i tersine çevir / toggle the LED
14  }
15  // Burada buton, sensör ve ekran işleri de yapılabilir / button, sensor and display tasks can run here
16}

Bu desende loop() hiç durmaz; LED yanıp sönmeye devam ederken aynı döngüde buton okuyabilir, sensör ölçebilir ve ekranı güncelleyebilirsin. micros() aynı mantıkla mikrosaniye verir; Uno'da 4 µs adımlarla ilerler ve yaklaşık 70 dakikada taşar. Birden fazla işi aynı anda yürütmenin bütün ayrıntılarını Arduino millis() ve delay() yazısında anlattık.

Serial.begin(), Serial.print() ve Serial.read(): seri haberleşme

Serial komutları Arduino'nun USB kablosu üzerinden bilgisayarla konuşmasını sağlar ve hata ayıklamanın en önemli aracıdır. Serial.begin(9600) seri portu saniyede 9600 bit hızında açar; Seri Monitör'deki hız bu değerle aynı olmazsa ekranda anlamsız karakterler görürsün. Serial.print() veriyi yazar ve aynı satırda kalır, Serial.println() ise yazdıktan sonra alt satıra geçer. İkinci parametreyle biçim seçebilirsin: Serial.print(78, HEX) ekrana "4E", Serial.print(78, BIN) "1001110" yazar; Serial.print(3.14159, 3) ise "3.142" gösterir (ondalık sayılarda varsayılan 2 basamaktır). Sabit metinleri F("...") içine yazmak, Uno'nun 2 KB'lık RAM'inden tasarruf sağlar.

Veri okumak için önce Serial.available() ile tamponda bekleyen bayt olup olmadığına bakılır; Uno'nun gelen veri tamponu 64 bayttır. Serial.read() bu tampondan tek bir bayt alır, okunacak veri yoksa -1 döndürür. Aşağıdaki kod, Seri Monitör'den gönderdiğin 1 ve 0 karakterleriyle LED'i açıp kapatır:

Arduino (C++)
1const int LED_PIN = 13;
2
3void setup() {
4  Serial.begin(9600);                    // Seri Monitör de 9600 olmalı / Serial Monitor must be 9600 too
5  pinMode(LED_PIN, OUTPUT);
6  Serial.println(F("1: LED açık / on, 0: LED kapalı / off"));
7}
8
9void loop() {
10  if (Serial.available() > 0) {          // tamponda bayt var mı? / any bytes waiting?
11    char c = Serial.read();              // ilk baytı al / read the first byte
12    if (c == '1') {                      // '1' karakteri, 1 sayısı değil / the character '1', not the number 1
13      digitalWrite(LED_PIN, HIGH);
14      Serial.println(F("LED açık / on"));
15    } else if (c == '0') {
16      digitalWrite(LED_PIN, LOW);
17      Serial.println(F("LED kapalı / off"));
18    }
19    // '\n' ve '\r' gibi diğer karakterler atlanır / other characters such as '\n' and '\r' are ignored
20  }
21}

Burada karşılaştırmanın '1' (tek tırnak, yani karakter) ile yapıldığına dikkat et: klavyeden gönderilen 1, ASCII tablosunda 49 sayısına karşılık gelir, bu yüzden c == 1 koşulu hiçbir zaman doğru olmaz. Birden fazla basamaklı sayılar için Serial.parseInt(), bütün satırı almak için Serial.readStringUntil('\n') kullanabilirsin. Seri Monitör'ün satır sonu ayarları, baud hızı ve grafik çizici için Arduino Serial Monitor kullanımı yazısına bak.

map() ve constrain(): değerleri ölçeklemek ve sınırlamak

map(değer, eskiAlt, eskiÜst, yeniAlt, yeniÜst) bir sayıyı bir aralıktan diğerine orantılı olarak taşır. Arka plandaki formül şudur: (x − eskiAlt) × (yeniÜst − yeniAlt) / (eskiÜst − eskiAlt) + yeniAlt. Örneğin map(512, 0, 1023, 0, 255) sonucu 127,6 değil 127'dir, çünkü map() yalnızca tam sayılarla çalışır ve küsuratı atar. Aralıkları ters yazarak ters orantı da kurabilirsin: map(x, 0, 1023, 255, 0). map() sonucu sınırlamaz; giriş verdiğin aralığın dışına çıkarsa çıkış da dışarı taşar. Bu yüzden çoğu zaman constrain(x, alt, üst) ile birlikte kullanılır.

Arduino (C++)
1const int LDR_PIN = A0;   // LDR + 10k gerilim bölücü / LDR + 10k voltage divider
2const int LED_PIN = 9;    // ~9 PWM pini / ~9 PWM pin
3
4void setup() {
5  pinMode(LED_PIN, OUTPUT);
6}
7
8void loop() {
9  int isik = analogRead(LDR_PIN);           // odada ölçülen aralık ~200-800 / measured range in the room ~200-800
10  int pwm = map(isik, 200, 800, 255, 0);    // karanlıkta parlak, aydınlıkta sönük / bright in the dark, dim in the light
11  pwm = constrain(pwm, 0, 255);             // aralık dışı değerleri kes / clip out-of-range values
12  analogWrite(LED_PIN, pwm);
13  delay(20);
14}

Bu örnekte LDR odada 200 ile 800 arası değerler veriyor. Gece değer 100'e düşerse map() 297 hesaplar; constrain() olmasaydı analogWrite() 0–255 aralığının dışındaki bu değeri alırdı. Uno'da böyle bir değer pine göre farklı ve beklenmedik sonuç verir: örneğin 8 bitlik zamanlayıcı kullanan 3, 5, 6 ve 11 numaralı pinlerde 297 taşarak 41 gibi davranır ve LED tam karanlıkta parlamak yerine neredeyse söner. constrain(), min(), max() ve abs() Uno'da makro olarak tanımlandığı için parantez içine x++ ya da başka bir fonksiyon çağrısı yazma; ifade birden fazla kez hesaplanabilir ve beklenmedik sonuç verir. LDR bağlantısı için LDR ışık sensörü yazısına bakabilirsin.

tone() ve noTone(): buzzer ile ses üretmek

tone(pin, frekans, süre) bir pinde %50 doluluk oranlı kare dalga üretir ve pasif buzzer ya da küçük bir hoparlörden o frekansta ses çıkarır. Süre milisaniye cinsindendir ve isteğe bağlıdır; verilmezse ses noTone(pin) çağrılana kadar sürer. Önemli bir ayrıntı: tone() beklemez, sesi başlatıp hemen sonraki satıra geçer. Bu yüzden ardışık notalar çalarken her tone() çağrısının arkasına en az nota süresi kadar delay() koyman gerekir, yoksa yalnızca son notayı duyarsın.

Arduino (C++)
1const int BUZZER_PIN = 8;   // pasif buzzer'ın + ucu / passive buzzer + leg
2
3void setup() {
4  int notalar[] = {262, 294, 330, 349, 392};   // Do Re Mi Fa Sol (Hz) / C D E F G (Hz)
5  for (int i = 0; i < 5; i++) {
6    tone(BUZZER_PIN, notalar[i], 200);         // 200 ms çal / play for 200 ms
7    delay(250);                                // tone() beklemez, sen bekle / tone() does not wait, so you do
8  }
9  noTone(BUZZER_PIN);                          // sesi kapat / stop the sound
10}
11
12void loop() {
13}
  • Frekans sınırları: Uno'da 31 Hz'in altında ton üretilemez, üst sınır 65.535 Hz'dir; buzzer ile anlamlı aralık yaklaşık 100–5000 Hz'dir.
  • Tek ses: Aynı anda yalnızca bir pinde ton çalınır; başka bir pinde ses çıkarmak için önce noTone() ile öncekini durdurmalısın.
  • PWM çakışması: Uno'da tone() Timer2'yi kullanır; ses çalarken 3 ve 11 numaralı pinlerdeki analogWrite() bozulur.
  • Aktif buzzer: Kendi osilatörü olduğu için frekansı tone() ile değiştirilemez; aktif buzzer'ı digitalWrite() ile açıp kapatman yeterlidir. Farklar için Buzzer nedir? yazısına bak.

pulseIn(): darbe süresini ölçmek

pulseIn(pin, HIGH) pinin HIGH olmasını bekler, HIGH kaldığı süreyi ölçer ve sonucu mikrosaniye olarak döndürür; 10 µs ile 3 dakika arasındaki darbeleri ölçebilir. En bilinen kullanımı HC-SR04 ultrasonik mesafe sensörüdür: sensör, sesin gidip dönme süresi kadar uzun bir darbe verir. Ses havada yaklaşık 343 m/s, yani 0,0343 cm/µs hızla ilerler; yol gidiş-dönüş olduğu için mesafe = süre × 0,0343 / 2 formülüyle bulunur.

Arduino (C++)
1const int TRIG_PIN = 9;
2const int ECHO_PIN = 10;
3
4void setup() {
5  Serial.begin(9600);
6  pinMode(TRIG_PIN, OUTPUT);
7  pinMode(ECHO_PIN, INPUT);
8}
9
10void loop() {
11  digitalWrite(TRIG_PIN, LOW);
12  delayMicroseconds(2);
13  digitalWrite(TRIG_PIN, HIGH);            // 10 µs tetik darbesi / 10 µs trigger pulse
14  delayMicroseconds(10);
15  digitalWrite(TRIG_PIN, LOW);
16
17  unsigned long sure = pulseIn(ECHO_PIN, HIGH, 30000UL);   // en fazla 30 ms bekle / wait at most 30 ms
18  if (sure == 0) {
19    Serial.println(F("Menzil dışı / out of range"));
20  } else {
21    float mesafe = sure * 0.0343 / 2.0;    // ses hızı 343 m/s, gidiş-dönüş / speed of sound 343 m/s, round trip
22    Serial.print(mesafe, 1);
23    Serial.println(F(" cm"));
24  }
25  delay(100);
26}

Üçüncü parametre olan zaman aşımı çok önemlidir. Verilmezse pulseIn() darbe gelmediğinde 1 saniye bekler ve 0 döndürür; sensör kablosu çıktığında bütün program her döngüde bir saniye donar. 30000 µs'lik zaman aşımı yaklaşık 5 metreye karşılık gelir ve HC-SR04'ün 4 metrelik menzili için yeterlidir. Sensörün bağlantısı ve doğruluğu için HC-SR04 mesafe sensörü yazısına bakabilirsin.

attachInterrupt(): kesme ile anında tepki

attachInterrupt(digitalPinToInterrupt(pin), fonksiyon, mod) bir pinde değişiklik olduğu anda, loop() o sırada ne yapıyor olursa olsun verdiğin fonksiyonu çalıştırır. Bu fonksiyona kesme servis rutini (ISR) denir. Mod dört değer alabilir: RISING LOW'dan HIGH'a geçişte, FALLING HIGH'dan LOW'a geçişte, CHANGE her değişimde, LOW ise pin LOW kaldığı sürece tetikler. Uno ve Nano'da yalnızca D2 ve D3 pinleri bu şekilde kesme üretir; Mega'da 2, 3, 18, 19, 20 ve 21 numaralı pinler kullanılabilir. Hızlı dönen bir enkoderi, rüzgâr ölçerin darbelerini ya da çok kısa bir butona basışı kaçırmamak için idealdir.

Arduino (C++)
1const int BUTON_PIN = 2;            // Uno'da kesme pinleri: 2 ve 3 / interrupt pins on the Uno: 2 and 3
2volatile unsigned long sayac = 0;   // ISR'de değişen değişken volatile olmalı / variables changed in an ISR must be volatile
3
4void say() {                        // kesme fonksiyonu (ISR): kısa tut / interrupt service routine: keep it short
5  sayac++;
6}
7
8void setup() {
9  Serial.begin(9600);
10  pinMode(BUTON_PIN, INPUT_PULLUP);
11  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), say, FALLING);   // HIGH'dan LOW'a geçişte / on a HIGH-to-LOW edge
12}
13
14void loop() {
15  noInterrupts();                   // 4 baytlık değeri güvenle kopyala / copy the 4-byte value safely
16  unsigned long kopya = sayac;
17  interrupts();
18
19  Serial.print(F("Basma sayısı / presses: "));
20  Serial.println(kopya);
21  delay(500);
22}
ISR içinde değiştirdiğin her değişkeni volatile olarak tanımla ve fonksiyonu olabildiğince kısa tut. ISR içinde delay() çalışmaz, millis() ilerlemez ve Serial.print() programı kilitleyebilir; yalnızca bir bayrak ya da sayaç güncelle, asıl işi loop() içinde yap. Mekanik butonlar zıpladığı için tek basışta sayaç birkaç kez artabilir; zıplama çözümü ve kesmelerin ayrıntıları Arduino interrupt yazısında.

random() ve randomSeed(): rastgele sayı üretmek

random(max) 0 ile max−1 arasında, random(min, max) ise min ile max−1 arasında rastgele bir tam sayı döndürür; üst sınır sonuca dahil değildir. Bu yüzden 1–6 arası bir zar için random(1, 7) yazılır. Arduino gerçek rastgelelik üretmez, sabit bir formülle sayı dizisi hesaplar; randomSeed() çağırmazsan kart her açıldığında aynı sırayla aynı sayıları görürsün. Boşta bırakılmış bir analog pinin gürültüsünü tohum olarak kullanmak bu sorunu pratikte çözer:

Arduino (C++)
1void setup() {
2  Serial.begin(9600);
3  randomSeed(analogRead(A3));     // boştaki A3 pininin gürültüsü / noise from the unconnected A3 pin
4}
5
6void loop() {
7  int zar = random(1, 7);         // 1-6 arası; üst sınır dahil değil / 1 to 6; the upper bound is exclusive
8  Serial.print(F("Zar / dice: "));
9  Serial.println(zar);
10  delay(1000);
11}

ESP32'de Arduino komutları: nelere dikkat etmelisin?

ESP32, Arduino IDE'de aynı komutlarla programlanır ve bu yazıdaki kodların çoğu pin numaraları değiştirildiğinde doğrudan çalışır. Ama donanım farklı olduğu için bazı komutlar farklı davranır. En önemli fark gerilimdir: ESP32 pinleri 3,3 V ile çalışır, digitalWrite(pin, HIGH) 3,3 V verir ve 5 V'luk sinyaller pinlere doğrudan bağlanmamalıdır. Kartı yakından tanımak için ESP32 nedir? yazısına bakabilirsin.

KomutArduino UnoESP32
digitalWrite(pin, HIGH)5 V3,3 V
analogRead()10 bit, 0–1023, A0–A512 bit, 0–4095; Wi-Fi açıkken yalnızca ADC1 pinleri (GPIO 32–39)
analogWrite()Yalnızca ~ pinleri (3, 5, 6, 9, 10, 11), 490/980 HzÇıkış verebilen hemen her GPIO; frekans için ledcAttach(pin, frekans, çözünürlük)
attachInterrupt()Yalnızca D2 ve D3Bütün GPIO'lar; ISR'ye IRAM_ATTR eklenir
tone()Timer2 kullanır, 3 ve 11'deki PWM'i bozarLEDC donanımıyla çalışır
Serial.begin()Genellikle 9600Genellikle 115200 (açılış mesajları da bu hızda)
delay()İşlemciyi tamamen bekletirSüreyi FreeRTOS'a bırakır; Wi-Fi arka planda çalışmaya devam eder
Arduino (C++)
1const int POT_PIN = 34;     // ADC1 pini, Wi-Fi açıkken de okur / ADC1 pin, works with Wi-Fi on
2const int LED_PIN = 2;      // çoğu DevKit'te dahili LED / onboard LED on most DevKits
3const int BUTON_PIN = 4;    // butonun diğer ucu GND / other button leg to GND
4
5volatile bool basildi = false;
6
7void IRAM_ATTR butonISR() { // ESP32'de ISR IRAM'e yerleşmeli / on the ESP32 the ISR should live in IRAM
8  basildi = true;
9}
10
11void setup() {
12  Serial.begin(115200);
13  pinMode(BUTON_PIN, INPUT_PULLUP);
14  attachInterrupt(digitalPinToInterrupt(BUTON_PIN), butonISR, FALLING);   // her GPIO kesme destekler / every GPIO supports interrupts
15}
16
17void loop() {
18  int ham = analogRead(POT_PIN);                     // 0-4095 (12 bit)
19  analogWrite(LED_PIN, map(ham, 0, 4095, 0, 255));   // 8 bit PWM / 8-bit PWM
20  if (basildi) {
21    basildi = false;
22    Serial.println("Butona basıldı / button pressed");
23  }
24  Serial.println(ham);
25  delay(200);
26}

ESP32'de analogRead() 0–4095 arası değer verdiği için map() aralığı da buna göre değişir. ISR fonksiyonunun başındaki IRAM_ATTR, kodun hızlı dahili belleğe yerleşmesini sağlar; eksik olursa bazı durumlarda kart "Guru Meditation Error" ile yeniden başlayabilir. ESP32'nin analog okumaları uçlara yakın bölgelerde (0 V ve 3,3 V civarında) doğrusal değildir; daha doğru bir ölçüm gerekiyorsa analogReadMilliVolts() fonksiyonu kalibre edilmiş milivolt değeri döndürür.

Raspberry Pi Pico: Arduino komutlarının MicroPython karşılıkları

Raspberry Pi Pico'yu Arduino IDE ile (arduino-pico çekirdeği) programlarsan bu yazıdaki komutların hepsi aynı isimlerle çalışır; analogRead() varsayılan olarak 10 bit döndürür ve analogWrite() 1 kHz PWM üretir. Ancak Pico çoğunlukla MicroPython ile kullanılır. Orada komutlar machine ve time modüllerindeki nesnelerle yazılır; mantık aynıdır, yalnızca söz dizimi değişir. Pico'nun pinleri de 3,3 V'tur ve analog girişleri GP26, GP27 ve GP28 pinleridir. Başlangıç için Raspberry Pi Pico nedir? yazısına bakabilirsin.

Arduino komutuMicroPython karşılığıNot
pinMode(15, OUTPUT)led = Pin(15, Pin.OUT)Pin nesnesi bir kez oluşturulur
pinMode(14, INPUT_PULLUP)btn = Pin(14, Pin.IN, Pin.PULL_UP)Dahili pull-up direnci
digitalWrite(15, HIGH)led.value(1)led.on() da olur
digitalRead(14)btn.value()0 ya da 1 döndürür
analogRead(A0)ADC(26).read_u16()0–65535 arası döndürür
analogWrite(15, 128)PWM(Pin(15)).duty_u16(32768)Doluluk 0–65535 arası
delay(500)time.sleep_ms(500)time.sleep(0.5) de olur
millis()time.ticks_ms()Fark için time.ticks_diff()
Serial.println(x)print(x)Thonny kabuğunda görünür
tone(pin, 440)pwm.freq(440) ve pwm.duty_u16(32768)Susturmak için duty_u16(0)
pulseIn(pin, HIGH, 30000)machine.time_pulse_us(pin, 1, 30000)Zaman aşımında negatif değer döner
attachInterrupt(...)btn.irq(trigger=Pin.IRQ_FALLING, handler=f)f, pin nesnesini parametre olarak alır
random(1, 7)random.randint(1, 6)Üst sınır dahildir
map() / constrain()Hazır değil, kendin yazarsınconstrain için min(max(x, 0), 255)
MicroPython
1from machine import Pin, ADC, PWM
2import time
3
4led = PWM(Pin(15))                       # pinMode + analogWrite karşılığı / pinMode + analogWrite equivalent
5led.freq(1000)                           # 1 kHz PWM
6buton = Pin(14, Pin.IN, Pin.PULL_UP)     # INPUT_PULLUP karşılığı / INPUT_PULLUP equivalent
7pot = ADC(26)                            # GP26 = ADC0
8
9def map_deger(x, giris_min, giris_max, cikis_min, cikis_max):   # Arduino map() karşılığı / Arduino map() equivalent
10    return (x - giris_min) * (cikis_max - cikis_min) // (giris_max - giris_min) + cikis_min
11
12onceki = time.ticks_ms()                 # millis() karşılığı / millis() equivalent
13while True:
14    ham = pot.read_u16()                 # 0-65535 (analogRead)
15    led.duty_u16(ham)                    # parlaklık / brightness (analogWrite)
16    if buton.value() == 0:               # digitalRead; basılı = 0 / pressed = 0
17        print("Butona basıldı / button pressed")
18    if time.ticks_diff(time.ticks_ms(), onceki) >= 1000:   # saniyede bir / once a second
19        onceki = time.ticks_ms()
20        print("Yüzde / percent:", map_deger(ham, 0, 65535, 0, 100))
21    time.sleep_ms(50)                    # delay(50)

Tabloda gördüğün gibi MicroPython'daki random.randint(1, 6) üst sınırı da kapsar ve Arduino'daki random(1, 7) ile aynı sonucu verir; time.ticks_diff() de millis() çıkarmasındaki taşma güvenliğini sağlar. Bu küçük farklar iki platform arasında geçiş yaparken en sık kafa karıştıran noktalardır. MicroPython'ın diğer temel komutları için MicroPython temelleri yazısına göz atabilirsin.

Bu komutlarla yapabileceğin proje fikirleri

  • Trafik lambası: pinMode(), digitalWrite() ve delay() ile üç LED'i sırayla yak; Arduino trafik lambası yazısında adım adım anlattık.
  • Dijital zar: random() ile 1–6 arası sayı üret, butona basınca sonucu LED'lerle ya da bir 7 segment display üzerinde göster.
  • Park sensörü: pulseIn() ile mesafeyi ölç, map() ile bip aralığına çevir ve tone() ile uyarı sesi çıkar.
  • Otomatik gece lambası: analogRead() ile ışığı oku, map() ve constrain() ile analogWrite() parlaklığını ayarla.
  • Seri port kumandası: Serial.read() ile bilgisayardan gelen komutlarla LED, röle ya da servo motor kontrol et.
  • Reaksiyon testi: random() ile rastgele bir anda LED yak, attachInterrupt() ve millis() ile butona basma süreni milisaniye hassasiyetle ölç.

Sık yapılan hatalar ve çözümleri

HataBelirtiÇözüm
pinMode() unutulmuşLED çok sönük yanıyor ya da hiç yanmıyorsetup() içinde pinMode(pin, OUTPUT) yaz
Buton dirençsiz ve INPUT modundadigitalRead() rastgele 0 ve 1 veriyorINPUT_PULLUP kullan; basılı durum LOW olur
Komut adında harf hatası'digitalwrite' was not declared in this scopeBüyük-küçük harfe dikkat et: digitalWrite
Baud hızı uyuşmuyorSeri Monitör'de anlamsız karakterlerSerial.begin() ile Seri Monitör hızını eşitle
PWM olmayan pinde analogWrite()LED yalnızca tam açık ya da kapalı~ işaretli pin kullan (3, 5, 6, 9, 10, 11)
millis() sonucu int değişkendeZamanlama yaklaşık 33 saniye sonra bozuluyorunsigned long kullan
random(1, 6) ile zar6 hiç gelmiyorrandom(1, 7) yaz; üst sınır dahil değil
map() ile ondalık sonuç beklemekSonuç hep tam sayı, küçük değişimler kayboluyorGerekirse float ile kendi formülünü yaz
pulseIn() zaman aşımı olmadanSensör yokken her döngü 1 saniye donuyorÜçüncü parametre olarak 30000 ver
ISR içinde delay() ya da SerialProgram kilitleniyor ya da tuhaf davranıyorISR'de yalnızca volatile bir bayrak değiştir
Bir komutun tam olarak ne yaptığından emin değilsen küçük bir deneme kodu yaz ve sonucu Serial.println() ile ekrana bas; Arduino IDE 2'de komutun adına sağ tıklayıp "Tanıma Git" seçeneğiyle kaynak koduna da bakabilirsin. Kod derlenmiyorsa hata mesajının ilk satırı genellikle sorunun yerini gösterir; en yaygın mesajlar ve çözümleri Arduino derleme hataları yazısında.

Bu yazıdaki komutlar, Arduino ile yapacağın projelerin büyük çoğunluğunun yapı taşıdır; geri kalanı çoğunlukla kütüphanelerin sunduğu ek fonksiyonlardır. Her komutu kendi küçük devresinde bir kez deneyip sonucunu Seri Monitör'de görmek, onları ezberlemekten çok daha kalıcı bir öğrenme sağlar. BlueGrays uygulamasında LED yakma, butonla LED kontrolü, LDR ile ışık ölçme, buzzer ile frekans ayarı, HC-SR04 ile mesafe ölçme ve zar projesi gibi bu komutları kullanan projeleri devre şemaları ve açıklamalı kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

Arduino'da en çok kullanılan komutlar nelerdir?

En sık kullanılanlar pinMode(), digitalWrite(), digitalRead(), analogRead(), analogWrite(), delay(), millis(), Serial.begin() ve Serial.println() komutlarıdır. Bunlara değer ölçeklemek için map(), ses için tone(), mesafe sensörleri için pulseIn() ve kesmeler için attachInterrupt() eklenince yeni başlayan projelerinin neredeyse tamamını yazabilirsin.

Arduino komutları hangi dilde yazılır?

Arduino kodu C ve C++ dilinin üzerine kurulmuştur; Arduino çekirdeği bu dile pinMode() ve digitalWrite() gibi hazır fonksiyonlar ekler. Komutlar İngilizcedir, büyük-küçük harfe duyarlıdır ve her ifade noktalı virgülle biter. ESP32 ve Raspberry Pi Pico istersen MicroPython ile de programlanabilir.

digitalWrite ile analogWrite arasındaki fark nedir?

digitalWrite() pini yalnızca iki durumdan birine getirir: HIGH (Uno'da 5 V) ya da LOW (0 V). analogWrite() ise pini çok hızlı açıp kapatarak 0–255 arası bir PWM sinyali üretir; böylece LED'in parlaklığı ya da motorun hızı ayarlanabilir. Uno'da analogWrite() yalnızca ~ işaretli pinlerde çalışır.

void setup ve void loop ne demek?

setup(), kart açıldığında ya da resetlendiğinde bir kez çalışan fonksiyondur; pinMode() ve Serial.begin() gibi hazırlıklar buraya yazılır. loop() ise setup() bittikten sonra sonsuza kadar tekrar eden fonksiyondur. Başlarındaki void, bu fonksiyonların geriye bir değer döndürmediğini belirtir.

Serial.print ile Serial.println arasındaki fark nedir?

Serial.print() veriyi yazar ve imleci aynı satırda bırakır, böylece sonraki veri yanına eklenir. Serial.println() ise yazdıktan sonra satır sonu karakterlerini (\r\n) gönderir ve sonraki veri alt satırdan başlar. Bir satırda birkaç değeri yan yana göstermek için önce print(), en sonda println() kullanılır.

Arduino map fonksiyonu ne işe yarar?

map(), bir aralıktaki sayıyı başka bir aralığa orantılı olarak çevirir; örneğin analogRead() ile okunan 0–1023 değerini analogWrite() için 0–255 aralığına ya da servo için 0–180 dereceye dönüştürür. Yalnızca tam sayılarla çalışır ve sonucu sınırlamaz, bu yüzden aralık dışı girişlere karşı constrain() ile birlikte kullanılması önerilir.

Tüm projeleri gör
Led Yakma
#1Başlangıç

Led Yakma

Arduino ile tek bir LED'i belirli aralıklarla yakıp söndüren temel giriş projesi. digitalWrite ve delay fonksiyonlarının kullanımını öğretir.

4.6(170)
901
Buton İle Led Yakma (Push)
#9Başlangıç

Buton İle Led Yakma (Push)

Butona basıldığında LED'i yakan, bırakıldığında söndüren anlık (push) kontrol projesi. digitalRead ile buton okuma ve koşullu ifade kullanımını öğretir.

4.9(112)
190
Ldr İle Işık Şiddeti Okuma
#11Başlangıç

Ldr İle Işık Şiddeti Okuma

LDR sensörü ile ortam ışık şiddetini ölçüp Serial Monitor'da gösteren proje. Analog sensör okuma ve seri haberleşme temellerini öğretir.

4.6(78)
124
Buzzer İle Frekans Ayarı
#14Orta

Buzzer İle Frekans Ayarı

4 buton ile buzzer'ın frekansını artırıp azaltabilen, açıp kapatabilen interaktif proje. Çoklu buton okuma ve değişken kontrolünü öğretir.

4.6(68)
112
HC-SR04 Mesafe Ölçme (Serial Ekran)
#27Başlangıç

HC-SR04 Mesafe Ölçme (Serial Ekran)

HC-SR04 ultrasonik sensör ile mesafe ölçüp sonucu Serial Monitor'da cm cinsinden gösteren proje. Ses dalgası ile mesafe hesaplama prensibini öğretir.

4.6(44)
66
Hız Ayarlı Karaşimşek Led
#8Orta

Hız Ayarlı Karaşimşek Led

Potansiyometre ile karaşimşek LED animasyonunun hızını gerçek zamanlı olarak ayarlayabilen proje. Analog giriş ve çift yönlü döngü kontrolünü birleştirir.

4.5(59)
115
Potansiyometre İle Servo Motor Kullanım
#36Başlangıç
Premium

Potansiyometre İle Servo Motor Kullanım

Potansiyometre değerini 0-180° aralığına dönüştürerek servo motoru gerçek zamanlı kontrol eden proje. map() fonksiyonu ve analog-servo entegrasyonunu öğretir.

4.6(37)
51
Zar Projesi
#79Orta
Premium

Zar Projesi

Butona her basışta 1–6 arasında rastgele bir sayı üretip 7 segment ekranda gösteren zar projesi. Debounce mekanizması sayesinde tek basışta tek sonuç üretilir.

5.0(48)
67