Rehberler · 10 dk okuma

Arduino Radar Projesi: HC-SR04, Servo ve Processing ile Yapımı

Arduino radar projesi adım adım: HC-SR04 ve SG90 servo bağlantısı, açı ve mesafe kodu, Processing ile yeşil tarama ekranı, OLED mini radar ve sık hatalar.

Arduino radar projesi, bir HC-SR04 ultrasonik mesafe sensörünü bir SG90 servo motorun üzerine yerleştirip 0 ile 180 derece arasında döndürerek çevredeki nesnelerin hem yönünü hem de uzaklığını ölçen ve sonucu bilgisayar ekranında filmlerdeki gibi yeşil bir tarama görüntüsüyle gösteren bir projedir. Arduino her açıda bir ölçüm yapar ve "açı,mesafe" biçimindeki satırı seri porttan gönderir; bilgisayarda çalışan küçük bir Processing programı da bu sayıları okuyup dönen tarama çizgisini ve algılanan nesneleri kırmızı çizgilerle çizer.

Bu rehberde malzeme listesinden bağlantı şemasına, Arduino kodundan Processing radar ekranına kadar her adımı açıklamalarıyla bulacaksın. Ayrıca bilgisayar gerektirmeyen OLED ekranlı mini radarı, ESP32 ve Raspberry Pi Pico uyarlamalarını, tarama hızını ve ölçüm doğruluğunu nasıl ayarlayacağını ve en sık karşılaşılan port hatalarının çözümünü de ele alıyoruz. Maliyeti düşük, bir öğleden sonrada bitirilebilen ve okulda sunulduğunda en çok ilgi çeken Arduino projelerinden biridir.

Arduino Uno
Arduino Uno
HC-SR04
HC-SR04
SG90 servo
SG90 servo
Breadboard
Breadboard

Arduino radar nasıl çalışır?

Sistemin kalbi HC-SR04'tür. Sensörün üzerindeki iki silindirden biri (T) insan kulağının duyamayacağı 40 kHz'lik kısa bir ses patlaması gönderir; ses bir nesneye çarpıp geri döndüğünde diğeri (R) yankıyı yakalar. Arduino bu gidiş-dönüş süresini mikrosaniye cinsinden ölçer. Ses havada yaklaşık 343 m/s hızla ilerler, yani bir santimetreyi yaklaşık 29 mikrosaniyede alır; yol hem gidiş hem dönüş olarak iki kez kat edildiği için formül mesafe (cm) = süre (µs) / 58 olur. Servo motor sensörü adım adım döndürür ve her adımda bu ölçüm tekrarlanır. Sonuçta elimizde "hangi açıda, kaç santimetrede bir şey var" bilgisi, yani kutupsal bir koordinat olur. Ekranda çizmek için açı ve mesafe x = mesafe × cos(açı) ve y = mesafe × sin(açı) formülleriyle piksel konumuna çevrilir.

ParçaGöreviÖnemli değerler
HC-SR04Ultrasonik mesafe ölçümü40 kHz, 2–400 cm, yaklaşık 15° ölçüm açısı, 5 V, 15 mA
SG90 servoSensörü 0–180° döndürür0,1 s/60° (4,8 V), 1,8 kg·cm tork, 4,8–6 V, 9 g
Arduino UnoÖlçer, servoyu sürer, veriyi gönderir16 MHz, 5 V mantık seviyesi, USB seri port
ProcessingBilgisayarda radar ekranını çizerÜcretsiz, Java tabanlı, Serial kütüphanesi dahil
OLED SSD1306 (isteğe bağlı)Bilgisayarsız mini radar ekranı128×64 piksel, I2C, adres 0x3C

Arduino radar malzeme listesi

  • Arduino Uno ya da Nano ve veri aktarabilen bir USB kablosu (yalnızca şarj eden kablolar bilgisayarda port göstermez).
  • HC-SR04 ultrasonik mesafe sensörü.
  • SG90 mikro servo motor ve kutusundan çıkan plastik kollar.
  • Breadboard ile 8–10 adet erkek-erkek ve erkek-dişi jumper kablo.
  • 470 µF (en az 10 V) elektrolitik kondansatör: servo hareket ederken gerilimin çökmesini engeller.
  • Sensörü servoya sabitlemek için çift taraflı bant, sıcak silikon ya da küçük bir 3D baskı tutucu.
  • İsteğe bağlı: 0,96 inç I2C OLED ekran (bilgisayarsız sürüm için) ve 5 V 2 A harici adaptör.

Arduino radar bağlantı şeması

BağlantıArduino UnoESP32Raspberry Pi Pico
HC-SR04 VCC5VVIN (5 V)VBUS (pin 40)
HC-SR04 GNDGNDGNDGND
HC-SR04 TrigD10GPIO 26GP14
HC-SR04 EchoD11GPIO 27 (bölücüyle)GP13 (bölücüyle)
SG90 kahverengi (GND)GNDGNDGND
SG90 kırmızı (+5 V)5VVIN (5 V)VBUS (pin 40)
SG90 turuncu (sinyal)D9GPIO 13GP15

Uno'da sensörün ve servonun 5 V ve GND uçlarını breadboard'un artı ve eksi hatlarına, bu hatları da Arduino'nun 5V ve GND pinlerine bağlamak kablolamayı sadeleştirir. 470 µF kondansatörü aynı hatlara, uzun bacağı (+) 5 V'a, gövdesinde şerit olan kısa bacağı GND'ye gelecek şekilde tak. Bazı servolarda kablo renkleri siyah, kırmızı ve beyazdır; bu durumda siyah GND, beyaz sinyaldir. Kartının pin yerlerinden emin olmak için pinout aracına bakabilirsin.

