ArduinoやRaspberry Piなど電子工作で使うマイコンボードで無線通信が出来ると非常に便利となります。
電子工作という趣味をはじめてからその用途で3Dプリンタも導入しました。
電子工作に3Dプリンタってホント最強のコンビですね!
3Dプリントパーツを使いこれまでいろいろと作ってきました。
例えばこのような4足歩行ロボットを作りました。
非常に可愛い動きをしてくれセンサーで障害物を検知しながら部屋中を歩き回ってくれます。

まだブログでご紹介出来ていませんが、こちらはDCモーターを使ったミニラジコンです。
こちらも障害物を避けクルクル回りながら動きまわってくれます。
そして最近ではロボットアームの製作なんかもしています。

このようにArduinoなどマイコンボードを使って動くものを製作する際に無線通信が使えると、製作物を自在に動かせるラジコンのように操作することも可能となり便利となるかと思います。
ドローンという趣味もやっていることから手元に送信機や受信機がたくさんあります。
これまで無線で操作する場合、ドローン用の物を使い無線化していましたが電子工作用途ではあまり使い勝手がいいものではありませんでした。
通信プロトコルはFrskyというものを使っていますが、近距離だと頻繁にバインドが切れてしまいます。
これではデスクの上でプログラムやテスト動作させる場合は非常に面倒となります。
そんなことをたまにSNSで書いていると海外のいろんな方がArduinoで使える無線モジュールについて教えてくれました。
その中でも安価で国内サイトでも比較的入手しやすく便利なnRF24L01というモジュールを今回ご紹介したいと思います。
電子工作用途で無線通信するためのモジュールは、技適が通っているXBeeやWi-FiならESP-WROOM-02などを使うことが多いようですが、製作物に組み込んで使う場合結構お高いモジュールとなります。
そこで今回は非常に安価に入手出来るnRF24L01無線モジュールを使ってみたいと思います。
中華サイトやAmazonでも入手する事が可能で、単価にして1個100~200円ほどと非常に安価なモジュールとなるので電子工作という趣味用途では非常に役立ちます。(技適の問題もあるので詳しくは後述します!)
Arduinoに接続しテスト動作させてみましたが、比較的簡単に使うことができ便利だったので自分への備忘録もかねこのnRF24L01モジュールについて書いておこうと思います。
Arduinoなどマイコンボードと接続して無線通信が出来るモジュールとして非常に便利なものとなります。
目次
- nRF24L01モジュールを使ってArduinoで無線通信をしてみる
- nRF24L01無線通信モジュール
- ピンの配列
- nRF24L01モジュールで使えるArduinoライブラリ
- Arduino間の無線通信でLEDを点灯させてみる
- Arduino間の無線通信でサーボモーターを動かしてみる
- 双方向通信でサーボモーターを動かしてみる
- 【追記】複数データの送信で使ってみる!
- 【追記】nRF24L01を安定動作させるための方法!
- 【追記】無線モジュールnRF24L01を使ったロボットカーの製作!
- 【追記】nRF24L01無線モジュール用ブラケットを作ってみました!
- 【追記】無線モジュールnRF24L01とジョイスティックシールドのコンビが便利!
- 【追記】Arduino NanoにnRF24L01モジュールが一体化したRF-Nanoを試してみました
- 【追記】Bluetoothモジュールも試してみました!
- 【追記】Wi-Fiモジュールも試してみました!
- 【追記】ミニシールドを作ってみました!
- 【追記】nRF24L01を使ったArduino無線コントローラーの製作!
- 最後に!
nRF24L01モジュールを使ってArduinoで無線通信をしてみる
今回、nRF24L01という無線モジュールをArduinoと接続し無線通信をしてみたいと思います。
モジュール用のライブラリを使えば比較的簡単にArduinoで無線通信を行うことが出来ました。
このモジュールの概要とともにArduino間の無線通信によりLEDを点灯させたり、サーボモーターを動かす簡単な方法もご紹介したいと思います。
nRF24L01無線通信モジュール
こちらがnRF24L01モジュールとなります。
ノルディック社の2.4GHz帯トランシーバーチップnRF24L01を搭載した小型無線モジュールとなり、マイコンと組み合わせることによりダイレクトに無線による制御を行うことが出来ます。
ボーレートは250kbps~2Mbpsとなっており、アンテナはパターンアンテナとなっています。
ボーレートが低い場合、100mほど電波が届くようですね。
端子は8ピンのピンヘッダーが付いています。
モジュール(基盤)サイズは約30mm×14mmと非常に小型なので製作物に組み込むには便利なサイズ感だと思います。
Aliexpressなど海外サイトでは非常に安く売られています。(1個100円ほど)
また国内サイトやAmazonなどでも売られているので入手はしやすいかと思います。(今回ご紹介しているものはAmazonで購入したものとなります)
通信には2.4GHz帯を使って通信しています。
このあたり私はあまり詳しくないのですが、以前ドローンで使うVTXで技適申請をしたことがあります。
アマチュア無線の免許を取る際に覚えた記憶では、2.4GHz帯の場合3mで35μV/m以下だと日本の電波法では微弱無線として扱われ技適申請の必要がなかったような・・・
送信出力がそれ以上となると特定小電力無線局の扱いとなり技適と呼ばれる技術基準適合証明の取得が必要となってきます。
つまり自分で無線局として開局するということですね。
このnRF24L01モジュールは技適が取得されていないようです。
個人使用やテスト環境レベルであれば最大送信出力は0dBm(11mA)とあるので大丈夫そうではあるのですが・・・少しグレーな感じがしますが、あまり詳しくないのでご了承下さい。
ピンの配列
基本的にこのnRF24L01モジュールは2つペアで使う形となります。
送信側と受信側ということですね。(サーバー側/クライアント側)
Arduinoのライブラリを使いスケッチで記述する事により1つのモジュールを送信側/受信側に割り当てることが出来ます。
また双方向でのやり取りも可能となっています。
送信側で操作し、ラジコンなどに組み込んだ受信側で取得したセンサー情報などを送り返すなどの使い方も出来そうですね。
そして複数モジュールでのやり取りも可能となっています。
各モジュールは最大6つの他のモジュールと通信出来るようです。
nRF24L01モジュールのピン配列はこのようになっています。
ここで注意したいのが、nRF24L01モジュールの動作電圧は1.9~3.6Vとなっています。
Arduinoに直接接続する場合、電源は3.3Vラインに接続する必要があります。(5Vラインではないので注意して下さい!)
そのためロジックレベルコンバーターなど使用せずにArduinoのデジタルピンと直接接続できます。
そしてこのnRF24L01モジュールは、上記ピン配列を見て分かるようにSPI通信でやり取りを行います。
ArduinoのSPI用ライブラリを利用する場合、Arduino側で使われるSPIピンはボードごとに決まっています。
ArduinoにはUnoやNano、MegaなどいろいろとありますがSPI通信で使える端子には違いがあります。
こちらではArduino Unoを使って説明していきます。
Arduino Unoの場合SPIピンは、デジタルピン10番がSS・デジタルピン11番がMOSI・デジタルピン12番がMISO・デジタルピン13番がSCLKとなっています。
またnRF24L01モジュールにはCSNピンとCEピンがありますが、これは送信モードを切り替えるものでArduinoの任意のデジタルピンに割り振る(接続)する事が出来ます。(スケッチにより変更が可能)
以上によりArduinoとnRF24L01モジュールの接続はこのようになります。(MegaなどではSPIピンが異なるので注意して下さい)
※CE/CSN/ピンはデジタルピン7番と8番に割り振っています。(スケッチで変更可能です)
送信側/受信側のどちらのArduinoへも同様の接続となります。
nRF24L01モジュール | Arduino Uno |
1.GND | GND |
2.Vcc | 3.3V |
3.CE | デジタルピン7 |
4.CSN | デジタルピン8 |
5.SCK | デジタルピン13 |
6.MOSI | デジタルピン11 |
7.MISO | デジタルピン12 |
8.IRQ | 未接続 |
一応、Arduino NanoとMegaのSPIピンも書いておきます。
Arduino | SCK | MISO | MOSI | SS |
Uno | 13 | 12 | 11 | 10 |
Nano | 13 | 12 | 11 | 10 |
Mega | 52 | 50 | 51 | 53 |
また今回行ったテスト動作では特に大きな問題はなかったのですが、無線モジュールはノイズの影響を大きく受けます。
Arduinoの3.3Vラインやブレッドボードでの配線等によりノイズが発生して動作が不安定になるといった話も聞きました。
動作が不安定になるようならモジュールのVcc/GND間にパスコン(バイパスコンデンサ)を付けるのがいいようです。
後述する双方向でのやり取りの際、ジャンパーワイヤーの本数が増えたためかサーボモーターが不安定な動きを見せる時がありました。
10μFほどのパスコンを入れることにより問題なく動作するようになりました。(テストレベルでは入れる必要はないとは思いますが!)
またnRF24L01モジュール用のソケットアダプターというものもあるようですね。
レギュレーターが内蔵されArduinoの5Vラインが使え、ノイズ対策などもされているようです。
基盤にビス穴もあり製作物に組み込みたい場合はソケットを装着すれば便利そうですね。(試してみます)
【追記】アダプアターを試してみました!
Arduinoからの5Vラインが使え、SPIピンもシルク印字されているので分かりやすいですね!
モジュール単体で使うより接続も簡単に行えます。
nRF24L01モジュールで使えるArduinoライブラリ
Arduinoへの接続が出来ればスケッチを書いていきますが、まずその前にArduinoでnRF24L01モジュールを使うためのライブラリをインストールしておきます。
ライブラリのダウンロードはこちらから。
参考 nRF24/RF24GitHubスケッチ内に上記ライブラリをインクルードして準備は完了です。
Arduino間の無線通信でLEDを点灯させてみる
それでは簡単なスケッチを使いArduino間の無線通信のテストを数パターンやってみたいと思います。
送信側(サーバー側)と受信側(クライアント側)の2つのArduino Unoを使います。
共に上記を参考にnRF24L01モジュールを接続しておきます。
まずはLEDを点灯させる簡単なスケッチを作ってみました。
送信側に接続したタクトスイッチを押すと受信側に接続したLEDが点灯するという簡単なものです。
接続(送信側)
送信側の接続はこのようになります。
送信側のタクトスイッチはArduinoにより内部プルアップさせています。
プルアップ・プルダウンに関してはこちらを参考にして下さい。

