ArduinoやESPなどのマイコンボードを使った電子工作で便利に使える無線モジュールにnRF24L01があります。
nRF24L01は2.4GHz帯の電波を使った無線モジュールとなり日本での技適が取得されていないためその使用には注意が必要ですが、安価で入手もしやすいためマイコンを使った無線通信の学習用としても適していると思います。
nRF24L01無線モジュールはSPIインターフェイスを介してマイコンボードと接続します。
ArduinoやESP系のマイコンボード(ESP8266/ESP32)、Raspberry Pi PicoなどSPIでの接続が出来ればマイコンボードの種類を問わず接続して使うことが出来ます。
Arduino間での無線通信やESP同士、またArduinoとESP間といった具合に使うことが出来ます。
マイコンを使った電子工作用途で非常に便利に使える無線モジュールですが、先述のように技適が取得されていないのが残念ではあります。
便利な無線モジュールなので以前ブログ記事としてまとめました。
Arduinoを使ったnRF24L01無線モジュールの基本的な使い方をまとめています。
無線部分のスケッチも比較的扱いやすくWi-FiやBluetoothと比べて接続が非常に速いため、Arduinoをベースとしたこのような無線コントローラーも作ってみました。
マイコンが起動すると即無線接続が完了するので、このようなコントローラーの製作には向いていますね!
この投稿をInstagramで見る
そしてnRF24L01は複数モジュール間での無線通信も出来るため、このように1台のコントローラーを使って2台のロボを同時に動かすなんてことも出来ます。
この投稿をInstagramで見る
コントローラー(送信機)はArduinoで動かしていますが、もちろんESPなど他のマイコンボードでデータを送受信する事も出来ます。
非常に便利な無線モジュールですね!
nRF24L01の基本的な使い方は上記記事でまとめたのですが、ブログ記事へのコメントやお問い合わせ、またSNSにも多く頂くことからArduino以外のマイコンボードとの接続や安定動作させるための方法など少し上記記事の追記として残しておきます。
目次
nRF24L01無線モジュールを安定動作させるための方法!
nRF24L01無線モジュールはSPI接続によりマイコンボードとデータのやり取りを行います。
SPIでの接続なので、MISO/MOSI/SCK/SS(CE/CNS)とマイコン側で使われるIO端子の数が少し多くなりますが、基本的にSPIでの接続が出来ればArduino以外にもESPなど他のマイコンボードでも扱うことが出来ます。
そしてnRF24L01についてこちらの記事でまとめたのですが、これまで多くのご質問を頂きました。
複数データを送信する方法などよく使われることが想定できるものは追記という形で上記記事内に追加したのですが、特に多かった以下内容について本記事で追記しておきます。
上記記事と合わせて読んで頂ければと思います。
- 無線を安定動作させるには
- 無線接続が切れた際にプログラムが暴走等しないようにするには
- 異なるマイコン間での通信方法
nRF24L01モジュールの接続方法
前回の記事内容と重複しますが、nRF24L01モジュールについて簡単に見ておきます。
nRF24L01モジュールのピン配列はこのようになっています。
モジュールの駆動電圧は3.3V、SPIインターフェイスを介してArduinoなどのマイコンボードとデータのやり取りを行います。
ArduinoのSPIに関してはこちらの記事で詳しく解説しているので合わせて読んで頂ければと思います。
nRF24L01を駆動するための駆動電圧は3.3Vとなっています。
これまでこのモジュールを使ってきてArduinoで使う場合、この電圧が少し厄介でトラブルの原因になることが多かったです。
安定した動作をさせるには、十分な電流を供給する事が出来る安定した3.3Vの電源が必要となってきます。
またノイズの影響も受けやすいモジュールでもあります。
ブレッドボードでのテストレベルではあまり問題になりませんが、マイコンで作ったラジコンなど製作物を実稼働させる場合はノイズの影響も考慮した方が良くなります。
まず前回の記事内容のArduinoとの接続を見ておきます。
ArduinoではSPI端子がボードによって決まっています。
詳しくは上記SPIの記事を参考にして下さい。
Arduino Unoを例に見てみます。
Arduino UnoではSPI接続で使える端子は、デジタルピンD10がSS端子、D11がMOSI、D12がMISO、D13がSCKとなります。
このSPIピンを使いnRF24L01の対応した端子同士を接続するだけです。
こんな感じですね。
送信側・受信側、ともに接続は同じです。
Arduino | nRF24L01 |
3.3V | VCC |
GND | GND |
D9(※空いているデジタル端子を任意で指定可能) | CE |
D10(※空いているデジタル端子を任意で指定可能) | CSN |
D11 | MOSI |
D12 | MISO |
D13 | SCK |
nRF24L01の駆動電圧は3.3Vなので、Arduinoの[3.3V]端子を使い電源供給を行う形となりますが・・・
①無線を安定動作させるには
十分な電流を供給できる3.3V電源が必要
上記がArduinoとの基本的な接続となりますが、この接続では動作が安定しない場合があります。
Arduinoの[3.3V端子]は[5V端子]とは違い流せる電流がそれほど多くありません。(公式サイトで確認下さい!)
nRF24L01は無線モジュールとなりその動作には比較的多くの電流が必要となるため、ボードにもよりますがArduinoの[3.3V端子]からの電力供給では電流が不足し動作が不安定になる場合があります。
このような場合には、Arduinoとは別系統の3.3V電源を用意するか、またArduinoの[5V端子]に降圧モジュールを接続し3.3Vを作り出せば安定動作させることが出来ます。
ブレッドボードでの動作では、このような小型な3.3V降圧モジュールがあると便利です!
Arduinoの[5V端子]からでも安定してnRF24L01を動作させることが出来ます。
また、このようなnRF24L01専用アダプタも販売されています。
ボードに3.3V降圧レギュレータが搭載されたアダプタでArduinoの[5V端子]を使って電源供給を行うことができます。
やっていることは上記と同じです。
このような5Vから電源を取るためのアダプタが販売されているということは、やはりArduino側の[3.3V端子]からの電源供給では電流が不足する場合があるということだと思います。
Arduinoのボードでは、[3.3V端子]では流せる電流が少ないためnRF24L01以外にもESP8266などを使いWi-Fi接続する場合も同様に動作が不安定になることは多い印象です。
nRF24L01モジュールの駆動には十分な電流を供給出来る安定した3.3V電源が必要となってきます。
デカップリングコンデンサの接続
nRF24L01無線モジュールは先述のように安定した電源供給を行う必要があり、またノイズの影響も受けやすいモジュールとなります。
ブレッドボードでの簡単なテストではあまり気になることはありませんが、製作物に組み込み動かす場合などでノイズの影響を受け動作が不安定になることはよくありました。
nRF24L01のVCC/GND間に1本デカップリングコンデンサを入れておくのが望ましくなります。
マイコンを使った電子工作では、電源ライン(VCC・GND間)にコンデンサを入れることがよくあります。(マイコンボード内には絶対に入っています)
このコンデンサのことをデカップリングコンデンサと呼びます。
バイパスコンデンサやパスコンと呼ばれることもあります。
- ノイズをGNDに逃したり、IC等にノイズが流入・流出するのを防ぐ
- 接続しているICやモジュールに必要な電力を補給する
- 電源電圧の変動を防ぐ など
正確なコンデンサの容量は通常あまり問題にならないと思いますが、nRF24L01のデータシートなどを見ると4.7μF〜47μFあたりのものがよく使われているようです。
nRF24L01無線モジュールの動作が安定しない原因の多くは、これら電源周りの問題が多いようです。
冒頭でご紹介したArduino Controllerの製作でいろいろと試したましたが、送信側・受信側ともにこのような対策を行っておけば動作も問題なく安定するようです。
②無線接続が切れた際にプログラムが暴走等しないようにするには
nRF24L01は無線接続が速くマイコンを使ったラジコンなどを動かす用途に使われることが多いと思いますが、送信・受信間の無線接続が何らかの原因で切れた際に暴走(意図しない動き)する場合があります。
いろんなパターンが想像できますが、無線の接続が切れるとデータの受け渡しが行われなくなるので当然データを格納している変数の値が更新されなくなります。
例えば、データを受信してそのデータを変数に格納しそれを使ってモーターを制御する用途で使っている場合、無線が切れたことによりその変数の値が更新されず前回の値のままとなりモーターが動き続ける・・・みたいなことが起こる原因となります。
これはスケッチで簡単に対応する事が出来ます。
受信側の無線モジュールからのデータが一定期間更新されていない場合(データを受信していない状態)に特定の動作をさせるというものです。
例えばこのようなスケッチを作ってみました。
これは受信側のスケッチとなりますが、一定期間(1秒間)送信側からのデータを受信できない状態になると特定の動作(dataReset()という関数を実行)をするというものです。
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 | #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Wire.h> RF24 radio(9, 10); // nRF24L01(CE,CSN) const byte address[6] = "00001"; // アドレスをセット unsigned long currentreceptionTime = 0; unsigned long lastreceivedTime = 0; int SW_state; void setup(){ // 無線通信の開始 radio.begin(); radio.openReadingPipe(0, address); radio.setPALevel(RF24_PA_MIN); radio.startListening(); dataReset(); } void loop(){ // 受信データが有るかどうかを確認する if(radio.available()){ radio.read(&SW_state, sizeof(SW_state)); lastreceivedTime = millis(); } // 最後にデータを受信してから1秒以上経過するとdataReset()関数を実行 currentreceptionTime = millis(); if( currentreceptionTime - lastreceivedTime > 1000){ dataReset(); } // *** loop内の処理 *** } // 無線接続が切れた際の処理 void dataReset(){ // *** 無線接続が切れた際の処理を記述 *** } |
これで何かしらの影響で電波が途切れてしまい受信できない状態が続くと、作成したdataReset()という関数を実行して対処する事が出来ると思います。
例えばモーターを動かすものであれば停止させるという動作を記述しておけば暴走等を防止することが出来ます。
nRF24L01は一旦無線での接続が完了すると接続が切れることはありませんが、自作したロボットやラジコンなど動くものを使った制御で使う場合にこのように工夫しておくと安心ですね!
③異なるマイコン間での通信方法
最後にArduinoとESP間など異なるマイコンボード間での通信に関してです。
接続に関しては各マイコンボードで指定されているSPI端子を使って接続するのは全く同じですが、データの受け渡しで使う変数の型(Byte数)には注意する必要があります。
Arduinoに接続したnRF24L01からデータを送信し、ESP8266に接続したnRF24L01でデータを受信する場合を考えてみます。
当ブログで以前紹介したWeMos D1 MiniというESP8266開発ボードを例にしてみます。
接続はこのようになります。
CE/CSNはスケッチで任意に変更できることは同様です。
NodeMCUなど他のESP8266ボードでも機能します。
WeMos D1 Mini(ESP8266) | nRF24L01 |
3.3V | VCC |
GND | GND |
GPIO15(D8) | CE |
GPIO4(D2) | CSN |
GPIO13(D7) | MOSI |
GPIO12(D6) | MISO |
GPIO14(D5) | SCK |
スケッチもこれまでとほぼ同様なものが使えますが、マイコンボードの仕様によりデータ受け渡しで使う変数の型は注意が必要です!
詳しいスケッチは前回の記事を参考にして下さい!
nRF24L01無線モジュールは1回の送信で最大32バイトのデータを送信することが出来ます。
そしてArduinoで使える変数の型にはいろいろとありますが、例えばint型では符号付きの整数が扱われ2バイトを使って格納されます。
またbyte型なら1バイト、float型なら4バイトといった具合です。
このように複数の変数に格納されたデータを一気に送信(最大32バイト分)するわけですが、当然受信側も同様に受信していかないと上手くデータの受け渡しができなくなります。
Arduino同士では変数の型は同じものを使えば問題ないのですが、ESPなど他のマイコンボード間で使用する場合は少し意識する必要が出てきます。
例えばESP8266ではint型は4バイトで扱われるなど仕様が異なっています。
同じ変数の型で違ったマイコン間でやり取りしていると、格納されるデータの大きさが変わってくるので上手くデータの受け渡しが出来ない原因となります。
詳しくは割愛しますが、例えばArduino側の変数の型がbyte型(符号なし1バイト)ならESP側では[uint8_t]と記述し、int型(符号付き2バイト)なら[int16_t]とするなど、このあたり少し意識して扱う必要が出てきます。
あとは接続等、ほぼ同じなので異なるマイコン間でもデータの送受信を行うことができます。
この投稿をInstagramで見る
もちろんESP32とのやり取りも同様に行うことができます。
この投稿をInstagramで見る
最後に!
nRF24L01無線モジュールは技適が取得されていないためその使用には注意が必要ですが、便利に使える無線モジュールです。
テスト環境でも便利に使えることからnRF24L01を使ったArduino Controllerを製作しましたが、製作物を操作する以外にもちょっとした動作テストをしたい場合にジョイスティックやタクトスイッチ、ポテンショメーターなどをブレッドボードを使って配線する手間もなく、Arduino以外のマイコンボードを制御する事も出来るので非常に便利です。
Arduino目線でnRF24L01の記事を書いていたことからESPで上手くデータのやり取りが行えないといった質問やモジュール自体が安定動作しないといった質問等頂いたことから簡単に追記記事としてまとめてみました。
詳細なスケッチ等は省略しましたが、基本的にこちらの記事で書いたものと同じなので合わせて読んで頂けると理解しやすいかと思います。
教えて頂きたいことがあり、インスタグラムのDMに内容を送らせて頂いています。お時間ある際にお答えして頂けますと助かります
すいません!
インスタのコメント&DMが非常に多いので確認出来ていませんでした。
後ほど確認させて頂きますm(__)m
受信部分のみテストしてみましたが、こんな感じのイメージでしょうか?
スイッチ部分は送信側に付け、無線部分はnRF24L01の記事を参考にして頂き組み合わせてもらえばと思います。
https://www.instagram.com/p/CkieK8fPcwW/