Parçalar · 12 dk okuma

nRF24L01 Arduino Kullanımı: Kablosuz Haberleşme ve Kumanda

nRF24L01 Arduino bağlantısı, 3,3 V ve 10 µF kondansatör, RF24 verici/alıcı kodu, PA+LNA ile 1 km menzil, joystickli kumanda, ESP32, Pico ve hata çözümleri.

nRF24L01 Arduino ikilisi, iki kart arasında kablo çekmeden veri göndermenin en ucuz ve en pratik yoludur. Tırnak büyüklüğündeki bu modül 2,4 GHz bandında çalışır, saniyede 2 megabite kadar veri taşır ve hem verici hem alıcı olarak kullanılabilir. Uzaktan kumandalı araba, kablosuz joystick, bahçedeki sensörden eve veri taşıyan bir istasyon ya da birbirine haber veren alarm düğümleri için idealdir. Standart sürümü açık alanda 100 metreye, antenli nRF24L01+PA+LNA sürümü ise uygun koşullarda 1 kilometreye kadar ulaşabilir.

Bu rehberde modülün nasıl çalıştığını, SPI pinlerini, neden mutlaka 3,3 V ile beslenmesi gerektiğini ve en sık sorunun çözümü olan 10 µF kondansatörü öğreneceksin. Ardından RF24 kütüphanesiyle verici ve alıcı kodu yazacak, adres ve kanal ayarlarını anlayacak, joystickli bir uzaktan kumanda yapacak, modülü ESP32 ve Raspberry Pi Pico'ya bağlayacak ve son olarak "radio.begin() false" ile "veri gelmiyor" sorunlarını adım adım çözeceksin.

nRF24L01 2,4 GHz kablosuz haberleşme modülü
Standart nRF24L01+ modülü: kartın ucundaki zikzak yol PCB antendir; 8 pinli konnektörden SPI ile bağlanır.

nRF24L01 nedir, nasıl çalışır?

nRF24L01, Nordic Semiconductor'ın ürettiği 2,4 GHz bir telsiz alıcı-verici (transceiver) yongasıdır; bugün satılan modüllerin neredeyse tamamında geliştirilmiş nRF24L01+ sürümü ya da onunla uyumlu bir klon yonga bulunur. Modül Arduino ile SPI üzerinden konuşur: Arduino ayarları ve gönderilecek veriyi SPI ile yazar, gerisini yonga halleder. Nordic'in Enhanced ShockBurst adını verdiği donanım protokolü her paketi bir adres ve CRC (hata denetimi) ile paketler. Alıcı paketi doğru aldığında vericiye otomatik bir onay (ACK) gönderir; onay gelmezse verici paketi kendiliğinden yeniden dener. Yani kodunda yalnızca "gönder" dersin, yeniden deneme ve hata denetimi donanımda yapılır.

Bir pakette en fazla 32 bayt veri taşınır. Bu az görünse de bir joystickin iki ekseni, birkaç buton ve birkaç sensör değeri rahatça sığar. Modül 126 kanaldan birini kullanır ve kanal frekansı 2400 + kanal numarası (MHz) formülüyle bulunur; örneğin 76. kanal 2476 MHz'dir. Bir alıcı aynı anda 6 farklı adresi (pipe, yani boru) dinleyebilir; böylece tek bir merkez altı vericiden veri toplayabilir.

ÖzellikDeğer
Frekans2,400–2,525 GHz (126 kanal, 1 MHz aralık)
Veri hızı250 kbps, 1 Mbps, 2 Mbps
Besleme gerilimi1,9–3,6 V (pratikte 3,3 V)
Giriş pinleri5 V'a dayanıklı (CE, CSN, SCK, MOSI)
Çıkış gücü0, −6, −12, −18 dBm
Akım (gönderirken, 0 dBm)Yaklaşık 11,3 mA
Akım (dinlerken, 2 Mbps)Yaklaşık 13,5 mA
Uyku (power down)Yaklaşık 900 nA
Alıcı hassasiyeti−94 dBm (250 kbps), −85 dBm (1 Mbps), −82 dBm (2 Mbps)
Paket boyutu1–32 bayt
ArayüzSPI, en fazla 10 MHz
Boru (pipe) sayısı6

nRF24L01 ile nRF24L01+PA+LNA farkı

Piyasada iki tip modül görürsün. Standart modülün anteni kartın üzerine çizilmiş zikzak bir bakır yoldur. nRF24L01+PA+LNA sürümünde ise aynı yonganın önüne bir RF ön uç yongası eklenmiştir: PA (Power Amplifier, güç yükselteci) giden sinyali güçlendirir, LNA (Low Noise Amplifier, düşük gürültülü yükselteç) gelen zayıf sinyali yongadan önce büyütür. Üstüne vidalı SMA konnektörlü harici bir anten takılır. İki modülün pin dizilişi ve kodu aynıdır, birbirleriyle de sorunsuz haberleşirler; fark menzilde ve akım ihtiyacındadır. Aşağıdaki değerler yaklaşıktır ve ortama göre değişir.

nRF24L01+PA+LNA antenli RF modülü
nRF24L01+PA+LNA: güç ve alıcı yükselteci olan, SMA antenli sürüm. Aynı kodla çalışır ama çok daha fazla akım çeker.
ÖzelliknRF24L01+ (PCB anten)nRF24L01+PA+LNA
AntenKart üzerine çiziliHarici SMA anten
Çıkış gücüEn fazla 0 dBm (1 mW)Modele göre +20 dBm'e (100 mW) kadar
Gönderirken tepe akımYaklaşık 12 mA115 mA'e kadar
Dinlerken tepe akımYaklaşık 13,5 mA45 mA'e kadar
Açık alanda menzil (250 kbps)50–100 m800–1100 m
Ev içinde menzil10–30 m, 1–2 duvarBirkaç kat ve onlarca metre
Besleme önerisi3,3 V pin + 10 µF kondansatörAyrı 3,3 V regülatör + kondansatör