HC-SR04 5 V ile beslendiğinde Echo pini de 5 V'luk çıkış verir. Arduino Uno için bu sorun değildir, ama ESP32 ve Raspberry Pi Pico'nun pinleri 5 V'a dayanıklı değildir. Echo hattına 1 kΩ ve 2 kΩ'luk bir gerilim bölücü koy (Echo → 1 kΩ → GPIO, GPIO → 2 kΩ → GND); pindeki gerilim yaklaşık 3,3 V'a iner. Değerleri gerilim bölücü hesaplayıcısıyla kontrol edebilirsin.

Sensörü servoya monte etmek

SG90 mikro servo motor
SG90 servo: kahverengi GND, kırmızı +5 V, turuncu sinyal. HC-SR04 servonun plastik koluna yapıştırılır.

Kolu takmadan önce servoyu 90 dereceye getir: radarServo.write(90) yazan kısa bir deneme kodu yükleyip servoyu bu konumda bırakman yeterli. Ardından kolu, sensör tam karşıya bakacak şekilde tak. Böylece 0° sağı, 90° ileriyi, 180° solu gösterir ve Processing ekranındaki yönler gerçek dünyayla birebir eşleşir. HC-SR04'ü kola çift taraflı bant ya da sıcak silikonla yapıştırırken iki silindirin yere paralel durmasına dikkat et; sensör aşağı eğik kalırsa masanın yüzeyini nesne sanar. Kablolara 180 derecelik dönüşte gerilmeyecek kadar boşluk bırak ve servoyu ağır bir tabana ya da kutuya sabitle; her adımda sarsılan bir gövde ölçümleri bozar.

Adım adım Arduino radar yapımı

  1. Bileşenleri yukarıdaki tabloya göre bağla, kondansatörü takmayı unutma ve sensörü servoya monte et.
  2. Arduino IDE'yi aç; Servo kütüphanesi IDE ile birlikte gelir, ayrıca kurman gerekmez.
  3. Aşağıdaki radar kodunu yükle. Kart ya da port seçiminde sorun yaşarsan Arduino kod yüklenmiyor yazısına göz at.
  4. Seri Monitör'ü 9600 baud ile aç; "30,45" gibi açı ve mesafe satırları akıyorsa Arduino tarafı hazırdır. Ardından Seri Monitör'ü mutlaka kapat.
  5. Bilgisayarına Processing 4'ü kur, yeni bir çizim (sketch) aç ve radar ekranı kodunu yapıştır.
  6. Run düğmesine bas; alttaki konsolda port listesi görünür ve radar penceresi açılır. Elini sensörün önünde gezdirdiğinde kırmızı çizgiler belirmelidir.

Arduino radar kodu

Arduino (C++)
1#include <Servo.h>
2
3const byte SERVO_PIN  = 9;     // SG90 turuncu kablo / SG90 orange wire
4const byte TRIG_PIN   = 10;    // HC-SR04 Trig
5const byte ECHO_PIN   = 11;    // HC-SR04 Echo
6const int  MIN_ANGLE  = 0;     // tarama başlangıcı / sweep start
7const int  MAX_ANGLE  = 180;   // tarama sonu / sweep end
8const int  STEP       = 2;     // adım başına derece / degrees per step
9const int  STEP_DELAY = 40;    // ölçümden önce bekleme (ms) / wait before measuring (ms)
10
11Servo radarServo;
12int angle = MIN_ANGLE;
13int dir = STEP;
14
15int measureCm() {
16  digitalWrite(TRIG_PIN, LOW);
17  delayMicroseconds(2);
18  digitalWrite(TRIG_PIN, HIGH);                         // 10 µs tetik darbesi / 10 µs trigger pulse
19  delayMicroseconds(10);
20  digitalWrite(TRIG_PIN, LOW);
21  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);  // en çok 30 ms bekle / wait at most 30 ms
22  if (us == 0) return 0;                                // yankı yok = menzil dışı / no echo = out of range
23  return us / 58;                                       // gidiş-dönüş süresi → cm / round-trip time → cm
24}
25
26void setup() {
27  Serial.begin(9600);
28  pinMode(TRIG_PIN, OUTPUT);
29  pinMode(ECHO_PIN, INPUT);
30  radarServo.attach(SERVO_PIN);
31  radarServo.write(angle);
32  delay(500);                                           // başlangıç konumuna gitsin / reach the start position
33}
34
35void loop() {
36  radarServo.write(angle);                              // servoyu yeni açıya döndür / move the servo to the new angle
37  delay(STEP_DELAY);                                    // titreşim geçsin / let the vibration settle
38  int distance = measureCm();
39
40  Serial.print(angle);                                  // biçim: açı,mesafe / format: angle,distance
41  Serial.print(',');
42  Serial.println(distance);
43
44  if (angle + dir > MAX_ANGLE || angle + dir < MIN_ANGLE) dir = -dir;  // uçta yön değiştir / reverse at the ends
45  angle += dir;
46}

Kod açıklaması

Kod bölümüNe yapar?
STEP ve STEP_DELAYServonun her adımda kaç derece döneceğini ve ölçümden önce ne kadar bekleneceğini belirler; tarama hızını bu iki sabitle ayarlarsın.
measureCm()Trig pinine 10 µs'lik bir darbe verir, pulseIn ile Echo pininin HIGH kaldığı süreyi ölçer ve 58'e bölerek santimetreye çevirir.
pulseIn(..., 30000UL)En fazla 30 ms bekler, yankı gelmezse 0 döndürür. Bu zaman aşımı olmasaydı boş bir yöne bakarken fonksiyon 1 saniyeye kadar takılabilirdi.
radarServo.write(angle)Servoyu istenen açıya götürür; kütüphane 0–180 değerini 544–2400 µs'lik bir darbeye çevirir.
Serial.print ... printlnHer ölçümü "açı,mesafe" biçiminde tek satır olarak gönderir; satır sonu Processing'e "veri tamam" işareti verir.
dir = -dirAçı 180'e ya da 0'a ulaştığında yönü tersine çevirir; servo durmadan ileri geri tarar.

