Loramesherライブラリは、Loraノード間でメッセージを通信するための距離ベクトルルーティングプロトコルを実装しています。 LORA無線チップとの相互作用については、さまざまなLORAシリーズモジュールをサポートする多用途の通信ライブラリであるRadiolibを活用します。
現時点では、Loramesherは次のモジュール内でテストされています。
問題を開くことにより、別のモジュールをライブラリに追加するようにリクエストできます。
詳細については、 library.jsonを確認できます。基本的に、メンテナンスタスクのスケジューリングのために、異なるLORAモジュールとフレートスへの低レベルの通信を実装するRadiolibを使用します。
この最初の実装のソースファイルには、新しい機能をテストする例があります。この例は、10秒ごとにブロードキャストメッセージを送信するカウンターの実装です。理解しやすくするために、MicrocontrollerをLoramesherライブラリで動作させるために必要ではない追加の機能を削除します。
概念実証として、Lora上に数値カウンターを送信します。その値は10秒ごとに増加し、TEパケットが送信されます。開始するには、使用するデータの種類を実装する必要があります。
この場合、カウンター自体であるuint32_tのみを送信します。
uint32_t dataCounter = 0;
struct dataPacket {
uint32_t counter = 0;
};
dataPacket* helloPacket = new dataPacket;
新しい実装を初期化するために、ライブラリが使用するLORAパラメーターを構成できます。ノードがアプリケーションにメッセージを受信する必要がある場合は、受信したパケット機能セクションを参照してください。
LORA構成に異なるパラメーターを構成できます。 LoRaMesherConfigを使用すると、次のパラメーターを構成できます(必須*):
この構成を使用してLORAMESHERを構成する方法の例を次に示します。
//Get the LoraMesher instance
LoraMesher& radio = LoraMesher::getInstance();
//Get the default configuration
LoraMesher::LoraMesherConfig config = LoraMesher::LoraMesherConfig();
//Change some parameters to the configuration
//(TTGO T-Beam v1.1 pins)
config.loraCS = 18
config.loraRst = 23
config.loraIrq = 26
config.loraIo1 = 33
config.module = LoraMesher::LoraModules::SX1276_MOD;
//Initialize the LoraMesher. You can specify the LoRa parameters here or later with their respective functions
radio.begin(config);
//After initializing you need to start the radio with
radio.start();
//You can pause and resume at any moment with
radio.standby();
//And then
radio.start();
無線周波数に適用される現地の法律に注意してください
ノードが他のノードからパケットを受信する必要がある場合は、次の手順に従う必要があります。
ライブラリがアプリのパケットを受信するたびに通知を取得する関数は、次のように見えます。
/**
* @brief Function that process the received packets
*
*/
void processReceivedPackets(void*) {
for (;;) {
/* Wait for the notification of processReceivedPackets and enter blocking */
ulTaskNotifyTake(pdPASS, portMAX_DELAY);
//Iterate through all the packets inside the Received User Packets FiFo
while (radio.getReceivedQueueSize() > 0) {
Serial.println("ReceivedUserData_TaskHandle notify received");
Serial.printf("Queue receiveUserData size: %dn", radio.getReceivedQueueSize());
//Get the first element inside the Received User Packets FiFo
AppPacket<dataPacket>* packet = radio.getNextAppPacket<dataPacket>();
//Print the data packet
printDataPacket(packet);
//Delete the packet when used. It is very important to call this function to release the memory of the packet.
radio.deletePacket(packet);
}
}
}
注意する必要があるいくつかの重要なことがあります:
void*が必要です。ulTaskNotifyTake(pdPASS,portMAX_DELAY)または同等のものを持っていることが必須です。この機能により、ライブラリは機能に通知して保留中のパケットを処理できます。radio.getReceivedQueueSize()のサイズを取得する機能があります。radio.getNextAppPacket<T>()で最初の要素を取得できます。ここで、Tはデータのタイプです。radio.deletePacket(packet)に電話する必要があります。パケットに割り当てられたメモリが解放されます。実行されていない場合、メモリリークやメモリエラーが発生する可能性があります。 TaskHandle_t receiveLoRaMessage_Handle = NULL;
/**
* @brief Create a Receive Messages Task and add it to the LoRaMesher
*
*/
void createReceiveMessages() {
int res = xTaskCreate(
processReceivedPackets,
"Receive App Task",
4096,
(void*) 1,
2,
&receiveLoRaMessage_Handle);
if (res != pdPASS) {
Serial.printf("Error: Receive App Task creation gave error: %dn", res);
}
}
radio.setReceiveAppDataTaskHandle(receiveLoRaMessage_Handle);
このセクションでは、 AppPacket内にあるものを示します。
class AppPacket {
uint16_t dst; //Destination address, normally it will be local address or BROADCAST_ADDR
uint16_t src; //Source address
uint32_t payloadSize = 0; //Payload size in bytes
T payload[]; //Payload
size_t getPayloadLength() { return this->payloadSize / sizeof(T); }
};
AppPacket<T>* packet = radio.getNextAppPacket<T>() :
packet->getPayloadLength() tの数でペイロードサイズを取得しますradio.deletePacket(packet)このパケットに割り当てられたメモリをリリースします。このセクションでは、パケットの作成と送信方法を示します。この例では、 AppPacketデータ構造を使用します。
void loop() {
helloPacket->counter = dataCounter++;
//Create packet and send it.
radio.createPacketAndSend(BROADCAST_ADDR, helloPacket, 1);
//Or if you want to send large and reliable payloads you can call this function too.
radio.sendReliable(dstAddr, helloPacket, 1);
//Wait 10 seconds to send the next packet
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
前の数字では、Hellopacketを使用していることがわかり、その中にカウンターを追加し、Loramesherを使用してパケットを作成して送信します。
このコードの最も重要な部分はradio.createPacketAndSend()で呼び出す関数です。
パケットを受け取るときは、キューが何を返すかを理解する必要があります。このため、次のサブセクションでは、簡単なパケット処理を実装する方法について説明します。
/**
* @brief Print the counter of the packet
*
* @param data
*/
void printPacket(dataPacket data) {
Serial.printf("Hello Counter received n %dn", data.counter);
}
/**
* @brief Iterate through the payload of the packet and print the counter of the packet
*
* @param packet
*/
void printDataPacket(AppPacket<dataPacket>* packet) {
//Get the payload to iterate through it
dataPacket* dPacket = packet->payload;
size_t payloadLength = packet->getPayloadLength();
for (size_t i = 0; i < payloadLength; i++) {
//Print the packet
printPacket(dPacket[i]);
}
}
processReceivedPackets()関数でパケットを受信した後、 printDataPacket()関数を呼び出します。packet->payloadを使用してパケットのペイロードを取得する必要があります。packet->getPayloadLength()を繰り返します。これにより、DataPacketsタイプでは、特定のパケットのペイロードがどれだけ大きいかを知らせます。私たちの場合、常に1つのデータパケットのみを送信します。printPacket(dPacket[i])関数を呼び出します。 詳細な説明については、オープンアクセスペーパー「Lora Meshライブラリの実装」をご覧ください。アカデミックな仕事でLoramesherライブラリを使用する場合は、以下を引用してください。
@ARTICLE{9930341,
author={Solé, Joan Miquel and Centelles, Roger Pueyo and Freitag, Felix and Meseguer, Roc},
journal={IEEE Access},
title={Implementation of a LoRa Mesh Library},
year={2022},
volume={10},
number={},
pages={113158-113171},
doi={10.1109/ACCESS.2022.3217215}}