nRF24L01 pinleri ve Arduino bağlantısı

Modülün 2×4 dizilmiş 8 pini vardır. Kare lehim pedli pin 1 numaradır ve GND'dir; hemen yanında VCC bulunur. CE (Chip Enable) modülü dinleme ya da gönderme moduna geçirir, CSN (Chip Select Not) ise SPI hattında "şimdi seninle konuşuyorum" demek için LOW çekilir. SCK, MOSI ve MISO standart SPI hatlarıdır ve kartının sabit SPI pinlerine bağlanmalıdır; CE ile CSN ise istediğin dijital pinlere bağlanabilir. IRQ pini isteğe bağlıdır, paket geldiğinde ya da gönderim bittiğinde LOW olur ve kesmeyle çalışmak istersen kullanılır. SPI'ın mantığı için SPI nedir yazısına, kartının tüm pin haritası için Pinout aracına bakabilirsin.

nRF24L01 piniGöreviArduino Uno / NanoArduino MegaESP32Raspberry Pi Pico
1 GNDToprakGNDGNDGNDGND
2 VCCBesleme (3,3 V)3.3V3.3V3V33V3(OUT)
3 CEMod seçimiD9D9GPIO 4GP6
4 CSNSPI seçmeD10D10GPIO 5GP5
5 SCKSPI saatD13D52GPIO 18GP2
6 MOSIKarttan modüle veriD11D51GPIO 23GP3
7 MISOModülden karta veriD12D50GPIO 19GP4
8 IRQKesme (isteğe bağlı)BoşBoşBoşBoş
VCC'yi asla 5 V'a bağlama. Yonga en fazla 3,6 V'a dayanır; 5 V verirsen kalıcı olarak bozulabilir. Sinyal pinleri 5 V'a dayanıklı olduğu için Uno'nun SPI pinlerine doğrudan bağlanabilir, ama besleme her zaman 3,3 V olmalıdır. Modülü breadboard'a da doğrudan takma: 2×4 pin dizisi yüzünden karşılıklı pinler aynı şeride düşer ve kısa devre olur; dişi-erkek jumper kablo kullan.

En sık hata: güç beslemesi ve 10 µF kondansatör

nRF24L01 sorunlarının büyük kısmının sebebi kod değil, beslemedir. Modül gönderim anında kısa ama sert akım darbeleri çeker. Uzun jumper kablolar ve zayıf bir 3,3 V kaynağı bu darbelere yetişemez; gerilim bir anlığına düşer, yonga paketi bozuk gönderir, onayları kaçırır ya da kendini sıfırlar. Arduino Uno'nun 3,3 V pini resmi belgelere göre en fazla 50 mA verir; standart modüle yeter ama 115 mA'e kadar çeken PA+LNA sürümüne yetmez. Bazı Nano klonlarında 3,3 V pini USB-seri yongadan gelir ve daha da zayıftır. Belirtiler tanıdık gelecektir: write() bazen başarılı bazen değil, modül eline dokununca daha iyi çalışıyor ya da menzil birkaç metrede kalıyor.

  • 10 µF kondansatör: Modülün VCC ve GND pinlerine, olabildiğince yakın bir 10 µF elektrolitik kondansatör tak ya da lehimle. Uzun bacak (+) VCC'ye, şeritli taraf (−) GND'ye gelmeli. 10–100 µF arası değerler de iş görür; neden işe yaradığını Kondansatör nedir yazısında okuyabilirsin.
  • 100 nF seramik kondansatör: Elektrolitiğe paralel eklenen küçük bir seramik kondansatör (üzerinde 104 yazar) yüksek frekanslı gürültüyü süzer. Kondansatör üzerindeki kodları Kondansatör kodu aracıyla çözebilirsin.
  • Soket adaptörü: nRF24L01 için satılan 8 pinli adaptör kartlarında AMS1117-3.3 regülatör ve kondansatörler hazırdır. Adaptörün VCC'sine 5 V verirsin, modüle temiz 3,3 V gider.
  • Ayrı regülatör: PA+LNA sürümünü Arduino'nun 3,3 V pininden değil, 5 V'tan beslenen ayrı bir AMS1117-3.3 regülatörden besle ve tüm GND'leri birleştir.
  • Kısa kablo: Jumper kabloları mümkünse 10 cm'nin altında tut; uzun ve gevşek kablolar hem beslemeyi hem SPI sinyallerini bozar.
AMS1117 3,3 V voltaj regülatörü
AMS1117-3.3 regülatör: 5 V'u 3,3 V'a düşürür ve PA+LNA modülünün gönderim anındaki yüksek akımını rahatça karşılar.

RF24 kütüphanesini kurmak

  1. Arduino IDE'de Araçlar > Kütüphaneleri Yönet menüsünü aç ya da soldaki kütüphane simgesine tıkla.
  2. Arama kutusuna RF24 yaz ve TMRh20 imzalı RF24 kütüphanesini kur. RF24Network, RF24Mesh ve RF24Ethernet ayrı kütüphanelerdir, başlangıç için gerekmez.
  3. Kurulumdan sonra Dosya > Örnekler > RF24 altında GettingStarted örneğini görürsün. Bu yazıdaki kodlar RF24'ün 1.5 ve sonraki sürümlerinin yazımıyla hazırlandı.
  4. Kütüphane kurmakta ilk kez zorlanıyorsan Arduino kütüphane ekleme yazısındaki adımları izle.