Gönderilen verinin bu kadar sade olmasının bir nedeni var: virgülle ayrılmış tek satır hem Seri Monitör'de rahatça okunur hem de Processing, Python ya da Excel gibi programlarda tek satır kodla ayrıştırılır. Mesafenin 0 gelmesi "bu açıda menzil içinde bir şey yok" anlamına gelir ve Processing bu değerleri çizmez. Aynı veriyi Arduino IDE'nin Seri Çizici (Serial Plotter) penceresinde açarsan açının testere dişi gibi inip çıktığını, mesafenin de bir nesnenin önünden geçerken sıçradığını görürsün. Bu proje için delay kullanmak yeterlidir; radar çalışırken aynı anda buton okumak ya da LED yakmak istersen döngüyü millis() ile yeniden yazabilirsin.

Servo tam 0° ya da 180°'de vızıldıyor ve titriyorsa mekanik sınırına dayanıyordur. Tarama aralığını 10–170° yap ya da servoyu radarServo.attach(SERVO_PIN, 500, 2400) ile başlatarak darbe aralığını kendi servona göre ayarla.

Processing ile yeşil radar ekranı

Processing, görsel programlama için geliştirilmiş ücretsiz ve Java tabanlı bir yazılımdır; arayüzü Arduino IDE'ye çok benzer: kodu yazar, Run düğmesine basarsın. Seri haberleşme için gereken Serial kütüphanesi Processing ile birlikte gelir; Sketch > Import Library menüsünden eklenebilir ya da kodun başındaki import satırı yeterlidir. Aşağıdaki kod Arduino IDE'ye değil, Processing'e yapıştırılır.

Arduino (C++)
1// Processing 4 çizimi: Arduino IDE'ye değil, Processing'e yapıştır / Processing 4 sketch: paste into Processing, not the Arduino IDE
2import processing.serial.*;                       // Serial kütüphanesi / Serial library
3
4Serial port;
5int angle = 0;                                    // son açı / last angle
6int distance = 0;                                 // son mesafe (cm) / last distance (cm)
7final int MAX_CM = 100;                           // ekrandaki en uzak mesafe / farthest distance on screen
8float R;                                          // radar yarıçapı (piksel) / radar radius (pixels)
9
10void setup() {
11  size(1200, 700);
12  R = width * 0.45;
13  printArray(Serial.list());                      // portları konsola yaz / print the ports to the console
14  String portName = Serial.list()[0];             // gerekirse [1] ya da "COM4" yaz / use [1] or "COM4" if needed
15  port = new Serial(this, portName, 9600);        // Arduino ile aynı baud / same baud as the Arduino
16  port.bufferUntil('\n');                         // satır sonunu bekle / wait for the end of a line
17  background(0);
18}
19
20void draw() {
21  noStroke();
22  fill(0, 12);                                    // yarı saydam siyah: solan iz / translucent black: fading trail
23  rect(0, 0, width, height);
24  translate(width / 2, height - 60);              // radar merkezi alt ortada / radar centre at the bottom middle
25  drawGrid();
26  drawSweep();
27  drawObject();
28  drawLabels();
29}
30
31void drawGrid() {
32  noFill();
33  strokeWeight(2);
34  stroke(98, 245, 31);
35  for (int i = 1; i <= 4; i++) {
36    float d = 2 * R * i / 4;
37    arc(0, 0, d, d, PI, TWO_PI);                  // 25-50-75-100 cm yayları / 25-50-75-100 cm arcs
38  }
39  for (int a = 0; a <= 180; a += 30) {
40    line(0, 0, R * cos(radians(a)), -R * sin(radians(a)));   // 30 derecelik çizgiler / 30-degree lines
41  }
42}
43
44void drawSweep() {
45  strokeWeight(5);
46  stroke(30, 250, 60);
47  line(0, 0, R * cos(radians(angle)), -R * sin(radians(angle)));   // tarama çizgisi / sweep line
48}
49
50void drawObject() {
51  if (distance <= 0 || distance > MAX_CM) return;  // menzil dışı / out of range
52  float p = R * distance / MAX_CM;                 // cm → piksel / cm → pixels
53  float c = cos(radians(angle));
54  float s = sin(radians(angle));
55  strokeWeight(7);
56  stroke(255, 10, 10);
57  line(p * c, -p * s, R * c, -R * s);              // nesneden dışa kırmızı çizgi / red line from the object outwards
58}
59
60void drawLabels() {
61  resetMatrix();
62  noStroke();
63  fill(0);
64  rect(0, height - 40, width, 40);                 // yazı şeridi / text strip
65  fill(98, 245, 31);
66  textSize(20);
67  for (int i = 1; i <= 4; i++) {
68    text(MAX_CM * i / 4 + " cm", width / 2 + R * i / 4 + 4, height - 66);   // yay etiketleri / arc labels
69  }
70  String d = (distance > 0 && distance <= MAX_CM) ? distance + " cm" : "-";
71  text("Açı / Angle: " + angle + "°", 40, height - 12);
72  text("Mesafe / Distance: " + d, width / 2, height - 12);
73}
74
75void serialEvent(Serial p) {
76  String msg = p.readStringUntil('\n');            // "açı,mesafe" satırı / "angle,distance" line
77  if (msg == null) return;
78  String[] parts = split(trim(msg), ',');
79  if (parts.length == 2) {
80    angle = int(parts[0]);
81    distance = int(parts[1]);
82  }
83}

