Lecture 3.3: Multi-Hop Routing and Data Aggregation

Introduction

Good morning, everyone! It’s great to see all of you here, eager to continue our exploration of LoRa technology and LilyGO devices. Over the past few lectures, we’ve delved into the advanced features of LoRa, learned how to implement secure communication using AES encryption, and understood the importance of key management in securing our networks.

Today, we’re going to embark on an exciting journey into the world of **multi-hop routing and data aggregation**. Imagine you’re tasked with deploying a sensor network across a vast forest to monitor environmental conditions. A single LoRa device’s range might not cover the entire area, and you need a way to relay data from distant sensors back to a central point. This is where multi-hop routing and mesh networks come into play.

By the end of this lecture, you’ll have a solid understanding of how to configure your LilyGO devices for multi-hop routing within a mesh network and implement data aggregation techniques suitable for large-scale deployments. We’ll explore practical examples, discuss the challenges you might face, and provide solutions to overcome them.

So, let’s dive in and unlock the potential of mesh networking in expanding the reach and reliability of our LoRa-based communication systems.

 

Section 1: Understanding Mesh Networks and Multi-Hop Routing

Before we get into the technical details, let’s first understand what mesh networks and multi-hop routing are, and why they are essential in IoT deployments.

What is a Mesh Network?

A mesh network is a network topology where each node is connected to one or more other nodes, allowing for data to be transmitted through multiple paths from source to destination. In a mesh network:

Nodes: Devices that can send, receive, and relay data.
Redundancy: Multiple paths between nodes increase reliability.
Scalability: Easy to add more nodes without significant reconfiguration.
Self-Healing: The network can adapt to node failures by finding alternative routes.

What is Multi-Hop Routing?

Multi-hop routing refers to the process where data is passed through multiple intermediary nodes before reaching its final destination. Each node acts as a relay, forwarding data packets to the next node in the route.

Benefits of Mesh Networks and Multi-Hop Routing

Extended Range: Overcome the limitations of individual node range by relaying data.
Robustness: Tolerant to node failures; the network can re-route data dynamically.
Flexible Deployment: Nodes can be placed wherever needed without worrying about direct communication with the central hub.

Applications

– Environmental monitoring over large areas.
– Smart agriculture with distributed sensors.
– Emergency communication networks in disaster-stricken regions.
– Industrial IoT systems across sprawling facilities.

 

Section 2: Challenges in Implementing Mesh Networks with LoRa

While mesh networks offer significant advantages, implementing them with LoRa technology presents unique challenges:

1. Low Data Rate and High Latency

– LoRa’s low data rate and long transmission times can lead to increased latency in multi-hop scenarios.

2. Duty Cycle Limitations

– Regulatory constraints limit the amount of time a device can occupy a frequency channel, impacting how frequently nodes can transmit.

3. Power Consumption

– Nodes acting as relays need to be active more often, consuming more power.

4. Complexity of Routing Protocols

– Implementing efficient routing protocols on resource-constrained devices is challenging.

5. Synchronization

– Ensuring nodes are synchronized to prevent collisions and manage time slots.

Overcoming the Challenges

Throughout this lecture, we’ll address these challenges and explore strategies to mitigate them, enabling us to build effective mesh networks using LilyGO devices.

 

Section 3: Introduction to Mesh Networking Protocols

To implement multi-hop routing, we need a protocol that dictates how nodes communicate and forward data. There are several protocols suitable for mesh networking:

1. Ad-hoc On-demand Distance Vector (AODV)

– A routing protocol designed for mobile ad hoc networks.
– Nodes discover routes on-demand.

2. Routing Protocol for Low-Power and Lossy Networks (RPL)

– Designed for resource-constrained devices.
– Builds a Destination-Oriented Directed Acyclic Graph (DODAG) for routing.

3. LoRa Mesh Libraries

RadioHead Mesh Library: Provides mesh networking capabilities for LoRa devices.
ESP-Now with LoRa: Combines ESP-Now protocol with LoRa for mesh networking.