İnternetteki eski örneklerde radio.openWritingPipe(address) ve ardından radio.stopListening() görürsün. RF24 1.5 sürümünden beri bunun yerine tek satırda radio.stopListening(address) yazılması öneriliyor; eski yazım hâlâ derlenir ama "deprecated" (kullanımdan kalkıyor) uyarısı verebilir. Bu yazıdaki kod derlenmiyorsa RF24 kütüphaneni güncelle.

Adres, kanal ve veri hızı: iki modülün anlaşması

İki modülün birbirini duyabilmesi için bazı ayarların iki tarafta birebir aynı olması gerekir. Bunu bir telsiz konuşmasına benzetebilirsin: aynı frekansa (kanal), aynı konuşma hızına (veri hızı) ve aynı çağrı koduna (adres) ayarlı değilsen karşı tarafı duyamazsın. Adres 5 baytlık bir dizidir ve kodda "00001" gibi 5 karakterlik bir metin olarak yazmak en kolayıdır. Adresi bir cihazın kimliği gibi değil, iki cihaz arasındaki ortak bir yol gibi düşün: verici paketi o yola bırakır, o yolu dinleyen alıcı paketi alır. Paket boyu da önemlidir; RF24 varsayılan olarak sabit boyutlu paket kullanır ve alıcı, vericiyle aynı boyu beklemezse paketi hiç görmez.

AyarRF24 fonksiyonuBu yazıdaki değerNot
KanalsetChannel(76)76 (2476 MHz)0–125 arası; iki tarafta aynı olmalı
Veri hızısetDataRate(RF24_250KBPS)250 kbpsHız düştükçe menzil artar
AdresstopListening(adres) / openReadingPipe(1, adres)"00001"Vericinin hedefi = alıcının borusu
Paket boyusetPayloadSize(sizeof(veri))32 bayt (joystick örneğinde 5)Sabit boyda iki taraf eşit olmalı
Çıkış gücüsetPALevel(RF24_PA_LOW)DüşükEşleşmesi gerekmez, menzili belirler
Otomatik onay ve CRCVarsayılan olarak açık16 bit CRCKapatacaksan iki tarafta da kapat

Verici kodu (TX)

İlk deneme için iki Arduino'yu iki ayrı USB portuna bağla ve modüllerin arasına 1–2 metre mesafe koy. Birine aşağıdaki verici kodunu yükle. Kod her saniye sayaçlı bir metin gönderir ve alıcının onay verip vermediğini Seri Port Ekranı'na yazar. Seri Port Ekranı'nı 115200 baud hızına ayarlamayı unutma.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // iki tarafta aynı adres / same address on both sides
6char message[32];                         // en fazla 32 bayt / 32 bytes max
7uint16_t counter = 0;
8
9void setup() {
10  Serial.begin(115200);
11  if (!radio.begin()) {                   // modül cevap vermiyor / module not responding
12    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
13    while (true) {}
14  }
15  radio.setChannel(76);                   // kanal 76 = 2476 MHz / channel 76 = 2476 MHz
16  radio.setDataRate(RF24_250KBPS);        // en uzun menzil / longest range
17  radio.setPALevel(RF24_PA_LOW);          // masa testi için düşük güç / low power for desk tests
18  radio.setPayloadSize(sizeof(message));  // paket boyu 32 bayt / 32-byte payload
19  radio.stopListening(address);           // verici modu + hedef adres / TX mode + target address
20}
21
22void loop() {
23  snprintf(message, sizeof(message), "Merhaba BlueGrays #%u", counter++);
24  bool ok = radio.write(message, sizeof(message));   // onay (ACK) geldi mi? / was it acknowledged?
25  if (ok) {
26    Serial.print(F("Gonderildi: "));
27    Serial.println(message);
28  } else {
29    Serial.println(F("Onay gelmedi"));
30  }
31  delay(1000);
32}

Alıcı kodu (RX)

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
5const uint8_t address[6] = "00001";       // vericiyle aynı adres / same address as the transmitter
6char message[32];
7
8void setup() {
9  Serial.begin(115200);
10  if (!radio.begin()) {
11    Serial.println(F("nRF24L01 bulunamadi, kablolari kontrol et!"));
12    while (true) {}
13  }
14  radio.setChannel(76);                   // ayarlar vericiyle aynı / settings match the transmitter
15  radio.setDataRate(RF24_250KBPS);
16  radio.setPALevel(RF24_PA_LOW);
17  radio.setPayloadSize(sizeof(message));
18  radio.openReadingPipe(1, address);      // 1 numaralı boruyu aç / open pipe 1
19  radio.startListening();                 // alıcı modu / RX mode
20}
21
22void loop() {
23  if (radio.available()) {                // paket geldi mi? / has a packet arrived?
24    radio.read(message, sizeof(message));
25    Serial.print(F("Gelen: "));
26    Serial.println(message);
27  }
28}

radio.write() paketi gönderir ve alıcıdan onay gelirse true döndürür; onay gelmezse varsayılan ayarda yaklaşık 1,5 ms arayla 15 kez yeniden dener, sonra false döner. Alıcıda openReadingPipe(1, address) 1 numaralı boruyu vericinin adresine ayarlar, startListening() modülü dinleme moduna geçirir, available() bekleyen paket olup olmadığını söyler ve read() paketi değişkene kopyalar. Alıcının ekranında "Gelen: Merhaba BlueGrays #0", "#1", "#2" diye artan satırlar görüyorsan bağlantın çalışıyor demektir.