Kodun en önemli kısmı serialEvent() fonksiyonudur. bufferUntil('\n') sayesinde Processing satır sonu gelene kadar veriyi biriktirir ve tam bir satır geldiğinde bu fonksiyonu kendiliğinden çağırır. Satır trim() ile boşluklardan ve \r karakterinden temizlenir, split() ile virgülden ikiye bölünür ve int() ile sayıya çevrilir. draw() ise saniyede yaklaşık 60 kez çalışır: önce ekranın üzerine yarı saydam siyah bir dikdörtgen çizer (fill(0, 12)), sonra ızgarayı, tarama çizgisini ve nesneyi yeniden çizer. Eski çizgiler her karede biraz daha karardığı için radarlardaki o iz bırakarak sönme etkisi kendiliğinden oluşur.

AyarNerede?Ne işe yarar?
MAX_CM = 100ProcessingEkranın kapsadığı en uzak mesafe; dış yay 100 cm'dir, içteki yaylar 25, 50 ve 75 cm'yi gösterir.
Serial.list()[0]ProcessingBilgisayardaki ilk seri portu seçer; Arduino'n başka sıradaysa indeksi değiştir ya da "COM4" gibi adı doğrudan yaz.
9600İkisinde deBaud hızı; Arduino'daki Serial.begin ile Processing'deki değer aynı olmalıdır.
fill(0, 12)ProcessingSolma hızı; 5 uzun bir iz, 30 neredeyse izsiz bir görüntü verir.
size(1200, 700)ProcessingPencere boyutu; ekranına sığmazsa küçült. Yarıçap genişliğe göre hesaplanır, yüksekliği genişliğin yarısından büyük tut.

Servo hızı ve tarama süresi ayarı

SG90'ın veri sayfasındaki hızı 4,8 V'ta 60 derece için 0,1 saniyedir; yani 2 derecelik bir adımı birkaç milisaniyede tamamlar. Tarama süresini asıl belirleyen servo değil, her adımdaki bekleme ve ölçüm süresidir. Servo durduktan sonra kol ve sensör kısa bir süre titrer; bu sırada ölçüm yapılırsa mesafeler zıplar. Ayrıca HC-SR04 üreticisi iki ölçüm arasında yaklaşık 60 ms bırakılmasını önerir, çünkü önceki darbenin odadaki yankıları sonraki ölçüme karışabilir. Pratikte adım başına toplam 50–60 ms (bekleme + ölçüm) iyi bir dengedir. Bir tam taramanın süresi kabaca (180 / adım + 1) × adım süresi formülüyle bulunur.

AdımSTEP_DELAYTek tarama (0→180°)Sonuç
1°20 msyaklaşık 7 sEn pürüzsüz görüntü ama yavaş; aynı nesne defalarca ölçülür.
2°40 msyaklaşık 5 sÖnerilen ayar: akıcı ve kararlı.
3°50 msyaklaşık 4 sDaha hızlı; sensörün 15°'lik huzmesi sayesinde nesne kaçmaz.
5°70 msyaklaşık 3,5 sEkran kesik görünür; büyük adımda titreşim arttığı için bekleme uzamalıdır.

Hareketi yumuşatmak için adımı küçük ve beklemeyi kısa tutmalı, hız istiyorsan adımı büyütüp beklemeyi biraz uzatmalısın. Taramayı yalnızca ilgilendiğin bölgeyle sınırlamak da (örneğin 45–135°) süreyi yarıya indirir. Servo kendi kendine sarsılıyor, Arduino ara sıra yeniden başlıyor ve Processing bağlantıyı kaybediyorsa sorun hız değil güçtür: SG90 hareket anında yaklaşık 100–250 mA, zorlandığında 600 mA'e kadar akım çekebilir. Kondansatörü ekle, gerekirse servoyu GND'si Arduino ile ortak olan harici bir 5 V kaynaktan besle.

Ölçüm doğruluğunu artırmak

HC-SR04 kâğıt üzerinde 3 mm çözünürlük vaat etse de radarda doğruluğu üç şey belirler: huzme genişliği, ses hızı ve yüzeyin türü. Sensörün ses demeti yaklaşık 15 derecelik bir koni gibi yayılır. Bu yüzden 50 cm uzaklıktaki ince bir kalem ekranda nokta olarak değil, 15–20 derecelik bir yay olarak görünür; radarın açısal çözünürlüğünü servo adımı değil bu huzme belirler ve nesnenin gerçek yönü bu yayın ortasıdır. Ses hızı ise sıcaklıkla değişir ve v = 331,3 + 0,606 × T (m/s, T °C cinsinden) formülüyle hesaplanır. Koddaki 58 sayısı yaklaşık 22 °C'ye karşılık gelir; soğuk bir garajda ölçümler birkaç yüzde uzun çıkar.

SıcaklıkSes hızı1 cm için gidiş-dönüş100 cm'deki nesne (/58 ile)
0 °C331,3 m/s60,4 µsyaklaşık 104 cm
10 °C337,4 m/s59,3 µsyaklaşık 102 cm
20 °C343,4 m/s58,2 µsyaklaşık 100 cm
30 °C349,5 m/s57,2 µsyaklaşık 99 cm
40 °C355,5 m/s56,3 µsyaklaşık 97 cm

Ortam sıcaklığını bir DHT11 ya da DS18B20 ile ölçüp ses hızını hesaba katabilir, tek seferlik hatalı ölçümleri de üç ölçümün ortancasını alarak atabilirsin. Aşağıdaki iki fonksiyonu ana koda ekleyip loop() içindeki measureCm() çağrısını bunlardan biriyle değiştirmen yeterli. Ortanca filtresi her adımda üç ölçüm yaptığı için taramayı biraz yavaşlatır.