接続(受信側)
次に受信側は制限抵抗(150Ωほど)を1本使いデジタルピン3にLEDを接続しています。
スケッチ(送信側)
スケッチはこのような簡単なものを作ってみました。
送信側のスイッチを押すと受信側のLEDが点灯するという単純なものです。
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 | // LED点灯(送信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを送信するアドレス int SW_PIN = 3; boolean SW_state = 1; void setup() { pinMode(SW_PIN, INPUT_PULLUP); // スイッチをプルアップで使用 radio.begin(); // 無線オブジェクトの初期化 radio.openWritingPipe(address); // データ送信先のアドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.stopListening(); // 送信側として設定 } void loop(){ SW_state = digitalRead(SW_PIN); // スイッチの状態を読み取る radio.write(&SW_state, sizeof(SW_state)); // スイッチの状態を送信する delay(10); } |
スケッチ(受信側)
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 | // LED点灯(受信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを受信するアドレス int LED_PIN = 3; boolean SW_state = 0; void setup() { pinMode(3, OUTPUT); radio.begin(); // 無線オブジェクトの初期化 radio.openReadingPipe(0, address); // データ受信アドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.startListening(); // 受信側として設定 } void loop(){ if (radio.available()){ radio.read(&SW_state, sizeof(SW_state)); // スイッチの状態を受信する if(SW_state == HIGH){ digitalWrite(3, LOW); } else { digitalWrite(3, HIGH); } } delay(10); } |
実際の動作を確認
上記スケッチを各Arduinoで動かすとこのように動作します。
スイッチの状態を送信しもう1台のArduinoで受信してLEDを点灯させています。
遅延等もなく上手く動作しているようです!
スケッチ解説
簡単にスケッチを解説しておきます。
まずnRF24L01モジュールを使うためのライブラリのインクルードです。
3 4 5 | #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> |
CEピンとCSNピンを指定します。
任意のデジタルピンが使えます。
Arduino UnoでSPI通信をするための接続ピンは先述のように決まっているので、その他空いている7ピン・8ピンを使いました。
7 | RF24 radio(7, 8); // CE,CSNピンの指定 |
データを送信するアドレスを指定。
任意の5文字の文字列で指定します。
複数のモジュール間でのやり取りが可能なので、どの受信機と通信するかを選択しています。
受信機側でも同じアドレスを指定する必要があります。
8 | const byte address[6] = "00001"; // データを送信するアドレス |
無線オブジェクトの初期化。
18 | radio.begin(); // 無線オブジェクトの初期化 |
データを送受信するアドレスを指定。
(送信側)
19 | radio.openWritingPipe(address); // データ送信先のアドレスを指定 |
(受信側)
19 | radio.openReadingPipe(0, address); // データ受信アドレスを指定 |
パワーアンプレベルを最小に設定。
高いレベルで動作させる場合は電圧が安定するようにモジュールのVcc/GND間にバイパスコンデンサを接続するのがいいようです。
20 | radio.setPALevel(RF24_PA_MIN); // 出力を最小に |
送信と受信の設定。
(送信側)
21 | radio.stopListening(); // 送信側として設定 |
(受信側)
21 | radio.startListening(); // 受信側として設定 |
あとはradio.writeでデータを送信し、radio.readで読み取っています。
簡単ですね!
29 | radio.write(&SW_state, sizeof(SW_state)); // スイッチの状態を送信する |
28 29 | if (radio.available()){ radio.read(&SW_state, sizeof(SW_state)); // スイッチの状態を受信する |
Arduino間の無線通信でサーボモーターを動かしてみる
次に同様の手順でサーボモーターを動かしてみたいと思います。
送信側にジョイスティックを接続し、受信側に接続したサーボモーターを動かします。
ラジコンのコントローラーみたいな感じですね。
接続(送信側)
ジョイスティックからのアナログ値をアナログピンA0に入力し、A/D変換により0~1023までの数値を送信します。
接続(受信側)
受信した数値をサーボモーターの動作角度(0~180°)にマッピングし動かします。
スケッチ(送信側)
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 | // サーボモーターを動かす(送信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを送////信するアドレス int Y_PIN = A0; int Y_pos; void setup() { pinMode (Y_PIN, INPUT) ; radio.begin(); // 無線オブジェクトの初期化 radio.openWritingPipe(address); // データ送信先のアドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.stopListening(); // 送信側として設定 } void loop() { Y_pos = analogRead (Y_PIN) ; // アナログ値を読み取る radio.write(&Y_pos, sizeof(Y_pos)); // アナログ値を送信する delay(10); } |
スケッチ(受信側)
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 | // サーボモーターを動かす(受信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo myservo; RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを受信するアドレス int SERVO_PIN = 3; int Y_pos; int Angle; void setup() { Serial.begin(9600); myservo.attach (SERVO_PIN); radio.begin(); // 無線オブジェクトの初期化 radio.openReadingPipe(0, address); // データ受信アドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.startListening(); // 受信側として設定 } void loop() { if (radio.available()) { radio.read(&Y_pos, sizeof(Y_pos)); // アナログ値を受信する Angle = map(Y_pos, 0, 1023, 0, 180); myservo.write (Angle) ; Serial.print("Servo Angle: "); Serial.println(Angle); } delay(10); } |
実際の動作を確認
ジョイスティックのアナログ値を送信し上手くサーボモーターを動かせていますね。
また、シリアルモニタを立ち上げると現在のサーボ角度が表示されます。
ここまで出来ると、Arduinoを使った簡単なラジコンやロボットカーなどに応用できいろいろと楽しめそうですね!
スケッチ解説
無線モジュールに関する部分は、先ほどのLED点灯の時と全く同じですね。
送信側のジョイスティックで取得した値をArduinoのアナログピンに入力し0~1023の数値に変換し(A/D変換)、その数値を送信しています。
ジョイスティックによるアナログ値の取得方法に関してはこちらの記事を参考にして下さい!

また、受信側は取得した数値をマッピングしサーボモーターの可動範囲(0~180°)に変換して動かしています。
ジョイスティックを使ったサーボモーターの制御方法に関してはこちらの記事を参考にして下さい!

双方向通信でサーボモーターを動かしてみる
最後に双方向でのやり取りをやってみたいと思います。
今回使っているnRF24L01モジュールは、先ほどの例のように送信側・受信側を決めて無線通信する以外にモジュールの送信・受信を入れ替え双方向でのやり取りを行うことも出来ます。
その例として送信側・受信側双方にジョイスティックとサーボモーターを繋げ、一方のジョイスティックで他のサーボモーターを動かしてみたいと思います。
接続(送信側・受信側)
接続は送信側・受信側ともにこちらを使用します。
スケッチ(送信側)
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 | // サーボモーターを双方向で動かす(送信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo myservo; RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[][6] = {"00001", "00002"}; // データを送信するアドレス int Y_PIN = A0; int SERVO_PIN = 3; int Y_pos; int Angle1; int Angle2; void setup() { pinMode (Y_PIN, INPUT) ; myservo.attach(SERVO_PIN); radio.begin(); radio.openWritingPipe(address[1]); // データ送信先アドレスを指定 radio.openReadingPipe(1, address[0]); // データ受信アドレスを指定 radio.setPALevel(RF24_PA_MIN); } void loop() { delay(5); radio.stopListening(); // 送信側として動作 Y_pos = analogRead (Y_PIN) ; Angle1 = map(Y_pos, 0, 1023, 0, 180); radio.write(&Angle1, sizeof(Angle1)); delay(5); radio.startListening(); // 受信側として動作 if(radio.available()){ radio.read(&Angle2, sizeof(Angle2)); myservo.write(Angle2); } } |
スケッチ(受信側)
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 | // サーボモーターを双方向で動かす(受信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo myservo; RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[][6] = {"00001", "00002"}; // データを送////信するアドレス int Y_PIN = A0; int SERVO_PIN = 3; int Y_pos; int Angle1; int Angle2; void setup() { pinMode (Y_PIN, INPUT) ; myservo.attach(SERVO_PIN); radio.begin(); radio.openWritingPipe(address[0]); // データ送信先アドレスを指定 radio.openReadingPipe(1, address[1]); // データ受信アドレスを指定 radio.setPALevel(RF24_PA_MIN); } void loop() { delay(5); radio.stopListening(); // 送信側として動作 Y_pos = analogRead (Y_PIN) ; Angle1 = map(Y_pos, 0, 1023, 0, 180); radio.write(&Angle1, sizeof(Angle1)); delay(5); radio.startListening(); // 受信側として動作 if(radio.available()){ radio.read(&Angle2, sizeof(Angle2)); myservo.write(Angle2); } } |
実際の動作を確認
これまでと違うのは双方向でやり取りしているという点です。
nRF24L01モジュールは送信にも受信にも両方使えるのが便利ですね!
スケッチ解説
2つのアドレスを使い双方向でやり取りをしています。
11 | const byte address[][6] = {"00001", "00002"}; // データを送信するアドレス |
送信側・受信側でアドレスを一致させておく必要があります。
(送信側)
26 27 | radio.openWritingPipe(address[1]); // データ送信先アドレスを指定 radio.openReadingPipe(1, address[0]); // データ受信アドレスを指定 |
(受信側)
26 27 | radio.openWritingPipe(address[0]); // データ送信先アドレスを指定 radio.openReadingPipe(1, address[1]); // データ受信アドレスを指定 |
(送信)radio.openWritingPipe(address[1]) → (受信)radio.openReadingPipe(1, address[1])
という感じですね。
あとはvoid loop()内で送信[radio.stopListening();]・受信[radio.startListening();]を切り替えてデータの送信&受信を繰り返しています。
35 36 37 38 39 40 41 42 43 44 45 46 | delay(5); radio.stopListening(); // 送信側として動作 Y_pos = analogRead (Y_PIN) ; Angle1 = map(Y_pos, 0, 1023, 0, 180); radio.write(&Angle1, sizeof(Angle1)); delay(5); radio.startListening(); // 受信側として動作 if(radio.available()){ radio.read(&Angle2, sizeof(Angle2)); myservo.write(Angle2); } |
【追記】複数データの送信で使ってみる!
「複数のサーボモーターを遠隔で操作したい時、どうすればいいですか?」
というご質問を下記コメント欄に頂きました。
片方向でのデータのやり取りや双方向でのやり取りは簡単な作例をご紹介していました。
コメント頂いたものがどのような用途を想定しているのか分かりませんが、複数データを送信する簡単な作例を追記しておきます。
上記ジョイスティックを使ってサーボモーターを動かす作例では、Y方向(またはX方向)のみのデータを送信し1つのサーボモーターを動かしました。
送信するデータを増やしX方向・Y方向の2つのデータを送信し、受信側はそれに対応したサーボ①とサーボ②を動かすといった作例となります。
接続の追加として送信側Arduinoではアナログ入力端子A1にジョイスティックのX方向(またはY方向)を追加接続し、受信側Arduinoのデジタル端子D4にサーボモーターをもう1本追加で接続しています。
送信側・受信側スケッチは一部スケッチを追加&修正しています。
ジョイスティックで取得したX方向・Y方向の値を配列(変数)に格納してそれぞれ送信、そして受信側も同様にデータを受け取り対応したサーボモーターを動かすといった内容です。
非常に簡単です!
スケッチ(送信側)
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 | // ジョイスティックで複数のサーボを動かす(送信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを送////信するアドレス int X_PIN = A1; int Y_PIN = A0; int Joy_pos[2]; void setup() { radio.begin(); // 無線オブジェクトの初期化 radio.openWritingPipe(address); // データ送信先のアドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.stopListening(); // 送信側として設定 } void loop() { Joy_pos[0] = analogRead(X_PIN); Joy_pos[1] = analogRead(Y_PIN) ; // アナログ値を読み取る radio.write(&Joy_pos, sizeof(Joy_pos)); // アナログ値を送信する delay(10); } |
スケッチ(受信側)
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 | // ジョイスティックで複数のサーボを動かす(受信側) #include <SPI.h> // ライブラリのインクルード #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> Servo myservo1; Servo myservo2; RF24 radio(7, 8); // CE,CSNピンの指定 const byte address[6] = "00001"; // データを受信するアドレス int SERVO1_PIN = 3; int SERVO2_PIN = 4; int Joy_pos; void setup() { Serial.begin(9600); myservo1.attach(SERVO1_PIN); myservo2.attach(SERVO2_PIN); radio.begin(); // 無線オブジェクトの初期化 radio.openReadingPipe(0, address); // データ受信アドレスを指定 radio.setPALevel(RF24_PA_MIN); // 出力を最小に radio.startListening(); // 受信側として設定 } void loop() { while(radio.available()) { // 受信データの確認 int SERVO[2]; radio.read(&SERVO, sizeof(SERVO)); // 受信データの読み込み myservo1.write(map(SERVO[0], 0, 1023, 0, 180)); myservo2.write(map(SERVO[1], 0, 1023, 0, 180)); Serial.print("Servo1: "); // シリアルモニタに受信データを表示する Serial.print(SERVO[0]); Serial.print(" Servo2: "); Serial.println(SERVO[1]); } delay(10); } |
【追記】nRF24L01を安定動作させるための方法!
本記事やSNSで、nRF24L01についてこれまで多くのコメントやご質問等を頂きました。
「無線接続が安定しない時がある」「ESPとのデータのやり取りは出来るのか?」など頂きました。
追記という形で別記事でこれらを簡単にまとめてみました。
本記事と合わせて読んで頂けると理解もしやすいかと思います。

【追記】無線モジュールnRF24L01を使ったロボットカーの製作!
今回ご紹介している無線モジュールnRF24L01を使ったロボットカーを製作しました!
Arduino Uno・L298Nモータードライバ・DCモーター・超音波センサーHC-SR04というシンプルな構成で作れる最小サイズでモデリングし、片手に乗るサイズのミニロボットカーとなっています。

無線モジュールnRF24L01を組み込み自在に動くミニラジコンとして動かすことも出来ます。
【追記】nRF24L01無線モジュール用ブラケットを作ってみました!
今回ご紹介したnRF24L01無線モジュールは、電子工作用途で非常に便利に使え個人的にこれから使う機会が増えてくると思います。
しかしこのモジュールボードには固定するためのネジ穴などが用意されていません。
何か製作物に組み込む場合、固定できるブラケットがあると便利となります。
またテスト動作させる場合もピンヘッダーにジャンパワイヤを使って接続している場合、その接触(ノイズなども)により動作が不安定になる場面もありました。
前者の製作物に組み込む用途でnRF24L01無線モジュール用のブラケットを作ってみましたが、テスト動作などさせる場合もブラケットを取り付けネジ固定や底面に両面テープなどで固定すれば使いやすくなるかと思います。
データはThingiverseの方にアップしているので、興味ある方は使ってみて下さい!

【追記】無線モジュールnRF24L01とジョイスティックシールドのコンビが便利!
ブレッドボードを使いアナログジョイスティックやタクトスイッチなどを接続するには結構な数のワイヤーが必要となってきます。
ジョイスティックシールドに無線モジュールnRF24L01を組み込むと簡単に簡易無線コントローラーとして使え便利となります。
また本記事では作例としてご紹介していませんでしたが、複数データの送信方法は?といった問い合わせを頂いたので簡単なスケッチも紹介しています。

簡単な構成のシールドですが、無線モジュールと組み合わせることによりいろいろと便利に使えそうですね!
【追記】Arduino NanoにnRF24L01モジュールが一体化したRF-Nanoを試してみました
Arduino Nano互換ボードにnRF24L01無線モジュールが一体化したRF-Nanoを試してみました。
nRF24L01は便利な無線モジュールですが組み込みの際にその配線の煩わしさがあります。
RF-NanoはArduinoボードに無線モジュールが一体化しているので便利に使えます!
この投稿をInstagramで見る

【追記】Bluetoothモジュールも試してみました!
Arduinoを手軽に無線通信化するためにBluetoothモジュールも試してみました。
nRF24L01はSPIでのやり取りとなりますが、、HC-05やHC-06などのBluetoothモジュールはUARTによるやり取りとなります。
UARTによるやり取りなので信号線が2本(送信:TX/受信:RX)のみの接続で出来るので比較的簡単に使うことが出来ました。
こちらは以前製作した4足歩行ロボットくんにBluetoothモジュールを組み込んでPCから操作しています。
専用ライブラリなど必要とせずArduinoとは通常のシリアルでのやり取りで使える便利なモジュールとなります。

複数デバイスとの無線でのやり取りが出来るnRF24L01は便利な無線モジュールです。
そしてBluetoothモジュールでの接続はさらに手軽に製作物に組み込んだり出来そうです。
ともに便利な無線モジュールですが、技適が取得されていないのが残念ですね。


【追記】Wi-Fiモジュールも試してみました!
Arduinoに接続して使える無線通信用モジュールとしてWi-Fiモジュールも試してみました。
ESP8266(ESP-01)はArduinoで使える便利な小型Wi-Fiモジュールです。
外観はnRF24L01によく似ていますが、このモジュールが面白いのはArduinoと接続してWi-Fiモジュールとして使う以外にESP-01にスケッチを書き込み単体で動かすことも出来ます。
こうなるとWi-Fi機能を持ったミニArduinoって感じですね!
この投稿をInstagramで見る
スマホアプリからArduinoを操作する方法などもご紹介しています。
この投稿をInstagramで見る
詳しくはこちらの記事をご覧下さい!

【追記】ミニシールドを作ってみました!
nRF24L01は便利な無線モジュールなので製作物に取り付けたりとよく使っています。
しかしテストなどで使いたい場合でSPIでの接続が結構面倒で手間となることから、Arduino Unoに取り付けできるミニシールドを作ってみました。
こちらの記事も参考になればと思います。

【追記】nRF24L01を使ったArduino無線コントローラーの製作!
以前製作した有線タイプのジョイスティックコントローラーをベースにArduinoとnRF24L01モジュールを使ったArduino Controllerを製作しました。
電子工作で作った製作物や、また複数スイッチやジョイスティックを使ったテスト動作などで便利に使える無線コントローラーとなります。
この投稿をInstagramで見る
nRF24L01無線モジュールはWi-FiやBluetoothと比べ接続が非常に早いので、このような無線コントローラーには最適なモジュールですね!

最後に!
電子工作用途で非常に便利に使える無線モジュールです。
ライブラリを使えば比較的簡単に扱えるのもいいですね。
今回ご紹介しきれませんでしたが、このように1つのArduinoから複数のモジュールとのやり取りも出来ます。
先述のように技適に関しては取得されていないのが残念ではありますが・・・個人レベルでのテスト環境での使用にとどめておきます。
そして、これまで作ったものを無線化出来たらまた楽しい遊び方もできそうです。
という事でこのへんで・・・








arduinoを初めて1週間の者です。
nRF24L01 を使って、とりあえずLEDをON/OFFさせたいなと思い、こちらの記事を参考に回路やプログラムを組ませていただきました。
Serial.println(radio.write(&SW_state, sizeof(SW_state)));
Serial.println(SW_state);
というコードを書き、シリアルモニタで確認してみたところ、スイッチの状態は変化しているのですが、radio.write関数で送信する予定のデータは0のまま変化しませんでした。
また、受信側もシリアルモニタで確認してみたところ、データは更新されることがなく、何も受信せず、LEDは光りませんでした。モジュールが不良品の可能性があるのでしょうか。電源の安定化やパスコンの挿入はまだしていませんが、これらの原因として考えられることをご教授いただければ幸いです。
電界強度はここで計算してもらえればわかりますが、0dBmならば3mでも100uV/m程度はありますね。
https://www.circuitdesign.jp/technical/radio-wave-propagation-characteristics/
使用されるなら電波暗室か電波法上のお手続きを(≠技適)お忘れなく。
ありがとうございますm(__)m
そうですよね、Wi-FiやBluetoothモジュールなどと比べこのモジュールは結構電波飛んじゃうんですよね!
電子工作用途ではないのですが、ドローンのVTX(5.8GHz帯)で何度か技適、開局申請はやってその手順自体は分かるので・・・便利なモジュールなので技適取れるなら取っちゃってもいいかなとは思っていますが・・・
ご丁寧に、ありがとうございます。
知識がないため,検討違いな質問をしていたら申し訳ありません。
このモジュールを用いて,データ収集装置として使用することは可能でしょうか。
具体的には,一方でデータ収集(複数のアナログ入力)を行い,もう一方で,PCでデータ表示を行いたいと考えております。
やってみたらうまく行きました!
記事更新までわざわざありがとうございます!
今後もこのブログを参考にしていくと思いますのでよろしくお願いしますm(._.)m
返信ありがとうございます!
用途としては4つのサーボを2つのジョイスティックでそれぞれx、y方向に操作してみたいんですがスケッチに追加してみてもなかなか動いてくれなくて…
ラジコン用の送受信機を自作してみたくていろいろやっております
ラジコン用の自作送信機、いいですねー!
ジョイスティックを1つ使いX方向・Y方向2つのサーボを動かす例を追記しました。
簡単なテストスケッチとなりますが、これだけでも上手く機能するようです。
もう1台ジョイスティックを追加しても理屈は同じなので対応出来るかと思います。
簡単なスケッチなので想定している用途で使えるか分かりませんが、参考になればと思いますm(__)m
複数のサーボを遠隔で動かしたいとき、どうすれば良いですか?
コメントありがとうございます。
「複数のサーボを遠隔で動かしたい場合?」
どのような事を想定しているか分かりませんが・・・基本的には本記事でご紹介したものをベースにスケッチを追加して頂ければ出来ます。
自作した2足歩行ロボットではジョイスティックから取得した複数の値を送信してそれぞれ対応した動作をさせたりしました。
本記事での例ではジョイスティックを使って1つのサーボモーターを制御していますが、例えばX軸・Y軸2つの状態を送信して2つのサーボを制御するということもスケッチを一部修正すれば出来ます。
簡単な方法として送信したい複数の値(データ)を配列(変数)に格納して順次送信して、受信側も同様に受け取りそれぞれのサーボを動かすといった感じです。
想定されている用途が分からないので具体例やうまく説明が出来ませんが・・・、スイマセン!