Modülleri test ederken yan yana koyma ve gücü düşük tut. Özellikle PA+LNA modüller birkaç santimetre arayla tam güçte çalışırken birbirinin alıcısını doyurur ve paketler kaybolur; bu da arıza varmış gibi görünür. Kısa mesafede RF24_PA_LOW ya da RF24_PA_MIN kullan, gerçek mesafede gücü artır.

Menzil: 100 metreden 1 kilometreye

Menzili üç şey belirler: çıkış gücü, alıcı hassasiyeti ve ortam. Veri hızı düştükçe alıcı daha zayıf sinyalleri çözebilir; 250 kbps'de hassasiyet −94 dBm iken 2 Mbps'de −82 dBm'dir. Aradaki 12 dB'lik fark, açık alanda kabaca 4 kat menzil demektir. Duvarlar, ağaçlar, insan vücudu ve metal yüzeyler 2,4 GHz sinyalini ciddi şekilde zayıflatır; Wi-Fi modemleri, Bluetooth cihazları ve mikrodalga fırınlar da aynı bandı paylaşır.

Veri hızıAlıcı hassasiyetiGöreceli menzilNe zaman?
250 kbps−94 dBmEn uzunKumanda, uzak sensör
1 Mbps−85 dBmOrtaGenel kullanım (RF24 varsayılanı)
2 Mbps−82 dBmEn kısaYüksek hız, kısa mesafe

Kanal seçimi de önemlidir. Yaygın kullanılan 1, 6 ve 11. Wi-Fi kanalları yaklaşık 2401–2473 MHz aralığını kaplar; nRF24L01'in 74–83 arası kanalları bunun üstünde kalır ve yakında 12. ya da 13. kanalı kullanan bir modem yoksa daha sessizdir. Türkiye'de ve Avrupa'da lisanssız 2,4 GHz bandı 2400–2483,5 MHz olduğu için 83'ün üstündeki kanalları kullanma; internetteki bazı örneklerde görülen 100 ve üzeri kanallar bu bandın dışındadır. Menzili artırmak için şunları dene:

  • 250 kbps kullan: Kumanda ve sensör verisi için yüksek hız gerekmez, düşük hızla menzil kazanırsın.
  • Önce beslemeyi düzelt, sonra gücü artır: RF24_PA_MAX ancak kararlı bir 3,3 V ve kondansatörle anlam kazanır; zayıf beslemede gücü artırmak işleri kötüleştirir.
  • Antenleri yükseğe ve aynı yöne koy: Yerden 1–2 metre yükseklik ve iki antenin de aynı yönde dik durması menzili belirgin şekilde artırır.
  • Metalden uzak tut: Modülü metal bir kutunun içine ya da büyük bir pil paketinin hemen yanına koyma.
  • Kalkansız PA+LNA kartını sar: Metal kapağı olmayan PA+LNA modülünü elektrik bandıyla sarıp üstüne alüminyum folyo geçirmek kendi kendine yaptığı paraziti azaltır; folyo hiçbir pine ve anten konnektörüne değmemeli.
  • Antensiz gönderme yapma: PA+LNA modülünü anteni takılı değilken tam güçte çalıştırmak güç yükseltecini zorlar.

Joystick ile kablosuz uzaktan kumanda

Şimdi gerçek bir proje yapalım: bir Arduino'ya bağlı joystick ile ikinci Arduino'daki servo motoru ve bir LED'i kablosuz kontrol edelim. Verici tarafta joystickin VRx ucu A0'a, VRy ucu A1'e, buton (SW) ucu D2'ye bağlanır; ayrıntılar Joystick modülü yazısında. Alıcı tarafta servonun sinyal kablosu D3'e, LED ise 220 Ω dirençle D4'e bağlanır. İki taraftaki nRF24L01 bağlantısı yukarıdaki tabloyla aynıdır.

Birden fazla değeri tek pakette göndermenin en temiz yolu bir struct (yapı) kullanmaktır. Burada önemli bir ayrıntı var: değişken türlerini int16_t ve uint8_t gibi sabit boyutlu yazmalısın. Arduino Uno'da int 2 bayt, ESP32'de 4 bayttır; ayrıca ESP32 derleyicisi yapının sonuna hizalama için boş bayt ekler. Aynı yapı Uno'da 5, ESP32'de 6 bayt olursa paket boyları tutmaz ve veri hiç gelmez. __attribute__((packed)) bu boşlukları kaldırır ve yapıyı her kartta 5 bayt yapar. Önce verici:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // her kartta 5 bayt / 5 bytes on every board
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
11const uint8_t address[6] = "JOY01";       // kumanda adresi / remote address
12JoystickData data;
13
14void setup() {
15  pinMode(2, INPUT_PULLUP);               // joystick butonu (SW) / joystick button (SW)
16  if (!radio.begin()) {
17    while (true) {}                       // modül yok / no module
18  }
19  radio.setChannel(76);
20  radio.setDataRate(RF24_250KBPS);
21  radio.setPALevel(RF24_PA_HIGH);         // orta-yüksek güç / medium-high power
22  radio.setPayloadSize(sizeof(data));
23  radio.stopListening(address);           // verici modu / TX mode
24}
25
26void loop() {
27  data.x = analogRead(A0);                // VRx ekseni 0-1023 / VRx axis 0-1023
28  data.y = analogRead(A1);                // VRy ekseni 0-1023 / VRy axis 0-1023
29  data.button = (digitalRead(2) == LOW);  // basılıysa 1 / 1 when pressed
30  radio.write(&data, sizeof(data));
31  delay(50);                              // saniyede 20 paket / 20 packets per second
32}