Arduino (C++)
1// Ana radar koduna eklenecek fonksiyonlar / functions to add to the main radar sketch
2
3// Sıcaklığa göre düzeltilmiş ölçüm / temperature-compensated reading
4int measureCmTemp(float tempC) {
5  digitalWrite(TRIG_PIN, LOW);
6  delayMicroseconds(2);
7  digitalWrite(TRIG_PIN, HIGH);
8  delayMicroseconds(10);
9  digitalWrite(TRIG_PIN, LOW);
10  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
11  if (us == 0) return 0;                                // yankı yok / no echo
12  float v = 331.3 + 0.606 * tempC;                      // ses hızı (m/s) / speed of sound (m/s)
13  return (int)(us * v / 20000.0 + 0.5);                 // µs × (m/s) / 20000 = cm
14}
15
16// Üç ölçümün ortancası: tek seferlik sıçramaları atar / median of three: drops one-off spikes
17int medianCm() {
18  int a = measureCm(); delay(20);
19  int b = measureCm(); delay(20);
20  int c = measureCm();
21  return max(min(a, b), min(max(a, b), c));
22}
23
24// loop() içinde kullanım / use inside loop():
25// int distance = medianCm();
26// int distance = measureCmTemp(18.5);                  // sıcaklık DHT11'den gelebilir / temperature can come from a DHT11
  • Yumuşak yüzeyler (perde, kumaş, sünger) sesi emer; nesne olduğu yerde görünmeyebilir.
  • Eğik yüzeyler sesi başka yöne yansıtır; sensöre 45°'den fazla açıyla duran düz bir kutu boşluk gibi okunabilir.
  • 2 cm'den yakın nesneler ölçülemez; pratikte 3–4 cm'nin altındaki değerleri güvenilmez kabul et.
  • Oda köşeleri çoklu yansıma yapar ve gerçekte olmayan uzak "hayaletler" oluşturabilir; deneme alanını boş ve geniş seç.
  • Menzil: Veri sayfası 400 cm der, ama küçük nesnelerde kararlı ölçüm genellikle 2 metreye kadar alınır; MAX_CM değerini buna göre seç.

OLED ekranda mini radar (bilgisayarsız)

Radarın bilgisayara bağlı kalmadan, pille çalışan taşınabilir bir cihaz olmasını istiyorsan Processing yerine 0,96 inçlik bir OLED ekran kullanabilirsin. SSD1306 sürücülü 128×64 ekranın alt orta noktası radarın merkezi olur; 60 piksel yarıçaplı bir yarım çember, tarama çizgisi ve her açıda son ölçülen nesneyi gösteren noktalar çizilir. Ekranın bağlantısı (SDA → A4, SCL → A5) ve kütüphane kurulumu için OLED ekran SSD1306 yazısına bakabilirsin; HC-SR04 ve servonun bağlantısı yukarıdakiyle aynıdır.

0,96 inç I2C OLED ekran SSD1306
0,96 inç OLED ekran: bilgisayarsız mini radarda 128×64 piksellik yarım daire tarama ekranı olur.
Arduino (C++)
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <Servo.h>
5
6const byte SERVO_PIN = 9;                 // SG90 sinyal / SG90 signal
7const byte TRIG_PIN  = 10;                // HC-SR04 Trig
8const byte ECHO_PIN  = 11;                // HC-SR04 Echo
9const int  MAX_CM    = 50;                // ekrandaki en uzak mesafe / farthest distance on screen
10const int  STEP      = 3;                 // adım başına derece / degrees per step
11const int  CX = 64, CY = 63, R = 60;      // radar merkezi ve yarıçapı (piksel) / radar centre and radius (px)
12
13Adafruit_SSD1306 display(128, 64, &Wire, -1);
14Servo radarServo;
15uint8_t dist[180 / STEP + 1];             // her açının son ölçümü (cm) / last reading per angle (cm)
16int angle = 0;
17int dir = STEP;
18
19int measureCm() {
20  digitalWrite(TRIG_PIN, LOW);
21  delayMicroseconds(2);
22  digitalWrite(TRIG_PIN, HIGH);
23  delayMicroseconds(10);
24  digitalWrite(TRIG_PIN, LOW);
25  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
26  if (us == 0) return 0;                  // yankı yok / no echo
27  return us / 58;
28}
29
30void setup() {
31  pinMode(TRIG_PIN, OUTPUT);
32  pinMode(ECHO_PIN, INPUT);
33  radarServo.attach(SERVO_PIN);
34  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
35    for (;;);                             // ekran bulunamadı / display not found
36  }
37  display.setTextColor(SSD1306_WHITE);
38}
39
40void loop() {
41  radarServo.write(angle);
42  delay(20);                              // çizim de zaman aldığı için kısa / short, drawing takes time too
43  int d = measureCm();
44  dist[angle / STEP] = (d > 255) ? 255 : d;   // byte'a sığdır / fit into a byte
45
46  display.clearDisplay();
47  display.drawCircle(CX, CY, R, SSD1306_WHITE);       // dış yay, alt yarısı ekran dışında / outer arc, lower half off-screen
48  display.drawCircle(CX, CY, R / 2, SSD1306_WHITE);   // orta yay = MAX_CM / 2 / middle arc = MAX_CM / 2
49  for (int i = 0; i <= 180 / STEP; i++) {
50    if (dist[i] > 0 && dist[i] <= MAX_CM) {
51      float rad = radians(i * STEP);
52      int r = map(dist[i], 0, MAX_CM, 0, R);          // cm → piksel / cm → pixels
53      display.fillCircle(CX + r * cos(rad), CY - r * sin(rad), 1, SSD1306_WHITE);
54    }
55  }
56  float rad = radians(angle);
57  display.drawLine(CX, CY, CX + R * cos(rad), CY - R * sin(rad), SSD1306_WHITE);  // tarama çizgisi / sweep line
58  display.setCursor(0, 0);
59  display.print(angle);                   // açı / angle
60  display.setCursor(98, 0);
61  display.print(d);                       // mesafe / distance
62  display.print(F("cm"));
63  display.display();
64
65  if (angle + dir > 180 || angle + dir < 0) dir = -dir;   // uçta yön değiştir / reverse at the ends
66  angle += dir;
67}

