Njord Project

Build an awesome drone from scratch

無線通信(NRF24L01)

さっきの記事ではモーターの管制する為にライブラリを書いた私たちの紹介しました。最近は、無線通信のコンポーネントに私たちが働いていました。今、ライブラリは出来上がりましたから、無線通信のライブラリを紹介します。

ライブラリ

始めに以下の写真は問題になっているコンポーネントの写真です。予想通り、このコンポーネントがドローンの欲しい大きさを取得する為に、十分に小さいです。

NRF24L01

このコンポーネントはNordic Semiconductorが作ります。Arduinoの共通性の中でNRF24L01がとても有名です。だから、インターネットに使用例とライブラリがたくさんあります。それでは、私たちがこのコンポーネントの成功を利用して、Radioheadのライブラリに基づいて私たちのライブラリを構築しています。RadioheadのライブラリはPaul Stoffregenが提案しています。

一台の送信機は私たちのCommunicationのクラスのインスタンスで表現します。以下のコードはCommunicationのクラスの声明です。


#include <SPI.h>
#include <RH_NRF24.h>

class Communication {
private:
	RH_NRF24 _nrf24;
public:
	Communication(int pin1, int pin2);
 	bool initRadio();
	bool sendMsg(uint8_t* data, uint8_t len, uint8_t channel);
	bool receiveMsg(uint8_t* data, uint8_t len, uint8_t channel);
};
					

ご覧のように、このクラスは素朴です。 アトリビュートだけ一つとメソッドだけ三つがあります。アトリビュートはRadioheadのライブラリから来て、一台のNRF24L01を表現します。このアトリビュートとメソッドでドローンとサーバーの間通話を確かめます。initRadio()のメソッドはコンポーネントの状態に色々なテストをします。正しい初期化とチャンネルと伝送速度と伝達動力のチェックします。値に応じて準備の出来たと見做すか否か。


bool Communication::initRadio() {
	bool state = true;
	if(!_nrf24.init())
			state = false;
	if(!_nrf24.setChannel(1))
			state = false;
	if(!_nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
			state = false;
	return state;
}
					

他の二つメソッドはデータのトランスミッションとデータのレセプションを処理するが、特じゃありませんだから、この記事で私たちが説明をしません。

具体的に、メッセージのタイプが二つあります:

サーバーから来るメッセージは整数の配列です。レングスは4です。目標位置(xとyとz)をドローンへ連絡します。 ドローンから来るメッセージも整数の配列ですが、レングスは11です。ドローンの番号(チャネル)と目標位置(xとyとz)と六台の超音波センサーの値を連絡します。

メッセージのタイプに関係なく、追加の数があります。この最後の数はエラーコードやドローンの状態について情報や特定な要求を連絡する為。例えば、もしサーバーがドローンへ0の値を送れば、「基地に帰りなさい」の意味するかもしれません。そして、もし、ドローンがサーバーへ10の値を送れば、「電池もうありません」の意味するかもしれません。

いつものように私たちのGitHubでライブラリをダウンロード出来ます。

テスト

私たちのライブラリの実行を確かめる為に、私たちがテストコードをArduino語で書きました。もし、方はこのライブラリを使ってみたいと、二台の電気回路が要ります。


#include <SPI.h>
#include <RH_NRF24.h>
#include <communication.h>

uint8_t msg[] = {1, 2, 3, 4};
uint8_t len = sizeof(msg);
bool ok;
Communication com(8, 10);

void setup() {
	Serial.begin(9600);
	ok = com.initRadio();
	if(!ok)
		Serial.println("Init error");
}

void loop() {
	ok = com.sendMsg(msg, len, 1);
	if(!ok)
		Serial.println("Sending error");

	ok = com.receiveMsg(msg, len, 1);
	if(!ok)
		Serial.println("Receiving error");
	else
		Serial.println(msg[0]);
}
					

以上のコードは単にCommunicationのクラスから一つのオブジェクトをインスタンス化して初期化します。主要なループで同じチャンネルを使う他のコンポーネントと連絡します。

私たちがたくさん別なライブラリを使ってみましたから、このコンポーネントを正しく使うのがたくさん時間を掛かりました。そして、問題に向かいました:BのコンポーネントからAのコンポーネントはメッセージを取り受けったら、Bへ返事を送りませんでした(かどうか確定的に)。私たちがサプライとグランドの間に10uFのコンデンサを追加しました。もし、私たちがインターネットで読んだ事に参照しますと、Arduinoボードは低いサプライを引き渡しますから。

次の記事はジャイロスコープのライブラリについてです。