Ardından servo ve LED'i süren alıcı:

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include <Servo.h>
4
5struct __attribute__((packed)) JoystickData {   // vericiyle birebir aynı / identical to the transmitter
6  int16_t x;
7  int16_t y;
8  uint8_t button;
9};
10
11RF24 radio(9, 10);                        // CE, CSN pinleri / CE, CSN pins
12const uint8_t address[6] = "JOY01";       // vericiyle aynı / same as the transmitter
13JoystickData data;
14Servo servo;
15unsigned long lastPacket = 0;
16
17void setup() {
18  pinMode(4, OUTPUT);                     // LED çıkışı / LED output
19  servo.attach(3);                        // servo sinyal pini / servo signal pin
20  if (!radio.begin()) {
21    while (true) {}
22  }
23  radio.setChannel(76);
24  radio.setDataRate(RF24_250KBPS);
25  radio.setPALevel(RF24_PA_HIGH);
26  radio.setPayloadSize(sizeof(data));
27  radio.openReadingPipe(1, address);
28  radio.startListening();                 // alıcı modu / RX mode
29}
30
31void loop() {
32  if (radio.available()) {
33    radio.read(&data, sizeof(data));
34    servo.write(map(data.x, 0, 1023, 0, 180));   // X ekseni -> servo açısı / X axis -> servo angle
35    digitalWrite(4, data.button ? HIGH : LOW);   // buton LED'i yakar / button lights the LED
36    lastPacket = millis();
37  }
38  if (millis() - lastPacket > 500) {      // 0,5 sn paket yok: güvenli konum / no packet for 0.5 s: failsafe
39    servo.write(90);
40    digitalWrite(4, LOW);
41  }
42}

Verici saniyede 20 paket gönderir; alıcı her pakette X eksenini 0–180 dereceye çevirip servoya yazar. Alıcıdaki güvenli konum (failsafe) bölümü çok önemlidir: kumandanın pili biterse ya da menzil dışına çıkarsan son komut sonsuza kadar uygulanmaz, 0,5 saniye paket gelmezse servo ortalanır ve LED söner. Robot araba yapıyorsan aynı yerde motorları durdurmalısın. Servoyu Arduino'nun 5 V pininden değil ayrı bir 5 V kaynaktan beslemek, servonun çektiği akım darbelerinin nRF24L01'i rahatsız etmesini de önler. Y eksenini bir L298N motor sürücüsüne bağlayarak kablosuz bir robot araba yapabilirsin; servo ayrıntıları için Servo motor nedir yazısına bakabilirsin.

Çift yönlü haberleşme ve birden fazla verici

nRF24L01 aynı anda hem gönderip hem dinleyemez, ama çift yönlü haberleşmenin kolay bir yolu var: ACK payload, yani onay paketinin içinde veri göndermek. Alıcı, writeAckPayload() ile bir sonraki onaya ekleyeceği veriyi (örneğin pil gerilimi ya da sensör değeri) önceden hazırlar; verici write() başarılı olduktan sonra available() ve read() ile bu cevabı okur. Bunun için iki tarafta da enableDynamicPayloads() ve enableAckPayload() çağrılmalıdır. Birden fazla verici için alıcının 6 borusu vardır: 0 ve 1. borular tam 5 baytlık adres alır, 2–5. borular ise 1. borunun adresiyle aynı gövdeyi paylaşır ve yalnızca bir baytta ayrılır. RF24'te bu bayt adres dizisinin ilk karakteridir; bu yüzden "1Node", "2Node", "3Node" gibi yalnızca ilk karakteri farklı adresler kullanılır. Daha büyük ağlar için RF24Network ve RF24Mesh kütüphaneleri vardır.

ESP32 ile nRF24L01 bağlantısı

ESP32'de RF24 kütüphanesi aynen çalışır ve radio.begin() varsayılan VSPI hattını kullanır: SCK = GPIO 18, MISO = GPIO 19, MOSI = GPIO 23. CSN için GPIO 5, CE için GPIO 4 iyi bir seçimdir. ESP32 DevKit kartlarındaki 3,3 V regülatör Uno'nunkinden güçlüdür, yine de 10 µF kondansatörü atlama. ESP32-C3 ya da ESP32-S3 gibi modellerde varsayılan SPI pinleri farklıdır, kartının pin haritasına bakmalısın. ESP32'nin Wi-Fi'si de 2,4 GHz'de çalıştığı için ikisini birlikte kullanıyorsan nRF24L01 kanalını modemin Wi-Fi kanalından uzak seç. Aşağıdaki kod, joystick vericisinden gelen paketleri ESP32'de okur; aynı yapıyla ESP32'yi nRF24L01 düğümlerinden gelen veriyi internete aktaran bir ağ geçidi olarak kullanabilirsin. ESP32 kartını yeni tanıyorsan ESP32 nedir yazısıyla başla.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3
4struct __attribute__((packed)) JoystickData {   // packed olmasa 6 bayt olurdu / 6 bytes without packed
5  int16_t x;
6  int16_t y;
7  uint8_t button;
8};
9
10RF24 radio(4, 5);                         // CE = GPIO 4, CSN = GPIO 5 pinleri / CE = GPIO 4, CSN = GPIO 5 pins
11const uint8_t address[6] = "JOY01";
12JoystickData data;
13
14void setup() {
15  Serial.begin(115200);
16  if (!radio.begin()) {                   // varsayılan VSPI: SCK 18, MISO 19, MOSI 23 / default VSPI pins
17    Serial.println("nRF24L01 bulunamadi!");
18    while (true) delay(1000);
19  }
20  radio.setChannel(76);
21  radio.setDataRate(RF24_250KBPS);
22  radio.setPALevel(RF24_PA_HIGH);
23  radio.setPayloadSize(sizeof(data));     // packed sayesinde 5 bayt / 5 bytes thanks to packed
24  radio.openReadingPipe(1, address);
25  radio.startListening();
26}
27
28void loop() {
29  if (radio.available()) {
30    radio.read(&data, sizeof(data));
31    Serial.printf("X=%d  Y=%d  Buton=%d\n", data.x, data.y, data.button);
32  }
33}