Bu sürümde mesafeler dist dizisinde açıya göre saklanır; böylece tarama çizgisi geçtikten sonra da noktalar ekranda kalır ve bir sonraki turda güncellenir. Merkezi ekranın alt kenarına konan çemberin alt yarısı ekranın dışına taştığı için kütüphane onu çizmez, geriye düzgün bir yarım daire kalır. Ekrana bir kare göndermek 400 kHz I2C hızında yaklaşık 25 ms sürdüğünden bekleme 20 ms'ye indirildi ve adım 3 dereceye çıkarıldı; bir tarama yaklaşık 4–5 saniye sürer. Küçük ekranda 50 cm'lik ölçek daha anlaşılır olduğu için MAX_CM 50 seçildi. Uno'nun 2 KB belleğinin yarısı ekran tamponuna gittiğinden diziyi byte (uint8_t) türünde tutmak da önemlidir.

ESP32 ile Arduino radar

ESP32'de Arduino'nun Servo kütüphanesi çalışmaz; Kütüphane Yöneticisi'nden ESP32Servo kütüphanesini kurman gerekir. Kodun geri kalanı neredeyse aynıdır. ESP32 3,3 V ile çalıştığı için HC-SR04'ün Echo hattına gerilim bölücü takmayı unutma; Trig hattındaki 3,3 V'luk darbe ise sensörlerin çoğunu tetiklemeye yeter. Bu kod 115200 baud kullandığı için Processing kodundaki 9600'ü de 115200 yapmalısın. ESP32'nin Wi-Fi özelliği sayesinde ileride radar verisini bilgisayar yerine telefondaki bir web sayfasına da gönderebilirsin; ESP32'ye yeniysen önce ESP32 nedir yazısına göz at.

Arduino (C++)
1#include <ESP32Servo.h>                // Kütüphane Yöneticisi: ESP32Servo / Library Manager: ESP32Servo
2
3const int SERVO_PIN  = 13;             // SG90 sinyal / SG90 signal
4const int TRIG_PIN   = 26;             // HC-SR04 Trig
5const int ECHO_PIN   = 27;             // 1k/2k bölücüden / through the 1k/2k divider
6const int STEP       = 2;              // adım başına derece / degrees per step
7const int STEP_DELAY = 40;             // ölçümden önce bekleme (ms) / wait before measuring (ms)
8
9Servo radarServo;
10int angle = 0;
11int dir = STEP;
12
13int measureCm() {
14  digitalWrite(TRIG_PIN, LOW);
15  delayMicroseconds(2);
16  digitalWrite(TRIG_PIN, HIGH);
17  delayMicroseconds(10);
18  digitalWrite(TRIG_PIN, LOW);
19  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
20  if (us == 0) return 0;               // yankı yok / no echo
21  return us / 58;
22}
23
24void setup() {
25  Serial.begin(115200);                       // Processing'de de 115200 / 115200 in Processing too
26  pinMode(TRIG_PIN, OUTPUT);
27  pinMode(ECHO_PIN, INPUT);
28  radarServo.setPeriodHertz(50);              // standart servo 50 Hz / standard servo 50 Hz
29  radarServo.attach(SERVO_PIN, 500, 2400);    // SG90 darbe aralığı (µs) / SG90 pulse range (µs)
30  radarServo.write(angle);
31  delay(500);
32}
33
34void loop() {
35  radarServo.write(angle);
36  delay(STEP_DELAY);
37  int distance = measureCm();
38  Serial.printf("%d,%d\n", angle, distance);  // açı,mesafe / angle,distance
39  if (angle + dir > 180 || angle + dir < 0) dir = -dir;   // uçta yön değiştir / reverse at the ends
40  angle += dir;
41}

Raspberry Pi Pico ve MicroPython ile radar

Pico'da servo için ayrı bir kütüphane gerekmez: 50 Hz'lik PWM sinyalinin darbe genişliğini duty_ns() ile ayarlamak yeterlidir. Yankı süresi machine.time_pulse_us() ile ölçülür ve zaman aşımında negatif bir sayı döner. Pico'nun pinleri de 3,3 V olduğundan Echo hattında bölücü şarttır. Kodu Thonny ile main.py adıyla Pico'ya kaydet, sonra Thonny'yi kapat; aksi halde port meşgul kalır ve Processing bağlanamaz. Pico USB üzerinden sanal bir seri port açtığı için Processing'deki baud değeri önemli değildir; aynı radar ekranı hiçbir değişiklik yapmadan çalışır.

