●NRF24L01無線通信モジュール

2台のArduinoと2個のNRF24L01モジュールを使って無線通信をしてみます。
使ったモジュールはこちらの物です。
KKHMF NRF24L01 + 無線 トランシーバー モジュール

しかし、このモジュールはArduinoの3.3Vで動作させようとすると誤動作してまともに動きません、 コンデンサを付けても誤動作しますし、電源に対する要求が厳しいので最初から電源専用のボードを買っておくのを強くお勧めします。
NRF24L01ソケットアダプターモジュールボード

モジュール自体の接続にはSPIが使われているようでこのようなピン配置になっています。
表から見たピン配置


次のようにArduinoと接続しました。

モジュールのIRQ→ 使用しない
モジュールのSCK→ デジタルピン13 (SCLK)
モジュールのMOSI → デジタルピン11 (MOSI)
モジュールのMISO → デジタルピン12 (MISO)
モジュールのCE → デジタルピン D9 もしくはお好きなデジタルピン
モジュールのCSN → デジタルピンD10もしくはお好きなデジタルピン


後は、GNDはGNDと接続し、VCCは3Vと接続するのですが、問題は電源です。
電源専用のボードを買ってあればいいのですが、私は買ってなかったので乾電池で代用しました。
乾電池の3Vで動作させましたが、電池が少々弱っていた2.5Vでも誤動作してうまく動作しませんでした。
上手く動かない時は新しい電池に変えてみると動作するかもしれません。

2台のArduinoと2台のNRF24L01モジュールを接続してハードウエアは完成です。

乾電池ボックスを2台のArduinoで共有していますが、接続は同じです。
モジュール自体にLEDなどは付いておらず、LEDに見えた部品も実はコンデンサだったりと電源ではまりました。


■ソフトウエアの作成

▼ライブラリの準備

まずはライブラリをダウンロードします。
https://github.com/nRF24/RF24

次に画面上の緑色のボタンを押して、Download ZIPを選択してファイルをダウンロードします。


ファイルがダウンロードされたら、ZIPファイルを開いて、フォルダごとパソコンの ( ドキュメント → Arduino → libraries ) にコピーします。
このライブラリ、同じようで動作が違う物が他にもあるようで他の場所からダウンロードしたライブラリだと、うまく動いたり動かなかったりするかもしれません。
ライブラリをコピーしたらArduino IDEを再起動させます。
これでライブラリの準備は完了です。


▼双方向通信を行うプログラム

一方通行の通信では面白くないので双方向通信を行うプログラムを作成しました。
2台のArduinoをパソコンに接続して、2つのArduino IDEを起動させます。
2つのArduino IDEで個々のArduinoが接続されたポートを指定すると、2つのArduinoを一つのパソコンで操作できます。
1台目のArduinoには次のプログラムを書き込みました。

#include <SPI.h>
#include "RF24.h"

RF24 radio(9, 10); //CE,CSNのピンをを指定

byte addr[][6] = {"addr0", "addr1"};

void setup() {
  Serial.begin(9800);
  Serial.println(F("start"));
  radio.begin();
  radio.setPALevel( RF24_PA_LOW );
  radio.openWritingPipe(addr[1]);
  radio.openReadingPipe(1, addr[0]);
  radio.startListening();
}

void loop() {
  char c = 'a';
  radio.stopListening();
  if (!radio.write( &c, sizeof(char) )) {
    Serial.println(F("failed"));
  }
  radio.startListening();
  if (radio.available() ) {
    radio.read( &c, sizeof(char) );
    Serial.print(c);
  }

  delay(1000);
}
2台目のArduinoには次のプログラムを書き込みました。
ほぼ同じですが、変更する箇所は、送受信するアドレスを入れ替えるのと、わかりやすいように送信文字をbにかえました。

#include <SPI.h>
#include "RF24.h"

RF24 radio(9, 10); //CE,CSNのピンをを指定

byte addr[][6] = {"addr1", "addr0"};

void setup() {
  Serial.begin(9800);
  Serial.println(F("start"));
  radio.begin();
  radio.setPALevel( RF24_PA_LOW );
  radio.openWritingPipe(addr[1]);
  radio.openReadingPipe(1, addr[0]);
  radio.startListening();
}

void loop() {
  char c = 'b';
  radio.stopListening();
  if (!radio.write( &c, sizeof(char) )) {
    Serial.println(F("failed"));
  }
  radio.startListening();
  if (radio.available() ) {
    radio.read( &c, sizeof(char) );
    Serial.print(c);
  }

  delay(1000);
}

2台のArduinoにプログラムを書き込んで、各々のシリアルモニタを開くと双方向通信できているのが確認できます。

もし、うまく動いていない場合には2個のArduinoのリセットボタンを同時に押してArduinoを再起動させます。
片方がうまく動いていない状態でもう片側を起動させても最初からエラーと判断して通信が上手く行かない事があるからです。

通信距離は大体10m程度でした。 もう少し伸ばしたい場合には次のように通信速度を下げて出力を最大に設定すると、
radio.setPALevel( RF24_PA_MAX );
radio.setDataRate( RF24_250KBPS );
少しは通信距離が伸びるかもしれません。


▼一度に送受信できる最大サイズ

nRF24L01の仕様書のパケットフォーマットを見てみると、

ペイロードはパケット中でユーザ・コンテンツになる部分です。
0〜32Byteの長さを持つことができます。

このような一文を見つけました。
プログラムの一部をこのように変更して32バイトを一度に送受信するように変更しても正しく動作するようです。

char str[32] = "1234567890123456789012345678901";
void loop() {

  char buf[32];
  radio.stopListening();
  if (!radio.write( str, 32)) {
    Serial.println(F("failed"));
  }
  radio.startListening();
  if (radio.available() ) {
    radio.read( buf, 32 );
    Serial.println(buf);
  }
  delay(1000);
}
32バイト以上のサイズでも試してみましたが正しく動作しませんでした。
単純にメモリーのサイズが32バイトですから、配列や構造体、char以外の他の変数型でも同様に送受信できるはずです。


▲トップページ > マイコンなど