Loramesher Library는 LORA 노드간에 메시지를 전달하기위한 원격 벡터 라우팅 프로토콜을 구현합니다. LORA 라디오 칩과의 상호 작용을 위해, 우리는 다양한 LORA 시리즈 모듈을 지원하는 다양한 통신 라이브러리 인 Radiolib를 활용합니다.
이 순간 Loramesher는 다음 모듈 내에서 테스트되었습니다.
문제를 열어 다른 모듈을 라이브러리에 추가하도록 요청할 수 있습니다.
자세한 내용은 library.json 확인할 수 있습니다. 기본적으로, 우리는 유지 보수 작업을 예약하기 위해 다른 LORA 모듈과 Freertos와의 낮은 수준의 통신을 구현하는 Radiolib를 사용합니다.
이 첫 번째 구현의 소스 파일에는 새로운 기능을 테스트하는 예입니다. 이 예제는 카운터 구현으로 10 초마다 방송 메시지를 전송합니다. 이해하기 쉽게하기 위해 Microcontroller가 Loramesher Library와 함께 작동하도록 할 필요가없는 추가 기능을 제거합니다.
개념의 증거로서, 우리는 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을받은 후 사용할 기능.
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() 반복합니다. 이렇게하면 주어진 패킷에 대한 페이로드가 데이터 패킷 유형에서 얼마나 큰지 알려줍니다. 우리의 경우, 우리는 항상 하나의 Datapacket 만 보냅니다.printPacket(dPacket[i]) 함수를 호출하십시오. 자세한 설명은 Open Access Paper "Lora Mesh 라이브러리 구현"을 참조하십시오. 학업에서 Loramesher Library를 사용하는 경우 다음을 인용하십시오.
@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}}