Arduino ile NRF24L01 uygulaması

Arduino kullanım kolaylığı ve kütüphane zenginliği ile hızlı yükselişini sürdürüyor. Bu yazımızda Arduino ile NRF24L01 çipini birlikte kullanarak kablosuz veri aktarımı uygulaması yapacağız. NRF24L01 Nordic Semiconductor'un geliştirdiği düşük fiyatlı sayısal bir kablosuz alıcı verici çip. Piyasada daha çok 433MHz lik alıcı verici modüller görebilirsiniz. Eğer kısa mesafe örneğin 10-20 metreler işinizi görecekse 2.4GHz frekansında çalışan NRF24L01 433MHz lik bu modüllere göre hem tutarlı çalışma hem de enerji tüketimi bakımından tercih edilebilir. NRF24L01 modüllü ayrıca fiyat bakımından da çok rekabetçi. 5-10TL gibi fiyatlarla bu modüllerden temin edebilirsiniz.

Bağlantı pinlerini kodun üst kısmında yorum bölümünde görebilirsiniz. Bağlantı için besleme pinleri dahil 7 pin yeterli. Modül SPI arayüzünü kullanıyor. 3 pin SPI bağlantısı için kullanılıyor. 2 pin çipin ve RF kısmının aktifleştirilmesi için kullanılıyor. 2 pin de besleme ve toprak olarak kullanılıyor. Uygulamaya bağlı olarak SPI ve çip seçme pinleri değiştirilebilir.

Kütüphanenin kendi örneklerinde alıcı ve verici kodları ayrı ayrı yazılmış. Kütüphaneyi buradan indirebilirsiniz. Aşağıdaki örnekte çip önce alıcı moduna ayarlanıyor ve 5sn kadar bu modda dinleme yapıyor. Eğer aynı kanal anahtarı ile yayın yapan bir verici varsa alıcı modunda kalıyor. Eğer 5sn içinde bir bilgi yakalayamazsa verici moduna geçiyor ve kendisi paket göndermeye başlıyor. Alıcı ve verici modları arasındaki geçiş 't' ve 'r' tuşları ile sağlanıyor. Aşağıdaki ekran görüntüsünde görebilceğiniz gibi seri port monitörü olarak putty ve arduinonun dahili port monitörü kullanılmıştır. Verici modül arduinonun açılışından itibaren geçen zamanı yayın yapacak şekilde programlandı. Alıcı - verici mod değişimlerindeki paket numaralarında oluşan değişikliğe dikkat ederseniz her iki modülün farklı zamanlarda açıldığını görebilirsiniz.

 

/**
 * An Mirf example which copies back the data it recives.
 *
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 *
 */
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#define  IDL    0
#define  TXD    1
#define  RXD    2

void InitMirf(void);
int CheckConnection (void);
byte TXbuffer[16];
byte RXbuffer[16];
byte RXbyte=0;
byte TXbyte=0;
byte TXmode = IDL;

byte prevstate = TXmode;
boolean forceIDL = false;
int  errorcnt=0;
int  idlcnt = 0;
unsigned long time;

void setup(){
  Serial.begin(9600);
 
  InitMirf();
  time = millis();
  if(0 == CheckConnection()){
    Serial.println("RF module OK");
    Serial.println("Ready to communicate");
    Serial.println("enter 't' for transmit mode or 'r' for receive mode");
    Serial.println("enter 'c' to check connection");
    Serial.println("Mode will be set to RXD in 5 sec");
    Serial.println("Mode will be set to TXD in next 5 sec if no packet received");
  }
 
  else Serial.println("Check RF module Connection");  
}void loop(){
  if(Serial.available() > 0){
    RXbyte = Serial.read();
    switch (RXbyte){
      case 't':
         prevstate = TXmode;
         TXmode = TXD;
         if(0 != CheckConnection()) InitMirf();
         Serial.println("TX mode activated");
         break;
       case 'r':
         prevstate = TXmode;
         if(0 != CheckConnection()) InitMirf();
         TXmode = RXD;
         Serial.println("RX mode activated");
         break;
       case 's':
         prevstate = TXmode;
         TXmode = IDL;
         forceIDL = true;
         Serial.println("IDLE mode activated");
         break;
       case 'c':
         InitMirf();
         if(0 == CheckConnection()) Serial.println("connection OK");
         else Serial.println("Check RF Connection");
       default:
           break;
    }       
  }
  if(millis() - time > 999){
    time = millis();
    switch(TXmode){
      case TXD:
        Mirf.send((byte *)&time);
        while(Mirf.isSending());
        Serial.print("T-");
        Serial.println(time, DEC);
        break;
      case RXD:
        if(!Mirf.isSending() && Mirf.dataReady()){
          while(Mirf.dataReady()){
            Mirf.getData(RXbuffer); //Get load the packet into the buffer.
            unsigned long rcvdtime=0;
            rcvdtime = RXbuffer[3];
            rcvdtime <<= 8;
            rcvdtime |= RXbuffer[2];
            rcvdtime <<= 8;
            rcvdtime |= RXbuffer[1];
            rcvdtime <<= 8;
            rcvdtime |= RXbuffer[0];
            if (0==rcvdtime) break;
            Serial.print("R-");
            Serial.println(rcvdtime, DEC);
          }
        }
        else{
          Serial.print("Listening");
          Serial.print('\r');
          if(idlcnt++ > 5){
            Serial.print("\r\n");
            Serial.println("Changing state to TXD");            
              idlcnt = 0;
              prevstate = TXmode;
              TXmode = TXD;
            }
          if(0 != CheckConnection()){
            if(errorcnt++ > 5) {
              Serial.println("No response from RF module");
              Serial.println("Switching to idle state");
              prevstate = TXmode;
              TXmode = IDL;
            }
          }
        }
       break;
      case IDL:
        errorcnt = 0;
        if(forceIDL != true){
          if(idlcnt++ % 5){
            Serial.println("Testing RF module");
            InitMirf();
            if(0 == CheckConnection()){
              idlcnt = 0;
              TXmode = RXD;
            }
          }
        }
        break;
    }
  }
}
void InitMirf(void){
  Mirf.spi = &MirfHardwareSpi; //init SPI
  Mirf.init(); // Init RF unit
  Mirf.setRADDR((byte *)"el.ar"); //Set receive address
  Mirf.setTADDR((byte *)"el.ar"); // Set transmit address
  Mirf.payload = sizeof(unsigned long); // Set Payload length. Transmiter and Receive must be same
  Mirf.config(); //Write channel and payload config then power up reciver.
}
int CheckConnection (void){
  int ret = 0;
  byte tempbuf[5];
  Mirf.readRegister(RX_ADDR_P0, tempbuf, 5);
  TXbuffer[0] = 'e';
  TXbuffer[1] = 'l';
  TXbuffer[2] = '.';
  TXbuffer[3] = 'a';
  TXbuffer[4] = 'r';
  for(int i = 0; i<5;i++){
    if(tempbuf[i] != TXbuffer[i]) ret = -1;
  }
  return ret;
}

 

Konu ile ilgili bilgi için