아두이노2017. 11. 4. 23:38

지난 글 (http://deneb21.tistory.com/546) 에서는 433Mhz 통신 모듈을 테스트 해 보았는데 통신거리가 별로 신통하지 않았었다. 일단 통신거리가 너무 짧았고 양방향 통신도 지원하지 않았다. 딱 한 가지 장점은 가격이 매우 싸다는 것.  무선 통신 모듈이 통신거리가 짧으면 아무짝에도 쓸모가 없다. 이러한 단점을 어느 정도 보완해 줄 수 있는 모듈이 NRF24L01 이다. 이 모듈은 여러가지 버전이 있는데 내가 구입한 것은 1km 정도까지 통신이 가능하다고 광고하는 안테나 달린 버전이다. (1km? 과연?) 무선 와이파이 공유기와 같은 2.4Ghz 대역으로 통신을 하고 SPI 통신을 하므로 양방향 송수신이 가능하다.  또한 1:n 통신도 가능하다. 


하나의 마스터가 슬레이브들에게 데이터를 보내거나 여러개의 슬레이브가 하나의 마스터에게 데이터를 보내는 것도 가능한 것이다. 여러모로 433Mhz 모듈 보다는 많이 발전된 칩이고 모듈이다.


모듈은 위와 같은 구성으로 되어 있다. 공유기 같은데 들어가는 안테나이다. 이런 외장안테나 버전 이외에도 기판에 안테나가 프린트되어 있는 버전도 있다.


안테나가 내장된 NRF24L01 모듈 아마도 외장 안테나 버전보다는 통신거리가 짧을 것이다.


모듈 기판의 모습니다. NRF24L01 칩이 보인다.


연결 단자의 모습이다. MISO, MOSI 가 있어서 마스터 슬레이브간 양방향 통신이 가능하다. 전원은 3.3V 를 이용한다.


반대편에서 본 연결 단자


일렬로 된 납땜 단자의 연결 배열이다.

 

nRF24L01+ 데이터시트


nRF24L01P_Product_Specification_1_0.pdf


 

■ 연결


두 개의 모듈로 테스트를 했으며 하나는 Receiver 역할로 아두이노 우노에 하나는 Sender 역할로 아두이노 나노에 연결했다. 전원은 아두이노 자체전원 3.3V에 연결했다. 전원 연결시 주의할 점이 있는데 모듈 전원 VCC 와 GND 사이에 1~10uF 의 콘덴서(보통 10uF 전해콘덴서)를 연결해서 노이즈를 제거해주어야 한다. 그러지 않으면 통신이 아예 되지 않을 수도 있다. 나의 경우도 그냥 연결하니 통신이 안됨. 그리고 데이터는 TMP36 온도센서를 이용해서 측정된 온도를 Receiver 로 보내 보았다.


 

nrf24l01_send.fzz

Sender 역할


 


nrf24l01_recv.fzz

Receiver 역할


각각의 연결은 위와 같다. 보다시피 Sender 와 Receiver 의 연결이 온도센서를 제외하면 같다. CE, CSN 은 변경이 가능하다.


 

■ 스케치


RF24 라는 라이브러리를 사용한다. 라이브러리 다운로드는 아래 링크에서 받아서 설치한다.

- RF24 라이브러리 : https://github.com/nRF24/RF24/tree/master

RF24-master.zip


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//Libraries for NRF24L01+ module.
#include <SPI.h>
#include <RF24.h>
 
//RF24 object with two pins defined with arguments. CE: 9, CSN: 10
RF24 radio(910);
 
//Address of the pipe. 40 bit long, you can choose this freely.
//Remember to use different address in different projects.
long long address = 0x1234ABCDEFLL;
int sensorPin = 0;
float temperature;
 
//Variable that selects whether the circuit is sender (1) or receiver (0)
bool sender = 0;
 
void setup() {
  //Start the radio
  Serial.begin(9600);
  radio.begin();
 
  if (sender) { //If sender
     radio.openWritingPipe(address);
    //RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
    //NRF24L01: -18dBm, -12dBm,-6dBM, and 0dBm
    radio.setPALevel(RF24_PA_LOW);
    radio.stopListening();
  } //If sender
  else { //If receiver
    //Open reading pipe with given address and start listening for incoming data
    radio.openReadingPipe(1, address);
    radio.startListening();
  } //If receiver
}
 
void loop() {
  if (sender) { //If sender
    //Get temperature from the sensor
    int reading = analogRead(sensorPin);
    float voltage = reading * 5.0;
    voltage /= 1024.0
    temperature = (voltage - 0.5* 100 ;
    
    //Send the temperature wirelessly, print error if failed
    if (!radio.write(&temperature, sizeof(temperature))) {
      Serial.println(F("Sending failed"));
    }
    delay(1000);
  } //If sender
  else { //If receiver
    //If data is available in radio's buffer
    if(radio.available()) {
      //While the data is available...
      while (radio.available()) {
        //Update temperature -variable with data from the radio module
        radio.read(&temperature, sizeof(temperature));
      }
      Serial.println(temperature);
    }
  } //If receiver
}
cs


하나의 소스로 Sender 와 Receiver 역할을 수행한다. 15행에 sender 변수값 1을 설정하면 Sender이고 0을 설정하면 Receiver 이다. 그러므로 두 개의 아두이노에 각각 1과 0 값으로 업로드 해야 한다. 


10행을 보면 파이프 방식 통신을 하므로 마스터와 슬레이브 간에 같은 어드레스를 사용해야 한다. 


26행을 보면 송신 전파 강도를 설정하는 부분이 있다. RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX 으로 설정할 수 있으며 좌에서 우로 갈수록 전파가 강해진다. 공급 전류가 허용된다면 MAX로 그렇지 않다면 한 단계씩 줄여서 통신 상황을 관찰한다. 나는 아두이노 자체전원을 이용 했으므로 제일 작은 MIN으로 설정했다.



위와 같이 RF 통신으로 온도센서의 측정값이 잘 전해졌다. 전파의 강도를 약하게 해서인지 둘 사이의 거리가 5m 정도를 넘으면 통신이 되지 않았다. 추후 전원을 보강해서 MAX 까지 추가 테스트를 해 볼 필요성을 느낀다.


- NRF24L01 참고 사이트

http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

http://www.mapescn.com/xe/ARDUINO/44799



반응형
Posted by 대네브 (deneb)

댓글을 달아 주세요