Yalnızca ESP32 kartları arasında haberleşeceksen ek modül gerektirmeyen ESP-NOW da iyi bir seçenektir; nRF24L01'in avantajı ise Uno, Nano, Pro Mini gibi ucuz ve az enerji harcayan kartlarla da çalışmasıdır.

Raspberry Pi Pico ve MicroPython ile nRF24L01

Pico'da MicroPython için resmi micropython-lib deposundaki nrf24l01.py sürücüsü kullanılır. Dosyayı Thonny ile Pico'ya kopyalayabilir ya da bilgisayarında mpremote mip install nrf24l01 komutuyla kurabilirsin. Bağlantı SPI0 üzerindendir: SCK = GP2, MOSI = GP3, MISO = GP4, CSN = GP5, CE = GP6 ve VCC = 3V3(OUT). Sürücünün varsayılanları RF24'ten farklıdır (kanal 46, paket boyu 16 bayt), bu yüzden Arduino ile konuşmak için kanalı, veri hızını ve paket boyunu kodda açıkça eşitliyoruz. Aşağıdaki kod joystick vericisinin paketlerini Pico'da çözer:

MicroPython
1from machine import Pin, SPI
2import struct
3import utime
4from nrf24l01 import NRF24L01, POWER_2, SPEED_250K
5
6spi = SPI(0, sck=Pin(2), mosi=Pin(3), miso=Pin(4))   # SPI0 pinleri / SPI0 pins
7csn = Pin(5, mode=Pin.OUT, value=1)                  # CSN pini GP5 / CSN pin GP5
8ce = Pin(6, mode=Pin.OUT, value=0)                   # CE pini GP6 / CE pin GP6
9
10nrf = NRF24L01(spi, csn, ce, channel=76, payload_size=5)   # Arduino ile aynı / same as the Arduino
11nrf.set_power_speed(POWER_2, SPEED_250K)             # -6 dBm güç, 250 kbps / -6 dBm power, 250 kbps
12nrf.open_rx_pipe(1, b"JOY01")                        # vericinin adresi / transmitter address
13nrf.start_listening()                                # alıcı modu / RX mode
14print("Dinleniyor... / Listening...")
15
16while True:
17    if nrf.any():                                    # paket geldi mi? / packet waiting?
18        x, y, button = struct.unpack("<hhB", nrf.recv())   # 2 + 2 + 1 bayt / 2 + 2 + 1 bytes
19        print("X:", x, "Y:", y, "Buton:", button)
20    utime.sleep_ms(5)

struct.unpack("<hhB") ifadesi gelen 5 baytı iki adet 16 bitlik işaretli sayıya ve bir bayta çevirir; baştaki "<" işareti, AVR ve ESP32'nin kullandığı little-endian bayt sırasını belirtir. Modül bulunamazsa sürücü "nRF24L01+ Hardware not responding" hatası verir; bu, Arduino'daki begin() false durumunun MicroPython karşılığıdır. Pico'ya yeni başlıyorsan önce Raspberry Pi Pico nedir yazısına göz at.

radio.begin() false dönüyor: adım adım çözüm

Seri Port Ekranı'nda "nRF24L01 bulunamadi" ya da RF24 örneklerindeki "radio hardware is not responding!!" mesajını görüyorsan Arduino modülle SPI üzerinden hiç konuşamıyor demektir. Bu durumda sorun neredeyse her zaman kablolamada ya da beslemededir, kodda değil. Önce aşağıdaki teşhis kodunu yükle; modülün tüm ayarlarını okunur biçimde yazdırır.

C++ (Arduino IDE)
1#include <SPI.h>
2#include <RF24.h>
3#include "printf.h"                       // RF24 ile gelir / ships with RF24
4
5RF24 radio(9, 10);                        // kendi CE, CSN pinlerin / your CE, CSN pins
6
7void setup() {
8  Serial.begin(115200);
9  printf_begin();                         // printPrettyDetails için / needed for printPrettyDetails
10  bool ok = radio.begin();
11  Serial.print(F("begin(): "));
12  Serial.println(ok ? "true" : "false");
13  Serial.print(F("isChipConnected(): "));
14  Serial.println(radio.isChipConnected() ? "true" : "false");
15  radio.printPrettyDetails();             // tüm ayarları yazdır / print every setting
16}
17
18void loop() {
19}
  1. MOSI ve MISO'yu kontrol et: En sık karışan iki kablodur. Uno ve Nano'da MOSI = D11, MISO = D12, SCK = D13; Mega'da 51, 50 ve 52 olmalıdır.
  2. CE ve CSN koddakiyle aynı mı: RF24 radio(9, 10) yazdıysan CE D9'a, CSN D10'a gitmeli. RF24'ün GettingStarted örneği 7 ve 8 numaralı pinleri kullanır; örneği değiştirmeden deniyorsan kabloları ona göre tak.
  3. Besleme 3,3 V mu: Multimetreyle VCC ile GND arasını ölç, 3,0–3,6 V görmelisin. Modül daha önce 5 V'a bağlandıysa bozulmuş olabilir.
  4. printPrettyDetails çıktısına bak: Adresler ve register değerleri hep 0x00 ya da 0xff görünüyorsa SPI hattı çalışmıyordur. Değerler mantıklı ama haberleşme yoksa sorun CE pininde, ayarlarda ya da beslemededir.
  5. Kabloları kısalt, SPI hızını düşür: Uzun ya da gevşek kablolarda RF24 radio(9, 10, 4000000) yazarak SPI hızını varsayılan 10 MHz'den 4 MHz'e indir.
  6. Modülü değiştir: Her şey doğruysa yedek bir modülle dene; ucuz çoklu paketlerde arızalı modül çıkabilir.