For our purposes, we’ll focus on using the RadioHead Library, as it supports mesh networking with LoRa and is compatible with Arduino and ESP32 platforms.

 

Section 4: Setting Up the Development Environment

Hardware Requirements

Multiple LilyGO Devices: At least three devices (e.g., T-Beam or T-Deck) to demonstrate multi-hop routing.
LoRa Antennas: Ensure all devices have properly connected antennas.
Power Supplies: USB cables or batteries for powering the devices.

Software Requirements

Arduino IDE: Configured for ESP32 development.
RadioHead Library: We’ll need to install this library to enable mesh networking capabilities.

Installing the RadioHead Library

1. Download the Library

– Visit the official website: [AirSpayce RadioHead](http://www.airspayce.com/mikem/arduino/RadioHead/)
– Download the latest version of the library.

2. Install the Library

– In the Arduino IDE, go to Sketch > Include Library > Add .ZIP Library…
– Navigate to the downloaded ZIP file and select it to install.

Library Overview

The RadioHead library provides a comprehensive set of features:

– Supports various radios, including LoRa modules.
– Provides drivers for different modulation schemes.
– Includes mesh and routing managers for building networks.

 

Section 5: Configuring Devices for Multi-Hop Routing

Let’s get hands-on and configure our devices to form a simple mesh network.

Network Topology

We’ll create a linear network where:

Node A (Source): Sends data to Node C (Destination).
Node B (Relay): Acts as a relay between Node A and Node C.

Assigning Unique Addresses

Each node in the mesh network needs a unique identifier.

Node A: Address 1
Node B: Address 2
Node C: Address 3

Coding the Nodes

Node A: Source Node

Step 1: Include Libraries and Define Addresses

“`cpp
#include <SPI.h>
#include <RHRouter.h>
#include <RHMesh.h>
#include <RH_RF95.h>

#define NODE_ADDRESS 1

// Define RF95 parameters
#define RFM95_CS 18
#define RFM95_RST 14
#define RFM95_INT 26

RH_RF95 rf95(RFM95_CS, RFM95_INT);
RHMesh manager(rf95, NODE_ADDRESS);
“`

Step 2: Setup Function

“`cpp
void setup() {
Serial.begin(115200);
while (!Serial);

pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);

// Initialize LoRa module
Serial.println(“Initializing Node A…”);
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);

if (!rf95.init()) {
Serial.println(“RF95 init failed”);
while (1);
}

rf95.setFrequency(915.0); // Adjust to your regional frequency
rf95.setTxPower(14, false);
}
“`

Step 3: Main Loop

“`cpp
void loop() {
const char *message = “Hello from Node A”;
Serial.println(“Sending message to Node C…”);

uint8_t data[strlen(message) + 1];
strcpy((char*)data, message);

// Send to Node C (Address 3)
uint8_t dest = 3;
if (manager.sendtoWait(data, sizeof(data), dest) == RH_ROUTER_ERROR_NONE) {
Serial.println(“Message sent successfully.”);
} else {
Serial.println(“Message send failed.”);
}

// Wait for a response
uint8_t buf[RH_MESH_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
uint8_t from;

if (manager.recvfromAckTimeout(buf, &len, 3000, &from)) {
Serial.print(“Received reply from Node “);
Serial.print(from);
Serial.print(“: “);
Serial.println((char*)buf);
} else {
Serial.println(“No reply, is Node C reachable?”);
}

delay(10000); // Wait before sending the next message
}
“`

Node B: Relay Node

Step 1: Include Libraries and Define Addresses

“`cpp
#include <SPI.h>
#include <RHRouter.h>
#include <RHMesh.h>
#include <RH_RF95.h>

#define NODE_ADDRESS 2

// Define RF95 parameters
#define RFM95_CS 18
#define RFM95_RST 14
#define RFM95_INT 26

RH_RF95 rf95(RFM95_CS, RFM95_INT);
RHMesh manager(rf95, NODE_ADDRESS);
“`

Step 2: Setup Function

Same as Node A.

Step 3: Main Loop

“`cpp
void loop() {
// Relay node doesn’t initiate messages but needs to call manager.update()
manager.listen();

// Optional: Print status or perform other tasks
}
“`

Note: The `manager.listen()` function allows Node B to receive and forward messages as per the routing protocol.

 

Node C: Destination Node

Step 1: Include Libraries and Define Addresses

“`cpp
#include <SPI.h>
#include <RHRouter.h>
#include <RHMesh.h>
#include <RH_RF95.h>

#define NODE_ADDRESS 3

// Define RF95 parameters
#define RFM95_CS 18
#define RFM95_RST 14
#define RFM95_INT 26

RH_RF95 rf95(RFM95_CS, RFM95_INT);
RHMesh manager(rf95, NODE_ADDRESS);
“`

Step 2: Setup Function

Same as Node A.

Step 3: Main Loop

“`cpp
void loop() {
uint8_t buf[RH_MESH_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
uint8_t from;

if (manager.recvfromAck(buf, &len, &from)) {
Serial.print(“Received message from Node “);
Serial.print(from);
Serial.print(“: “);
Serial.println((char*)buf);

// Send a reply
const char *reply = “Hello Node A, message received!”;
uint8_t data[strlen(reply) + 1];
strcpy((char*)data, reply);

if (manager.sendtoWait(data, sizeof(data), from) == RH_ROUTER_ERROR_NONE) {
Serial.println(“Reply sent successfully.”);
} else {
Serial.println(“Reply send failed.”);
}
}

// Allow the manager to process routing
manager.update();
}
“`

Step 4: Upload and Test

– Upload the respective sketches to Node A, Node B, and Node C.
– Place the nodes such that Node A cannot directly communicate with Node C, but both can reach Node B.

Expected Outcome

– Node A sends a message to Node C.
– Node B relays the message between Node A and Node C.
– Node C replies to Node A through Node B.
– Both Node A and Node C display the received messages on the Serial Monitor.

 

Section 6: Understanding the Routing Mechanism

How Does Routing Work in RHMesh?

Route Discovery: When a node needs to send a message to a destination, it initiates a route discovery process if the route is unknown.
Route Request (RREQ): The source node broadcasts a route request.
Route Reply (RREP): The destination node responds with a route reply.
Routing Table: Nodes maintain a routing table with known routes.

Handling Dynamic Topologies

– The mesh network can adapt to changes, such as nodes moving or going offline.
– Nodes periodically update their routing tables.

Limitations

Memory Constraints: Routing tables consume memory; limited on resource-constrained devices.
Latency: Multi-hop routes increase latency.
Bandwidth Usage: Route discovery and maintenance consume bandwidth.

 

Section 7: Implementing Data Aggregation Techniques

In large networks with numerous nodes, it’s inefficient for every node to send data directly to a central server. Data aggregation helps in:

Reducing Data Traffic: Combining data from multiple nodes into a single packet.
Saving Energy: Less transmission time saves power.
Enhancing Scalability: Allows the network to handle more nodes.

Common Data Aggregation Methods

1. Summarization

– Nodes aggregate data by computing summaries, such as averages, minimums, maximums, or totals.

2. Compression

– Data is compressed to reduce size before transmission.

3. Filtering

– Redundant or irrelevant data is filtered out at intermediate nodes.

4. Hierarchical Aggregation

– Data is aggregated in a hierarchical manner, with intermediate nodes performing aggregation before forwarding.

Implementing Data Aggregation in Code

Let’s modify Node B to perform data aggregation.

Scenario

– Nodes A and D send temperature readings.
– Node B aggregates these readings and forwards an average to Node C.

Node A and Node D: Sensor Nodes

Step 1: Modify the message to include temperature data

“`cpp
float temperature = readTemperatureSensor(); // Replace with actual sensor reading
char message[32];
snprintf(message, sizeof(message), “Temp: %.2f”, temperature);
“`

Node B: Aggregator Node

Step 1: Maintain a buffer for incoming data

“`cpp
struct SensorData {
uint8_t from;
float temperature;
};

SensorData dataBuffer[10];
int dataCount = 0;
unsigned long lastAggregationTime = 0;
const unsigned long aggregationInterval = 60000; // 1 minute
“`

Step 2: Receive Data and Store

“`cpp
void loop() {
uint8_t buf[RH_MESH_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
uint8_t from;

if (manager.recvfromAck(buf, &len, &from)) {
// Parse temperature
float temp;
sscanf((char*)buf, “Temp: %f”, &temp);

// Store data
dataBuffer[dataCount].from = from;
dataBuffer[dataCount].temperature = temp;
dataCount++;

Serial.print(“Received temp from Node “);
Serial.print(from);
Serial.print(“: “);
Serial.println(temp);
}

// Check if it’s time to aggregate and send data
if (millis() – lastAggregationTime > aggregationInterval) {
if (dataCount > 0) {
// Perform aggregation (e.g., compute average)
float sum = 0;
for (int i = 0; i < dataCount; i++) {
sum += dataBuffer[i].temperature;
}
float average = sum / dataCount;

// Send aggregated data to Node C
char aggregatedMessage[32];
snprintf(aggregatedMessage, sizeof(aggregatedMessage), “Avg Temp: %.2f”, average);

uint8_t dest = 3; // Node C
uint8_t data[strlen(aggregatedMessage) + 1];
strcpy((char*)data, aggregatedMessage);

if (manager.sendtoWait(data, sizeof(data), dest) == RH_ROUTER_ERROR_NONE) {
Serial.println(“Aggregated data sent to Node C.”);
} else {
Serial.println(“Failed to send aggregated data.”);
}

// Reset buffer
dataCount = 0;
}
lastAggregationTime = millis();
}

// Allow the manager to process routing
manager.update();
}
“`

Node C: Data Sink

Step 1: Receive Aggregated Data

“`cpp
void loop() {
uint8_t buf[RH_MESH_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
uint8_t from;

if (manager.recvfromAck(buf, &len, &from)) {
Serial.print(“Received aggregated data from Node “);
Serial.print(from);
Serial.print(“: “);
Serial.println((char*)buf);

// Process data as needed
}

manager.update();
}
“`

Section 8: Optimizing Network Performance

Strategies for Efficient Mesh Networking

1. Time Synchronization

– Synchronize nodes to prevent collisions and manage sleep schedules.

2. Adaptive Duty Cycling

– Nodes adjust their active periods based on network traffic and power availability.

3. Efficient Routing Protocols

– Use lightweight protocols optimized for low-power, lossy networks.

4. Selective Data Transmission

– Only transmit significant changes or anomalies to reduce unnecessary traffic.

5. Load Balancing

– Distribute data forwarding responsibilities to prevent overloading certain nodes.

 

Section 9: Power Management in Mesh Networks

Challenges

– Nodes acting as routers consume more energy.
– Battery-powered nodes need efficient power management strategies.

Solutions

1. Energy Harvesting

– Utilize solar panels or other energy harvesting methods to power nodes.

2. Sleep Modes

– Implement deep sleep modes when nodes are idle.
– Wake up periodically to check for data or perform tasks.

3. Duty Cycling

– Schedule nodes to be active only when necessary.

4. Low-Power Routing Protocols

– Design protocols that minimize energy consumption.

Example: Implementing Sleep Mode

“`cpp
void loop() {
// Perform tasks

// Enter deep sleep
esp_sleep_enable_timer_wakeup(wakeInterval * 1000000);
esp_deep_sleep_start();
}
“`

Section 10: Scaling Up – Managing Large Networks

Considerations for Large Deployments

– Routing Table Size

– Limited memory requires efficient routing table management.

– Network Segmentation

– Divide the network into clusters to manage scalability.

– Hierarchical Topologies

– Implement hierarchical routing to reduce complexity.

– Data Management

– Use edge computing to process data locally before transmission.

Tools and Technologies

– LoRaWAN

– Leverage LoRaWAN for large-scale networks with gateway infrastructure.

Custom Protocols

– Develop custom protocols tailored to specific application needs.

 

Conclusion

Today, we’ve journeyed through the intricacies of multi-hop routing and data aggregation in LoRa mesh networks. We’ve seen how to configure our LilyGO devices to relay messages across multiple nodes, effectively extending the range and robustness of our communication systems.

By implementing data aggregation techniques, we’ve learned how to optimize network traffic, conserve energy, and handle large-scale deployments efficiently. These skills are invaluable in building scalable, reliable, and efficient IoT networks that can operate in diverse environments and meet various application requirements.

As you continue to experiment and develop your projects, I encourage you to explore different mesh networking protocols, optimize your network configurations, and consider the unique challenges of your specific applications.

Remember, the key to mastering mesh networks lies in understanding both the theoretical concepts and practical implementation details. Don’t hesitate to delve deeper, ask questions, and share your experiences.

 

Questions and Discussion

Let’s open the floor for any questions or insights you’d like to share.

Question: Can we implement encryption and security measures in our mesh network communications?

Answer: Absolutely! Security is crucial, even more so in mesh networks where data passes through multiple nodes. You can integrate the encryption methods we discussed in the previous lecture, such as AES encryption, into your mesh network communications. Ensure that all nodes share the necessary keys and that encryption is handled appropriately at each hop.

Question: What happens if a node in the mesh network fails or goes offline?

Answer: One of the strengths of mesh networks is their ability to self-heal. If a node fails, the routing protocol can find alternative paths to route data around the failed node. However, the effectiveness depends on the network’s topology and the availability of alternative routes. Designing your network with redundancy in mind enhances its resilience.

Question: How does duty cycle regulation affect mesh networks in regions with strict limitations?

Answer: Duty cycle regulations limit the amount of time a device can transmit on a specific frequency. In mesh networks, where nodes may need to transmit more frequently to relay data, this can be challenging. Strategies to mitigate this include:

Frequency Hopping: Use multiple frequencies to spread transmissions.
Adaptive Data Rates: Adjust data rates to reduce transmission times.
Efficient Protocols: Minimize unnecessary transmissions.

Always ensure compliance with local regulations to avoid legal issues and interference with other services.

 

Additional Resources

RadioHead Library Documentation: Explore more features and advanced configurations.
LoRa Alliance: Provides guidelines and best practices for LoRa networks.
Mesh Networking Protocols: Research AODV, RPL, and other protocols for deeper understanding.

 

Closing Remarks

As we conclude today’s lecture, I hope you’re inspired to explore the possibilities that mesh networking and multi-hop routing offer in expanding the capabilities of your IoT projects. The techniques we’ve covered empower you to build networks that are not only robust and scalable but also adaptable to the ever-changing environments they operate in.

In our next lecture, we’ll delve into implementing a mesh network with LilyGO devices in a step-by-step guide, allowing you to apply what you’ve learned today in a practical, hands-on manner.

Thank you for your attention and active participation. I look forward to seeing the innovative solutions you’ll create.

“See you all in the next lecture!”

 

‘Fix the broken countries of the west through increased transparency, design and professional skills. Support Skills Gap Trainer.’


To see our Donate Page, click https://skillsgaptrainer.com/donate

To see our Twitter / X Channel, click https://x.com/SkillsGapTrain 

To see our Instagram Channel, click https://www.instagram.com/skillsgaptrainer/

To see some of our Udemy Courses, click SGT Udemy Page

To see our YouTube Channel, click https://www.youtube.com/@skillsgaptrainer

Scroll to Top