İki Arduino (veya başka mikrodenetleyici) arasında kablosuz haberleşme yöntemlerinden biri nRF24L01 isimli modül kullanmak. Bu modül Nordic firması tarafından üretilen radyo frekanslarını kullanarak kendi arasında haberleşebiliyor. Alıcı ya da verici olarak kullanılabiliyor. O yüzden yabancı kaynaklarda “verici” (transmitter) ve “alıcı” (reciever) kelimelerinin birleştirilmesiyle “tranciever” adıyla da anılıyor. İki arduino iki modüle bağlanarak haberleşebiliyor. Bu modül kablosuz kumanda, klavye, fare, oyuncaklar,ev otomasyonu, güvenlik sistemleri, kablosuz veri iletimi vb uygulamalarında kendisine yer buluyor. Ucuz ve hızlı olması nedeniyle tercih ediliyor. Güç tüketimi de oldukça az; 10mA civarında, bir LED’in tüketiminden az.
2.400 – 2.525 GHZ frekans aralığında çalışıyor. Bu aralık ISM (Industrial, Scientific, Medical) endüstriyel, bilimsel ve tıbbi araçların legal olarak çalışabileceği frekans aralığı. Yoksa radyo frekanslarında kafanıza esen frekansta yayın yapmak kanuni değil. Zaten bu frekans aralığı; mikrodalga fırınların, bluetooth ve evdeki erişim noktalarının da çalıştığı aralık. Bu da bazen çakışmalara neden olabiliyor. Aynı ortamda birden fazla bağlantı oluşturulabiliyor. Bağlantı frekansındaki 1 MHZ lik aralıklar sayesinde 2.400 GHz ile 2.525 GHz arasında 126 farklı bağlantı hattı (kanal) kurulabiliyor. Örneğin iki modül 2.415 GHZ arasında çalışırken başka iki modül arasında 2.420 GHz frekansındaki bağlantı diğerini etkilemeden sağlıklı bir şekilde çalışabiliyor. Güzel bir özellik! Bitmedi: Her bir kanaldaki modül aynı anda altı diğer modülden veri alabiliyor.
Bu özellik sayesinde örneğin evin değişik odalarına kuracağınız istasyonlarla tüm odalardaki sıcaklığı bir noktadan takip edebilirsiniz.
Bu arada haberleşme hızı (baud rate) saniyede 250 kb ile 2 Mb arasında ayarlanabiliyor. Bu özelliklerin nasıl kullanılacağına kodlama bölümünde değineceğim.
Kartın fiziksel özelliklerine gelince; yaklaşık 3 cm x 1.5 cm. Smd parçalardan başka fiziksel olarak göze çarpan 16 MHz bir kristal ile ortada modüle de ismini veren ve tüm işi yapan nRF24L01 entegresi. Ayrıca 8 adet bağlantı pini var. Ve maalesef bu şekliyle board üzerinde kullanılamıyor. Prototip çalışmalarınızı mecburen dişi jumper kablolar ile yapmak zorundasınız. Parlak sarı renkte olan bölüm ise anten olarak tasarlanmış. Veri kağıdı bu şekilde evde 20 metreye, açık alanda ise 100 metreye kadar çıktığı söylenmiş. Ben anten bölümüne fazladan kablo ile anten ekledim ama sonuç pek değişmiyor (ama güç tüketimi artıyor). Bu arada bağlantı hızı da bu mesafeyi etkiliyor. Ne kadar hızlı bağlantı, o kadar düşük mesafe. Yani yukarıdaki menzile ulaşmak için hızı 250 Mbps olarak ayarlamak gerekli.
Bu arada bu modülün anten eklenmiş hali de var. 1km menzile kadar ulaştığından bahsediliyor. Kart üzerindeki antenin yerine standart anten konnektörü ve anten ile geliyor. Ayrıca sadece alıcı olarak kullanıldığında aktif olan bir düşük gürültülü yükselteç (LNA: Low Noise Amplifier) eklenmiş.Eğer elinizde bu modelden sadece bir tane varsa bunu alıcı tarafında kullanmak mantıklı olacaktır. Unutmadan her iki model de birbiriyle etkileşebiliyor.
Bu modelin sıkıntılı tarafı besleme gerilimi! Veri kağıdı 1.9 volt ile 3.6 volt arsında bir gerilimle çalıştığını söylüyor. Yani Arduino’nun 3.3 v çıkışına bağlanmalı. 5 voltun modüle zarar vereceği söylenmiş. Yani pro mini gibi 3.3 volt çıkışı olmayan mikrodenetleyici ile kullanmak isterseniz, ekstra gerilim kaynağına ihtiyaç olacaktır. Ayrıca maalesef bu değil. Arduino’dan 3.3 volt alıp bağlasanız da modül verimli çalışmayabiliyor. Özellikle Arduino’dan güç çekildiğinde problem çıkıyor. O yüzden besleme gerilimini dengelemek için modülün Vcc ve GND hatları arasına 1 μF (ya da daha küçük) kondansatör ekleniyor. Ama bu da çok verimli olmayabilir. Çözüm?
Yine çok pahalı olmayan bu adaptörü kullanmak en iyi seçenek. Zaten bu iş için yapılmış; soketlerine modülü takıyorsunuz oluyor. Adaptörün üzerinde 3.3 volt çıkışlı bir gerilim dönüştürücü var. Dolayısıyla modüle zarar vermeden verimli çalışmasını sağlıyoruz. Besleme ve GND pinleri de diğer pinlerden ayrı bir yere konumlandırılmış. Artık Vcc hattını Arduino’nun 5 volt çıkışına ya da direk besleme gerilimine bağlayabilirsiniz. Ama sizin de aklınıza gelmiyor mu? Madem böyle çözülebiliyor, neden modül üzerine bu gerilim dönüştürücü eklenerek geliştirilmiyor!
Gelelim Arduino bağlantılarına;
Modül Arduino’ya SPI (Serial Peripheril Interface) port üzerinden bağlanıyor. MOSI, MISO’ları görünce anladınız sanırım. Yandaki bağlantı, modül; anten yukarı gelecek şekilde tutulduğundaki haliyle pinleri gösteriyor. Yanında da bu pinlerin Arduino’nun hangi bacağına bağlanması gerektiği.Hatırlayalım;
MOSI: Arduino’dan modüle veri akışı hattı (modül için Rx olarak düşünün),
MISO: Modülden Arduino’ya veri akışı hattı (modül için Tx olarak düşünün),
SCK : Veri iletiminde kullanılan saat (SPI clock) hattı, olarak tanımlanmış olup Arduino modellerine göre tanımlanmış mecburi bağlantılarımızdır. (Yani buradaki 11, 12 ve 13 numaralı bacaklar, mega kullansak mecburen başka bağlantılar olacaktı)
CE : Modülü alıcı ya da verici olarak aktif eden pin (chip enable)
CSN : çip seçimi (SPI chip select), bu iki bağlantı Arduino’nun herhangi digital pinleri olabilir. Kod yazarken bunları belirtiyoruz zaten.
IRQ pini durdurma/kesme (interrupt) için kullanılıyor. Bu aşamada bizi ilgilendirmiyor, boş bırakıyoruz.
Benim örneğimde iki nRF24L01 modülünün bağlandığı iki Arduino’nun her birinde 3 numaralı pine LED, 4 numaralı pine buton bağlandı. Karşılıklı iletişimi göstermek için her buton diğer taraftaki LED’i kontrol ediyor. Yani görüntüye göre soldaki sarı buton, sağdaki sarı LED’i; sağdaki kırmızı buton ise soldaki kırmızı LED’i kontrol ediyor. Yani her iki taraf da hem alıcı hem verici.
Önce kütüphaneleri yüklememiz gerekiyor. SPI kütüphanesi Arduino IDE üzerinde var zaten. nRF24L01 için de kütüphenenin zip halini buradan indirip, Arduino IDE ye eklememiz gerekiyor.
Bu arada bu işlemlerin hem alıcı hem de verici tarafında aynı olduğunu da belirtmeliyim. Zaten ben de her iki taraf da hem alıcı hem verici.
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
Sonra ‘RF24 radio(9, 10);‘ komutu ile “radio” ismli bir nesne oluşturuyoruz. Parantez içindeki pinler sırasıyla CE ve CSN nin bağlantıları. Ben CE’yi 9, CSN’yi 10 numaralı pine bağladım.
Setup kısmında ‘radio.openWritingPipe(addresses[1]);’ komutu ile veri yollamak için, ‘radio.openReadingPipe(1, addresses[0]);‘ komutu ile de veri almak için hat (pipe:boru) açıyoruz. Ben hem veri alıp hem de veri yolladığım için iki hat açtım. Buradaki adresler de setup’dan önce tanımlandı: ‘const byte addresses[][6] = {“00001”, “00002”};‘ Adresin biri ‘00001’, diğeri ‘0002’ tabi alıcı verici olarak diğer kodda bunların yeri tam tersine. Burada hemen söyleyeyim: kodlar aynı da olsa birinde alıcı olarak belirlene şartlar ve komutlar, diğer Arduino için verici hattında olmalı! Yine setup içerisinde veri hızını belirliyoruz. İki modül yakın olduğundan 250 kbps seçildi: ‘radio.setDataRate (RF24_250KBPS);‘ Burada yapılacak seçimlerin biri de sinyal güç seviyesi. Yine mesafe yakın olduğundan “minimum” seçildi: ‘radio.setPALevel(RF24_PA_MIN);‘ Buradaki son seçim de kanal seçimi. Hani bahsetmiştik ya 126 kanal seçebiliyorduk. Burada rastgele 15 olsun dedim: ‘radio.setChannel(15);‘ Sadece iki modül olduğundan kanal seçimi ve hız seçeneklerini gösteren satırlar olmadan da program çalıştı.
void loop() {
delay(5);
radio.startListening();
while (!radio.available());
radio.read(&buttonStateS, sizeof(buttonStateS));
if (buttonStateS == HIGH) {
digitalWrite(ledSari, HIGH);
}
else {
digitalWrite(ledSari, LOW);
}
delay(5);
radio.stopListening();
buttonStateK = digitalRead(buttonKirmizi);
radio.write(&buttonStateK, sizeof(buttonStateK));
}
Gelelim void loop’a. Yukarıda kod bölümü sırasıyla karşı taraftan veri alma moduna geçiyor, veri akışı sağlandığı sürece sarı butona basılıp basılmadığını kontrol ediyor. Eğer sarı butona basıldıysa sarı LED’i yakıyor, değilse söndürüyor. 5 ms sonra dinlemeyi kapatıp kırmızı butona basılıp basılmadığı bilgisini karşı tarafa yolluyor. Bu kadar! Aynı kodun diğer tarafındaki versiyonu ise:
void loop() {
delay(5);
radio.stopListening();
buttonStateS = digitalRead(buttonSari);
radio.write(&buttonStateS, sizeof(buttonStateS));
delay(5);
radio.startListening();
while (!radio.available());
radio.read(&buttonStateK, sizeof(buttonStateK));
if (buttonStateK == HIGH) {
Serial.println(“verici ok”);
digitalWrite(ledKirmizi, HIGH);
}
else {
digitalWrite(ledKirmizi, LOW);
}
}
Burada da önce veri almayı kesip, sarı butona basılıp basılmadığı bilgisini karşı tarafa yolluyor. Sonra 5 ms sonra karşıdan veri almaya başlıyor. Veri olduğu sürece kırmızı buton durumu okunuyor. Eğer butona basılı ise kırmızı LED’i yakıyor, değilse yakmıyor.
Devre şeması birebir aynı. Sadece butonlar ile LED’lerin renkleri ters. Fritzing şeması aşağıdaki gibi. (Tabi ben soket adaptör kullandığım için Vcc’yi 5 volt hattına bağladım. Ayrıca fazladan bir modül ekledim ki üzerindeki bağlantıların isimleri de okunabilsin)
Bu girişten sonra emin olabilirsiniz ki bu modül birçok projede kullanılabilir. Umuyorum yakında kullanırız.
Hoşça kalın…
Kaynak Linkler:
Kevin Darrah: https://www.youtube.com/watch?v=hI4JGDB7WtU&t=1254s
DroneBot Workshop: https://www.youtube.com/watch?v=lhGXAJj8rJw
Andreas Spiess : https://www.youtube.com/watch?v=61kWj6zu4Uw
educ8s.tv: https://youtu.be/D40cgHyBLL4
https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/
nRF24L01 Kütüphanesi
Data Sheet: nRF24L01