Veri gelmiyor ya da kesik kesik geliyor: sık hatalar

BelirtiOlası sebepÇözüm
begin() true ama alıcıya hiç veri gelmiyorKanal, veri hızı, adres ya da paket boyu iki tarafta farklıDört ayarı iki kodda yan yana karşılaştır
Uno'dan ESP32'ye veri gelmiyorStruct boyu farklı (5 ve 6 bayt)Sabit boyutlu türler ve __attribute__((packed)) kullan
write() false ama alıcı veriyi alıyorAlıcının onayı vericiye ulaşmıyor, çoğu zaman alıcı tarafın beslemesiAlıcı modüle de 10 µF kondansatör ekle
Ekranda sürekli boş ya da anlamsız veriSPI kablosu gevşek ya da MISO kopukKabloları yenile, SPI hızını 4 MHz'e düşür
Modüller yan yanayken çalışmıyor, uzaklaşınca düzeliyorTam güçte alıcı doyuyorsetPALevel(RF24_PA_LOW) ya da RF24_PA_MIN kullan
Eline dokununca daha iyi çalışıyorKararsız besleme ya da kalkansız PA+LNAKondansatör, ayrı regülatör ve folyo kalkan
Birkaç metrede bağlantı kopuyor2 Mbps hız, zayıf besleme ya da Wi-Fi paraziti250 kbps, temiz besleme, 74–83 arası kanal
Sorun ararken her zaman en basit düzene dön: iki modül 1–2 metre arayla, RF24_PA_LOW, 250 kbps, kısa kablolar ve 10 µF kondansatör. Bu düzende çalışan bir bağlantı kurduktan sonra mesafeyi, gücü ve kodun karmaşıklığını adım adım artır; böylece sorunun hangi adımda başladığını hemen görürsün.

nRF24L01 ile proje fikirleri

  • Kablosuz robot araba kumandası: İki joystickli bir kumandayla robot arabayı onlarca metre öteden sür.
  • Bahçe sensör istasyonu: Toprak nem sensörü ve sıcaklık verisini pille çalışan bir vericiden evdeki ekrana gönder. radio.powerDown() ile modül uykuda yaklaşık 900 nA çeker; pil ömrünü Pil ömrü aracıyla hesaplayabilirsin.
  • Kablosuz kapı ve hareket alarmı: Bir PIR sensörü ya da reed röle tetiklendiğinde merkezdeki buzzer'ı çaldır.
  • Çok odalı sıcaklık ağı: Altı odadaki sensörün verisini altı boru üzerinden tek bir alıcıda topla.
  • ESP32 ağ geçidi: nRF24L01 düğümlerinden gelen verileri ESP32 ile internete, telefona ya da bir izleme paneline aktar.
  • Kablosuz skor tabelası: Butonlu kumandalarla spor salonundaki 7 segment tabelayı uzaktan güncelle.

nRF24L01 uygun fiyatına rağmen Bluetooth'tan daha uzun menzil, daha düşük gecikme ve çoklu cihaz desteği sunar; tek şartı temiz bir 3,3 V besleme ve iki tarafta eşleşen ayarlardır. Telefondan kontrol istiyorsan HC-05 Bluetooth modülü, kilometrelerce menzil gerekiyorsa LoRa daha uygun olabilir; seçeneklerin karşılaştırması Arduino kablosuz haberleşme modülleri yazısında. BlueGrays uygulamasında iki Arduino arasında haberleşme, joystick ile servo ve LED kontrolü ve uzaktan kumandalı araba gibi projeleri devre şemaları ve hazır kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

nRF24L01 menzili kaç metre?

Standart PCB antenli nRF24L01+ açık alanda 250 kbps hızla yaklaşık 50–100 metreye, ev içinde ise duvarlara bağlı olarak 10–30 metreye ulaşır. Antenli nRF24L01+PA+LNA sürümü açık ve engelsiz alanda 800–1100 metreye kadar çıkabilir. Bu değerler için temiz bir 3,3 V besleme, 10 µF kondansatör ve düşük veri hızı gerekir.

nRF24L01 5V ile çalışır mı?

Hayır, VCC pini 1,9–3,6 V arasında çalışır ve 5 V yongayı bozabilir. Buna karşın CE, CSN, SCK ve MOSI giriş pinleri 5 V'a dayanıklıdır, bu yüzden Arduino Uno'nun SPI pinlerine seviye dönüştürücü olmadan bağlanabilir. Modülü 5 V'tan beslemek istiyorsan AMS1117-3.3 regülatörlü bir soket adaptörü kullan.

"radio hardware is not responding" hatası neden çıkar?

Bu mesaj radio.begin() false döndüğünde yazılır ve Arduino'nun modülle SPI üzerinden konuşamadığını gösterir. En sık sebepler yer değiştirmiş MOSI ile MISO, koddakinden farklı CE ve CSN pinleri, yetersiz ya da 5 V'luk besleme ve gevşek jumper kablolardır. Kabloları kontrol edip printPrettyDetails() çıktısına bakarak sorunu daraltabilirsin.