MicroPython
1from machine import Pin, PWM, time_pulse_us
2import time
3
4servo = PWM(Pin(15))                     # SG90 sinyal / SG90 signal
5servo.freq(50)                           # standart servo 50 Hz / standard servo 50 Hz
6trig = Pin(14, Pin.OUT)
7echo = Pin(13, Pin.IN)                   # bölücüden gelir / comes through the divider
8
9def set_angle(a):
10    # 0° = 500 µs, 180° = 2400 µs darbe / pulse
11    servo.duty_ns(500000 + a * 1900000 // 180)
12
13def measure_cm():
14    trig.value(0)
15    time.sleep_us(2)
16    trig.value(1)                        # 10 µs tetik / 10 µs trigger
17    time.sleep_us(10)
18    trig.value(0)
19    t = time_pulse_us(echo, 1, 30000)    # en çok 30 ms bekle / wait at most 30 ms
20    if t < 0:
21        return 0                         # yankı yok / no echo
22    return t // 58
23
24angle, step = 0, 2
25set_angle(angle)
26time.sleep_ms(500)
27
28while True:
29    set_angle(angle)
30    time.sleep_ms(40)                    # servo otursun / let the servo settle
31    print("{},{}".format(angle, measure_cm()))   # açı,mesafe / angle,distance
32    if angle + step > 180 or angle + step < 0:
33        step = -step                     # uçta yön değiştir / reverse at the ends
34    angle += step

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

Belirti ya da hata mesajıSebepÇözüm
Error opening serial port COM3: Port busyArduino IDE'nin Seri Monitör'ü ya da Seri Çizici'si, Thonny veya ikinci bir Processing penceresi portu tutuyor.Seri Monitör'ü ve diğer programları kapat, Processing çizimini yeniden çalıştır; gerekirse USB kablosunu çıkarıp tak.
ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0Serial.list() boş: kart bağlı değil, kablo yalnızca şarj kablosu ya da CH340 sürücüsü kurulu değil.Veri aktaran bir kablo kullan, sürücüyü kur; Arduino IDE portu görüyorsa Processing de görür.
Pencere açılıyor ama tarama çizgisi kıpırdamıyorYanlış port seçilmiş (Windows'ta COM1 çoğu zaman listenin başındadır) ya da baud hızları farklı.Konsoldaki listede Arduino'nun sırasını bul, Serial.list()[1] gibi düzelt ve iki taraftaki baud değerini eşitle.
The package “processing.serial” does not exist. You might be missing a library.Serial kütüphanesi bulunamıyor; Processing 4.4.8 kurulum paketinde bu kütüphane eksikti.Processing'i daha yeni bir sürüme güncelle ya da 4.4.7'yi kullan; import satırının doğru yazıldığını kontrol et.
Error opening serial port /dev/ttyACM0: Permission deniedLinux'ta kullanıcının seri porta erişim izni yok.Kullanıcını dialout grubuna ekle (sudo usermod -a -G dialout $USER), oturumu kapatıp yeniden aç.
Processing açıkken Arduino'ya kod yüklenmiyorPort Processing tarafından kullanılıyor.Yüklemeden önce Processing çizimini Stop düğmesiyle durdur.
Mesafe hep 0 ya da anlamsız değerlerTrig ve Echo yer değiştirmiş, sensörün beslemesi yok ya da nesne menzil dışında.Bağlantıyı tabloya göre kontrol et, önce yalnızca mesafe ölçen basit bir kodla dene.
Servo titriyor, Arduino kendini resetliyorUSB portu servonun çektiği akımı karşılayamıyor, gerilim düşüyor.470 µF kondansatör ekle ya da servoyu GND'si ortak olan harici bir 5 V kaynaktan besle.
Radar ekranında sağ ile sol tersServo ya da sensör ters yönde monte edilmiş.Processing'de angle = 180 - int(parts[0]); yaz ya da servonun kolunu çevirip yeniden tak.
Hata ayıklarken sırayı bozma: önce Seri Monitör'de "açı,mesafe" satırlarını gör, sonra Seri Monitör'ü kapatıp Processing'i çalıştır. Arduino tarafında veri doğru akıyorsa sorun neredeyse her zaman port seçimi ya da baud hızıdır.

Radar projesini geliştirme fikirleri

  • Alarmlı güvenlik radarı: Bir nesne 30 cm'den yakına girdiğinde buzzer öttür ve kırmızı bir LED yak; Arduino alarm sistemi yazısındaki fikirlerle birleştir.
  • Engelden kaçan robot: Radarı robotun önüne yerleştir; robot durduğunda sağı ve solu tarayıp en boş yöne dönsün. Ayrıntılar engelden kaçan robot yazısında.
  • Oda haritası: Tarama verisini bir SD kart modülüne kaydet ve bilgisayarda nokta bulutu olarak çiz.
  • Kablosuz radar: ESP32 ile ölçümleri Wi-Fi üzerinden telefondaki bir web sayfasına gönder; ESP32 web sunucusu ile gerçek zamanlı çizim yapabilirsin.
  • Daha keskin harita: HC-SR04 yerine dar huzmeli bir lazer (ToF) sensör kullan; seçenekleri mesafe sensörleri karşılaştırması yazısında bulabilirsin.
  • Akıllı baston: Mesafe sensörü ve titreşim motoruyla görme engelliler için engel uyarısı veren bir baston yap: akıllı baston projesi.

Arduino radar projesi; mesafe sensörü, servo kontrolü, seri haberleşme ve bilgisayarda grafik çizimini tek projede birleştirdiği için yeni başlayanlar için harika bir sonraki adımdır. Temelleri pekiştirmek istersen HC-SR04 mesafe sensörü ve servo motor yazılarına da göz atabilirsin. BlueGrays uygulamasında HC-SR04 ile mesafe ölçme, park sensörü, servo motor kullanımı ve engelden kaçan robot projelerini devre şemaları ve açıklamalı kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

Arduino radar projesi gerçek bir radar mı?

Teknik olarak hayır, bir sonardır. Gerçek radarlar radyo dalgası gönderirken bu proje HC-SR04 ile 40 kHz'lik ses dalgası kullanır. Çalışma mantığı (dalga gönder, yankının dönüş süresini ölç, yönle birlikte ekrana çiz) aynı olduğu ve görüntüsü radar ekranına benzediği için "Arduino radar" adıyla bilinir.

Arduino radar kaç metre uzağı algılar?

HC-SR04'ün veri sayfasındaki menzili 2–400 cm'dir. Duvar gibi büyük ve düz yüzeylerde 3–4 metreye kadar ölçüm alınabilir, ancak sandalye ayağı ya da insan gibi nesnelerde güvenilir menzil genellikle 1,5–2 metredir. Processing kodundaki MAX_CM değerini bu menzile göre ayarlamak en net görüntüyü verir.

Arduino radar için hangi malzemeler gerekir?

Bir Arduino Uno ya da Nano, HC-SR04 ultrasonik sensör, SG90 servo motor, breadboard, birkaç jumper kablo ve servo için 470 µF'lık bir kondansatör yeterlidir. Radar ekranını bilgisayarda ücretsiz Processing programı çizer; bilgisayarsız sürüm için 0,96 inç bir OLED ekran eklenir.

Processing olmadan Arduino radar yapılabilir mi?

Evet. SSD1306 OLED ekranla radarı doğrudan Arduino üzerinde çizebilir ve pille çalışan taşınabilir bir cihaza dönüştürebilirsin. Ekran kullanmadan da Arduino IDE'nin Seri Çizici penceresinde açı ve mesafe değerlerini grafik olarak izlemek mümkündür.

Processing'de "Port busy" hatası nasıl çözülür?

Bu hata seri portu başka bir programın kullandığını gösterir. Arduino IDE'deki Seri Monitör ve Seri Çizici pencerelerini, Thonny'yi ya da açık kalmış başka bir Processing çizimini kapatıp tekrar dene. Sorun sürerse USB kablosunu çıkarıp yeniden tak.

Servo motor neden titriyor ve Arduino neden resetleniyor?

SG90 hareket ederken anlık olarak yüksek akım çeker ve USB'den beslenen Arduino'nun 5 V hattı bir an düşer. Servo besleme hattına 470 µF'lık bir kondansatör koymak çoğu zaman sorunu çözer; çözmezse servoyu GND'si Arduino ile ortak olan harici bir 5 V kaynaktan besle.

Tüm projeleri gör
HC-SR04 Mesafe Ölçme (Serial Ekran)
#27Başlangıç

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

Yarasalar karanlıkta yollarını nasıl buluyorsa HC-SR04 sensörü de öyle çalışır: duyamadığın bir ses gönderir, yankısını dinler ve önündeki cismin ne kadar uzakta olduğunu ölçer. Arduino bu mesafeyi sa

4.6(45)
68
Servo Motor Kullanım
#35Başlangıç
Premium

Servo Motor Kullanım

Küçük bir servo motorun kolu sırayla üç konuma döner: en başa, tam ortaya ve en sona, her durakta iki saniye bekleyerek. Arduino motora hangi açıda durması gerektiğini söyler, motor da oraya gidip ora

4.7(48)
67
Pot ile SG90 Servo Açı Kontrolü
#99Başlangıç
Premium

Pot ile SG90 Servo Açı Kontrolü

Potansiyometre ile Servo Motor (SG90) Kontrolü Bu projenin temel amacı, analog bir giriş birimi olan potansiyometreyi kullanarak, bir servo motorun açısal konumunu gerçek zamanlı ve hassas bir şekilde kontrol etmektir. Proje, analog-dijital dönüşüm (ADC) ve sinyal haritalama mantığını kavramak için temel bir mühendislik örneğidir. Çalışma Mantığı: Analog Veri Okuma: Kullanıcı potansiyometreyi çevirdiğinde, direnç değişimi sonucunda Arduino'nun A0 analog pinine 0V ile 5V arasında bir voltaj siny

4.5(24)
38
HC-SR04 ile Park Sensörü
#28Orta
Premium

HC-SR04 ile Park Sensörü

Arabalardaki park sensörünün küçük bir benzeri: bir şey yaklaştıkça bip sesleri hızlanır. Mesafe sensörü önündeki nesneyi ölçer; 20 santimetreden uzaktaysa yeşil LED yanar, daha yakına gelince kırmızı

4.8(64)
84
Engelden Kaçan Robot
#81İleri
Premium

Engelden Kaçan Robot

Kendi yolunu bulan akıllı bir araç yapmaya ne dersin? Engelden Kaçan Robot, önündeki ultrasonik sensör sayesinde çevresini sürekli tarar. Bir engelle karşılaştığında durur, servo motoruyla sağına ve s

5.0(38)
49
ESP32 HC-SR04 Ultrasonik Mesafe Ölçer
#116Orta

ESP32 HC-SR04 Ultrasonik Mesafe Ölçer

HC-SR04 ultrasonik sensör, gönderdiği ses dalgasının nesneye çarpıp geri dönme süresini (Time of Flight) ölçerek mesafe hesaplar. Bu projede ESP32 ile TRIG pinine 10 mikrosaniyelik darbe gönderip, ECHO pininden gelen yankı süresini `pulseIn()` ile okuyacağız. Hesaplanan mesafeyi cm cinsinden 16x2 I2C LCD'de göstereceğiz. HC-SR04 5V çalıştığı için ECHO pinine **gerilim bölücü** zorunludur — aksi halde ESP32'nin 3.3V GPIO'su zarar görür.

4.9(28)
44
ESP32 Park Sensörü (HC-SR04 + 5 LED Bar + Buzzer + OLED)
#142İleri
Premium

ESP32 Park Sensörü (HC-SR04 + 5 LED Bar + Buzzer + OLED)

Otomobil park sensörünün ESP32 versiyonu! HC-SR04 ultrasonik sensör ile önündeki nesneye olan mesafeyi ölçüyoruz. Mesafe azaldıkça 5 LED'lik bar dolar (yeşil → sarı → kırmızı) ve buzzer bip aralığı kısalır. Çok yakınlaşınca (10 cm altında) sürekli alarm çalar ve tüm LED'ler yanar. SSD1306 OLED ekranda büyük fontla anlık cm değeri, durum metni (SAKIN / DIKKAT / YAKIN / DUR! / TEHLIKE) ve LED bar simülasyonu gösterilir. Klasik ve öğretici bir proje — HC-SR04 pulseIn, digital multi-output, buzzer P

0.0(0)
14
LCD Ekran Kullanarak Mesafe Ölçme
#31İleri
Premium

LCD Ekran Kullanarak Mesafe Ölçme

Cetvelsiz mesafe ölçen bir alet: elini sensörün önünde ileri geri götür, sayı değişsin. HC-SR04 ses dalgası gönderip yankısını dinler, Arduino da aradaki uzaklığı santimetre olarak hesaplayıp iki satı

4.6(45)
59