아두이노 기본실습 10 - NRF24L01 무선통신 실험

NRF24L01은 2.4~2.5GHz 주파수 대역을 사용하는 무선통신 칩으로서 SPI통신으로 출력파워와 채널, 프로토콜을 설정할 수 있습니다. 10mA 정도의 저전력 디바이스로 파워다운모드나 스텐바이모드시에는 전력소모를 최소화가 가능합니다.

NRF24L01모듈은  통신거리가 최대 250미터인 기본모듈과 최대 1KM까지 가능한 NRF24L01+PA+LNA 모듈이 판매되고 있으며 사용방법은 동일합니다.

실제 환경에서는 여러가지 장애물과 통신장벽에 의해 통신 거리가 짧아집니다.

여기서는 NRF24L01 모듈 2개와 아두이노 보드 2개 가변저항을 가지고 실험합니다.

송신부와 수신부로 나누고 송신부에서는 가변저항으로부터 아날로그 전압값을 읽어서 송신하며 수신부에서는 수신한 데이터를 시리얼모니터를 통해 화면에 출력합니다.

아래는 일반적인 NRF24L01모듈입니다.

 

NRF24L01과 아두이노 보드와의 결선방법

  • VCC --> 3.3V
  • GND --> GND
  • CE   --> D9
  • CSN --> D10
  • MOSI--> D11
  • MISO--> D12
  • SCK --> D13
  • IRQ --> 사용안함

송신부 및 수신부 모두 동일한 방법으로 결선합니다.

주의사항 : NRF24L01모듈의 VCC전압은 3.3V입니다. 5V에 결선하지 않도록 주의하십시요.

송신부 결선도

송신부는 아래와 같이 10K옴 가변저항을 추가로 결선합니다.

 

수신부 결선도

 

아래는 소스컴파일에 필요한 NRF24L01용 아두이노 라이브러리 입니다.

라이브러리

송신부 소스코드

아래는 송신부 소스코드입니다. 아두이노 IDE에 붙여넣기 하여 컴파일하고 업로드해봅니다.


/*
 * NRF24L01_SEND 송신측
 */

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>


void setup()
{
    Serial.begin(9600);

    Mirf.cePin = 9;   //CE핀
    Mirf.csnPin = 10; //CS핀
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  // nRF24L01 초기화

    //송수신에 사용할 바이트 수 지정 sizeof(unsigned int) 는 2바이트
    Mirf.payload = sizeof(unsigned int);
    //송수신 채널 지정(0~128), 송수신 모듈이 동일한 채널을 사용해야함
    Mirf.channel = 3;
    Mirf.config();
    //송신기표시
    Serial.println("NRF24L01_SEND");
}
unsigned int adata = 0;
void loop()
{
    //A0의 아날로그 값을 읽어옴
    adata = analogRead(A0);

    //송신할 데이터 버퍼 정의
    byte data[Mirf.payload];

    //아날로그 데이터를 송신할 바이트 어레이에 저장
    data[0] = adata & 0xFF;   //하위바이트
    data[1] = adata >> 8;     //상위바이트

    //수신측 어드레스 지정 및 데이터 송신
    Mirf.setTADDR((byte *)"TX_01");
    Mirf.send(data);
    //데이터가 송신이 완료될 때가지 대기
    while(Mirf.isSending()) {}
    delay(20);
}

수신부 소스코드

아래는 수신부 소스코드입니다. 아두이노 IDE에 붙여넣기 하여 컴파일하고 업로드해봅니다.


/*
 * NRF24L01_RECEIVE 수신측
 */

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

unsigned int adata = 0, oldadata = 0;

void setup()
{
    Serial.begin(9600);

    Mirf.cePin = 9;   //CE핀
    Mirf.csnPin = 10; //CS핀
    Mirf.spi = &MirfHardwareSpi;
    Mirf.init();  // nRF24L01 초기화

    //수신측 어드레스 설정
    Mirf.setRADDR((byte *)"TX_01");
    //송수신에 사용할 바이트 수 지정 sizeof(unsigned int) 는 2바이트
    Mirf.payload = sizeof(unsigned int);
    //송수신 채널 지정(0~128), 송수신 모듈이 동일한 채널을 사용해야함
    Mirf.channel = 3;
    Mirf.config();

    //수신기표시
    Serial.println("NRF24L01_RECEIVE");
}

void loop()
{
    //수신할 데이터 버퍼 정의
    byte data[Mirf.payload];
    if(Mirf.dataReady())    //데이터수신 대기
    {
        Mirf.getData(data);    //수신 데이터를 data에 저장
        //데이터 버퍼를 통합
        adata = (unsigned int)((data[1] << 8) | data[0]);

        //이전 데이터와 동일여부 확인 시리얼통신 과부하 방지
        //이전 데이터와 다른 경우만 표시함
        if(adata != oldadata)
        {
            oldadata = adata; //oldadata로 복사
            //수신 데이터 표시
            Serial.print("A0=");
            Serial.println(adata);
        }

    }
}

아래는 실제 결선하여 테스트한 모습입니다.

아래는 송신부 아두이노 보드를 PC와 연결한 후 아두이노 IDE의 시리얼모니터로 수신된 데이터를 보여주고 있습니다.