nRF24L01 mi HC-05 Bluetooth mu?

İki Arduino arasında uzun menzil, düşük gecikme ve birden fazla cihaz gerekiyorsa nRF24L01 daha iyidir. Telefondan kontrol edeceksen HC-05 gibi bir Bluetooth modülü ya da ESP32 seçmelisin, çünkü telefonlar nRF24L01'in protokolünü konuşmaz. HC-05'in menzili genelde 10 metre civarındayken nRF24L01 benzer fiyata çok daha uzağa ulaşır.

Bir nRF24L01 alıcı kaç vericiyi dinleyebilir?

Bir alıcı aynı anda 6 boruyu (pipe) dinleyebilir, yani doğrudan 6 vericiden veri toplayabilir. 2–5 numaralı borular 1. borunun adres gövdesini paylaşır ve yalnızca bir baytta ayrılır. Daha fazla düğüm için vericileri sırayla sorgulayabilir ya da RF24Network ve RF24Mesh kütüphaneleriyle çok daha büyük ağlar kurabilirsin.

nRF24L01 telefona bağlanabilir mi?

Doğrudan bağlanamaz; nRF24L01 aynı 2,4 GHz bandında çalışsa da Wi-Fi ya da Bluetooth protokolünü kullanmaz. Telefon kontrolü istiyorsan nRF24L01 ağının merkezine bir ESP32 koyup veriyi Wi-Fi ya da Bluetooth üzerinden telefona aktarabilirsin. Böylece uzak düğümler nRF24L01 ile, telefon ise ESP32 ile konuşur.

Tüm projeleri gör
2 Arduino Tek Yönlü Haberleşme
#57Orta
Premium

2 Arduino Tek Yönlü Haberleşme

İki Arduino'yu tek bir kabloyla konuşturursun: birindeki butona basınca öbüründeki LED yanar, bir daha basınca söner. Gönderen kart butona basıldığını kısa bir mesajla bildirir, alan kart bu mesajı du

4.4(37)
50
2 Arduino Çift Yönlü Haberleşme
#58Orta
Premium

2 Arduino Çift Yönlü Haberleşme

İki Arduino kabloyla birbirine bağlanıp konuşur: birinin butonuna basınca öbürünün ışığı yanar, yeniden basınca söner. İki kartta da aynı program çalışır, yani ikisi de hem haber gönderir hem haber al

4.5(20)
26
Joystick İle Led Kontrol
#59Orta
Premium

Joystick İle Led Kontrol

Oyun kolundaki küçük çubuğu hangi yöne sonuna kadar itersen o yöndeki LED yanar: sağ, sol, yukarı ve aşağı için dört ayrı renk var. Çubuğu bıraktığında ortaya döner ve bütün LED'ler söner. Robot araba

4.7(50)
67
Joystick İle Servo Kontrol
#60Orta
Premium

Joystick İle Servo Kontrol

Bir oyun kolu çubuğuyla iki motoru yönet, tıpkı bir güvenlik kamerasını çevirir gibi. Çubuğu sağa sola ittiğinde alttaki servo motor yavaşça döner, yukarı aşağı ittiğinde üstteki servo başını kaldırıp

4.7(42)
58
L298N ile Bluetooth Kontrollü Araba
#80İleri
Premium

L298N ile Bluetooth Kontrollü Araba

Telefonunu kumandaya çevirip kendi robot arabanı sür. Arduino, Bluetooth modülü üzerinden telefondaki bir kumanda uygulamasından gelen komutları alır ve motor sürücüyle tekerlekleri döndürür; araba il

5.0(38)
65
Bluetooth İle Telefondan Led Yakma
#34Başlangıç
Premium

Bluetooth İle Telefondan Led Yakma

Telefonundan odadaki ışıkları açıp kapatmanın küçük bir provası. Bluetooth modülü telefondan gelen harfleri Arduino'ya iletir; bir harf kırmızı LED'i, başka bir harf yeşil LED'i yakar, aynı harflerin

4.8(68)
89
IR Alıcı Ve Kumanda İle Led Açma Kapatma
#17Orta
Premium

IR Alıcı Ve Kumanda İle Led Açma Kapatma

Koltuktan kalkmadan üç ayrı lambayı yönetmek gibi: kumandanın 1, 2 ve 3 tuşları mavi, kırmızı ve yeşil LED'i yakar, 4, 5 ve 6 tuşları aynı sırayla söndürür. Güç tuşu üçünü birden yakar, sessiz tuşu he

4.7(45)
66
ESP32 IR Universal Remote (IR Alıcı + Kumanda + 3 LED + Buzzer + OLED)
#143İleri
Premium

ESP32 IR Universal Remote (IR Alıcı + Kumanda + 3 LED + Buzzer + OLED)

ESP32 ile hazır bir IR uzaktan kumandayı okuyup kendi cihazını kontrol edebilirsin! Bu projede kızılötesi alıcı (NEC protokolü 38kHz) ile 20 tuşlu bir IR kumandanın sinyallerini yakalıyoruz. Her tuş için farklı aksiyon tanımladık: 1/2/3 tuşları üç ayrı LED'i toggle eder, PWR tuşu hepsini söndürür, 4-9 rakamları OLED'de özel gösterim yapar. SSD1306 OLED ekranda basılan son tuş büyük fontla, yapılan aksiyon açıklaması ve LED durumu canlı gösterilir. Bilinmeyen bir tuş basıldığında OLED'de HEX kodu

4.5(9)
16