nRF24L01 –仕組み、Arduinoインターフェース、回路、コード
このチュートリアルでは、無線通信を作成する方法を学習します nRF24L01を使用した2つのArduinoボード間 トランシーバーモジュール。 nRF24L01モジュールは、Arduinoを使用する場合のワイヤレス通信で非常に人気があります。
私はすでにこのモジュールを多くのArduinoプロジェクトに使用しており、それらのいくつかをここでチェックできます:
次のビデオを見るか、以下のチュートリアルを読むことができます。モジュールのピン配列、動作原理、配線、いくつかのコード例など、nRF24L01トランシーバモジュールについて知っておく必要のあるすべてが含まれています。
ワイヤレス通信を説明するために、2つの例を示します。最初の例では、あるArduinoから別のArduinoに簡単な「HelloWorld」メッセージを送信します。2番目の例では、Arduinoボード間で双方向通信を行います。最初のArduinoのジョイスティックは2番目のArduinoのサーボモーターを制御し、その逆も同様です。2番目のArduinoのプッシュボタンを使用して、最初のArduinoのLEDを制御します。
NRF24L01トランシーバモジュールを詳しく見てみましょう。 2.4 GHz帯域を使用し、250kbpsから2Mbpsまでのボーレートで動作できます。オープンスペースで使用され、ボーレートが低い場合、その範囲は最大100メートルに達する可能性があります。
完全な仕様は次のとおりです。
モジュールは125の異なるチャネルを使用できるため、125の独立して動作するモデムのネットワークを1か所に配置できます。各チャネルは最大6つのアドレスを持つことができます。または、各ユニットは同時に最大6つの他のユニットと通信できます。
このモジュールの消費電力は、送信時に約12mAであり、単一のLEDよりもさらに低くなります。モジュールの動作電圧は1.9〜3.6Vですが、他のピンは5Vロジックを許容するため、ロジックレベルコンバータを使用せずにArduinoに簡単に接続できます。
これらのピンのうち3つはSPI通信用であり、ArduinoのSPIピンに接続する必要がありますが、Arduinoボードごとに異なるSPIピンがあることに注意してください。ピンCSNとCEは、Arduinoボードの任意のデジタルピンに接続でき、モジュールをスタンバイモードまたはアクティブモードに設定したり、送信モードとコマンドモードを切り替えたりするために使用されます。最後のピンは、使用する必要のない割り込みピンです。
NRF24L01モジュールにはいくつかのバリエーションがあります。最も人気のあるのは、オンボードアンテナを備えたものです。これにより、モジュールはよりコンパクトになりますが、一方で、伝送範囲は約100メートルの距離にまで低下します。
2番目のバリエーションは、オンボードアンテナの代わりに、SMAコネクタを備えており、送信範囲を拡大するためにダックアンテナを取り付けることができます。
ここに示す3番目のバリエーションは、ダックアンテナに加えて、 PAを含むRFX2401Cチップを備えています。 (パワーアンプ)と LNA (低ノイズアンプ)。これにより、NRF24L01信号が増幅され、オープンスペースで最大1000メートルのさらに優れた伝送範囲が可能になります。
NRF24L01のピン配置とNRF24L01+PA/LNAモジュールの詳細を以下に示します。
NRF24L01とNRF24L01+PA / LNAの両方のモジュールは同じピン配置であるため、回路内で同じ方法で接続できます。
NRF24L01モジュールをArduinoボードに接続する方法は次のとおりです。
すでに述べたように、Arduinoボードごとに異なるSPIピンがあるため、モジュールをArduinoボードに接続するときはそのことに注意してください。
このArduinoチュートリアルに必要なコンポーネントは、以下のリンクから入手できます。
NRF24L01モジュールをArduinoボードに接続すると、送信機と受信機の両方のコードを作成する準備が整います。
まず、RF24ライブラリをダウンロードしてインストールする必要があります。これにより、プログラミングが難しくなりません。このライブラリは、Arduino IDELibraryManagerから直接インストールすることもできます。 「rf24」を検索し、「TMRh20、Avamander」で検索してインストールします。
これが無線通信の2つのコードであり、以下はそれらの説明です。
したがって、基本的なSPIと新しくインストールされたRF24ライブラリを含めて、RF24オブジェクトを作成する必要があります。ここでの2つの引数は、CSNピンとCEピンです。
次に、アドレスを表すバイト配列、または2つのモジュールが通信するいわゆるパイプを作成する必要があります。
このアドレスの値を任意の5文字の文字列に変更できます。これにより、話す受信機を選択できるため、この場合、受信機と送信機の両方で同じアドレスになります。
セットアップセクションでは、無線オブジェクトを初期化し、radio.openWritingPipe()関数を使用して、データの送信先となる受信者のアドレス(以前に設定した5文字の文字列)を設定する必要があります。
一方、受信機では、radio.setReadingPipe()関数を使用して同じアドレスを設定し、その方法で2つのモジュール間の通信を有効にします。
次に、radio.setPALevel()関数を使用して、パワーアンプのレベルを設定します。この場合、モジュールが互いに非常に近いため、最小に設定します。
より高いレベルを使用する場合は、モジュールのGNDと3.3Vの間にバイパスコンデンサを使用して、動作中の電圧がより安定するようにすることをお勧めします。
次に、モジュールを送信機として設定するradio.stopListening()関数があり、反対側には、モジュールを受信機として設定するradio.startListening()関数があります。
ループセクションの送信機で、「HelloWorld」というメッセージを割り当てる文字の配列を作成します。 radio.write()関数を使用して、そのメッセージを受信者に送信します。ここでの最初の引数は、送信する変数です。
変数名の前に「&」を使用することで、送信するデータを格納する変数の表示を実際に設定し、2番目の引数を使用して、その変数から取得するバイト数を設定します。この場合、sizeof()関数は文字列「text」のすべてのバイトを取得します。プログラムの最後に、1秒の遅延を追加します。
radio.write()関数を使用すると、一度に最大32バイトを送信できます。
一方、受信機では、radio.available()関数を使用したループセクションで、受信するデータがあるかどうかを確認します。その場合は、最初に「テキスト」と呼ばれる32個の要素の配列を作成します。この配列に、受信データを保存します。
radion.read()関数を使用して、データを読み取り、「text」変数に格納します。最後に、シリアルモニターにテキストを印刷します。したがって、両方のプログラムをアップロードすると、レシーバーでシリアルモニターを実行でき、「HelloWorld」というメッセージが毎秒出力されます。
電源ノイズは注目に値します これは、NRF24L01モジュールとの通信を成功させるときに人々が経験する最も一般的な問題の1つです。一般に、RF回路または無線周波数信号は電源ノイズに敏感です。したがって、電源ラインの両端にデカップリングコンデンサを含めることをお勧めします。コンデンサは10uFから100uFまで何でもかまいません。
もう1つの一般的な問題は、Arduinoボードの3.3VピンがNRF24L01モジュールに常に十分な電力を供給できるとは限らないことです。したがって、外部電源を使用してモジュールに電力を供給することもお勧めします。
2番目の例である2つのArduinoボード間の双方向ワイヤレス通信を見てみましょう。回路図は次のとおりです。
この例に必要なコンポーネントは、以下のリンクから入手できます。
以下に2つのコードとその説明を示します。
送信機コード
受信者コード
ここで前の例と異なるのは、双方向通信用に2つのパイプまたはアドレスを作成する必要があることです。
セットアップセクションでは、両方のパイプを定義する必要があります。最初のArduinoの書き込みアドレスは2番目のArduinoの読み取りアドレスである必要があり、その逆も同様です。最初のArduinoの読み取りアドレスはでの書き込みアドレスである必要があります。 2番目のArduino。
radio.stopListening()関数を使用するループセクションでは、最初のArduinoを送信機として設定し、ジョイスティックの値を読み取って0から180にマッピングし、radio.write()関数を使用してデータを受信機に送信します。
一方、radio.startListening()関数を使用して、2番目のArduinoを受信機として設定し、利用可能なデータがあるかどうかを確認します。利用可能なデータがある間、それを読み取り、「angleV」変数に保存し、その値を使用してサーボモーターを回転させます。
次に、送信機で、最初のArduinoを受信機として設定し、空の「while」ループを使用して、2番目のArduinoがデータを送信するのを待ちます。これは、押されているかどうかに関係なく、プッシュボタンの状態のデータです。ボタンを押すとLEDが点灯します。したがって、これらのプロセスは常に繰り返され、両方のArduinoボードが常にデータを送受信しています。
NRF24L01モジュールを使用したもう1つのサンプルコードを見てみましょう。すべてが前の例と同じままです。構造化して日付を送信する方法を期待してください。
送信機コード
したがって、実際にはさまざまなタイプの変数のコレクションである構造体を作成できます。
この構造体データの最大サイズは32バイトである可能性があることに注意してください。ここでは、3つの変数タイプbyte、1つの整数変数(4バイト)、1つのfloat変数(4バイト)、および4文字(4バイト)を含む1つの文字列が含まれていることがわかります。合計15バイトです。
受信者コード
受信側では、受信データを受信できるようにするために、同じ構造体データを定義する必要があります。無線通信が正しく機能するかどうかをテストするために、各変数をシリアルモニターに印刷しました。
NRF24L01モジュールは、Arduinoプロジェクトでワイヤレス通信が必要な場合に最適なオプションです。私はすでにこのモジュールをArduinoプロジェクトの多くで使用しています。
ここでは、これらのモジュールを使用したすべてのプロジェクトを一覧表示します。
これらの各プロジェクト/チュートリアルには、回路図、より良い通信のための改善されたコード実装などを含む、NRF24L01モジュールの使用方法の詳細な説明があります。
私のお気に入りのプロジェクトは、このカスタム設計されたArduinoRC送信機です。これは実際には14チャンネルのRCコントローラーであり、ほとんどすべてのArduinoプロジェクトを制御するために使用できます。
このチュートリアルは以上です。楽しんで、新しいことを学んだことを願っています。いつものように、下のコメントセクションで質問をしてください。
nRF24L01トランシーバモジュール
周波数範囲 2.4 –2.5GHzISMバンド データレート 250Kbps / 1Mbps / 2Mbps 最大出力電力 0dBm 動作電圧 1.9 – 3.6V 最大動作電流 12.3mA スタンバイ電流 22µA ロジック入力 5Vトレラント 通信範囲 100m(オープンスペース) 仕組み
モジュールのバリエーション
nRF24L01モジュールのピン配置
nRF24L01をArduinoに接続する方法
Arduino SCK MISO MOSI SS 宇野 13 12 11 10 ナノ 13 12 11 10 メガ 52 50 51 53
ArduinoおよびnRF24L01コード
送信機コード
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
Code language: Arduino (arduino)受信者コード
/*
* Arduino Wireless Communication Tutorial
* Example 1 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
Code language: Arduino (arduino)コードの説明
RF24 radio(7, 8); // CE, CSN
Code language: Arduino (arduino)const byte address[6] = "00001";
Code language: Arduino (arduino)radio.openWritingPipe(address);
Code language: Arduino (arduino)radio.openReadingPipe(0, address);
Code language: Arduino (arduino)radio.setPALevel(RF24_PA_MIN);
Code language: Arduino (arduino)// at the Transmitter
radio.stopListening();
Code language: Arduino (arduino)// at the Receiver
radio.startListening();
Code language: Arduino (arduino)void loop() {
const char text[] = "Hello World";
radio.write(&text, sizeof(text));
delay(1000);
}
Code language: Arduino (arduino)void loop() {
if (radio.available()) {
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}
Code language: Arduino (arduino)2つのNRF24L01とArduinoを使用した双方向ワイヤレス通信
nRF24L01ソースコード
/*
* Arduino Wireless Communication Tutorial
* Example 2 - Transmitter Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define led 12
RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
boolean buttonState = 0;
void setup() {
pinMode(12, OUTPUT);
radio.begin();
radio.openWritingPipe(addresses[1]); // 00002
radio.openReadingPipe(1, addresses[0]); // 00001
radio.setPALevel(RF24_PA_MIN);
}
void loop() {
delay(5);
radio.stopListening();
int potValue = analogRead(A0);
int angleValue = map(potValue, 0, 1023, 0, 180);
radio.write(&angleValue, sizeof(angleValue));
delay(5);
radio.startListening();
while (!radio.available());
radio.read(&buttonState, sizeof(buttonState));
if (buttonState == HIGH) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}
Code language: Arduino (arduino)/*
* Arduino Wireless Communication Tutorial
* Example 2 - Receiver Code
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
#define button 4
RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
Servo myServo;
boolean buttonState = 0;
void setup() {
pinMode(button, INPUT);
myServo.attach(5);
radio.begin();
radio.openWritingPipe(addresses[0]); // 00001
radio.openReadingPipe(1, addresses[1]); // 00002
radio.setPALevel(RF24_PA_MIN);
}
void loop() {
delay(5);
radio.startListening();
if ( radio.available()) {
while (radio.available()) {
int angleV = 0;
radio.read(&angleV, sizeof(angleV));
myServo.write(angleV);
}
delay(5);
radio.stopListening();
buttonState = digitalRead(button);
radio.write(&buttonState, sizeof(buttonState));
}
}
Code language: Arduino (arduino)const byte addresses[][6] = {"00001", "00002"};
Code language: Arduino (arduino)// at the Transmitter
radio.openWritingPipe(addresses[1]); // 00001
radio.openReadingPipe(1, addresses[0]); // 00002
Code language: Arduino (arduino)// at the Receiver
radio.openWritingPipe(addresses[0]); // 00002
radio.openReadingPipe(1, addresses[1]); // 00001
Code language: Arduino (arduino)radio.stopListening();
int potValue = analogRead(A0);
int angleValue = map(potValue, 0, 1023, 0, 180);
radio.write(&angleValue, sizeof(angleValue));
Code language: Arduino (arduino)radio.startListening();
if ( radio.available()) {
while (radio.available()) {
int angleV = 0;
radio.read(&angleV, sizeof(angleV));
myServo.write(angleV);
}
Code language: Arduino (arduino)例3–1つのパッケージで複数の変数を送信する
/*
Arduino Wireless Communication Tutorial
Example 1 - Transmitter Code
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; // Create a variable with the above structure
void setup() {
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
// Send the whole data from the structure to the receiver
radio.write(&data, sizeof(Data_Package));
delay(500);
}
Code language: Arduino (arduino)// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; // Create a variable with the above structure
Code language: Arduino (arduino)/*
Arduino Wireless Communication Tutorial
Example 1 - Receiver Code
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte a = 0;
byte b = 125;
byte c = 255;
int d = 1024;
float e = 3.141592;
String f = "Test";
};
Data_Package data; //Create a variable with the above structure
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
}
Serial.print("a: ");
Serial.print(data.a);
Serial.print(" b: ");
Serial.print(data.b);
Serial.print(" c: ");
Serial.print(data.c);
Serial.print(" d: ");
Serial.print(data.d);
Serial.print(" e: ");
Serial.print(data.e);
Serial.print(" f: ");
Serial.println(data.f);
}
Code language: Arduino (arduino)
製造プロセス