37  ::: {style=“overflow-x: auto;”}

title: “IoT Protocol Review: Hands-On Labs” difficulty: advanced —

Key Concepts
  • Lab Review: A retrospective analysis of hands-on exercises to consolidate learning and identify gaps before assessment
  • Packet Trace Analysis: Interpreting captured network frames to verify protocol behaviour and measure overhead
  • Configuration Verification: Checking that protocol parameters (QoS, topic hierarchy, CoAP options) match design requirements
  • Error Diagnosis: Identifying the root cause of failed connections or dropped packets using logs and traces
  • Performance Baseline: The measured latency and throughput of a correctly configured protocol stack, used as a reference for detecting degradation
  • Lab Report Structure: The standard format for documenting observations, measurements, and conclusions from a practical exercise
  • Peer Review: Evaluating another student’s lab configuration and results to identify errors and learn alternative approaches

37.1 In 60 Seconds

This advanced lab builds ESP32-based packet analyzers to inspect IoT protocol structures at the byte level. You will calculate header sizes, implement tools that decode protocol fields in real-time, diagnose communication problems through low-level analysis, and optimize message payloads to minimize protocol overhead on constrained networks.

37.2 Learning Objectives

By the end of this chapter, you will be able to:

  • Calculate protocol overhead: Determine header sizes and efficiency for different protocol stacks quantitatively
  • Construct packet analyzers: Implement ESP32 tools to inspect protocol structures at byte level
  • Diagnose protocol issues: Use low-level analysis to identify communication problems
  • Optimize message payloads: Design efficient payloads that minimize protocol overhead on constrained networks

37.3 Prerequisites

Required Chapters:

Technical Background:

  • Protocol stack concepts
  • C/C++ programming for ESP32
  • Understanding of bytes and bits

Hardware Required:

  • ESP32 development board
  • USB cable
  • Computer with Arduino IDE

Estimated Time: 25 minutes

What is protocol overhead? Protocol overhead is the “wrapper” that protocols add to your actual data. Like shipping a small item in a big box with lots of packing material, protocols add headers that can be much larger than your actual payload.

Why does this matter? For IoT devices: - Battery life: More bytes = more radio time = shorter battery life - Network capacity: Less overhead = more devices per gateway - Cost: Less airtime = lower cellular/network costs

Example: Sending a 4-byte temperature reading (23.5°C) might require: - 66 bytes total with uncompressed IPv6 - 26 bytes total with 6LoWPAN compression - That’s 40 bytes saved per message!

Protocol efficiency in this lab is measured as payload ratio:

\[ \eta = \frac{B_{\text{payload}}}{B_{\text{payload}} + B_{\text{overhead}}} \]

Worked example: For a 4-byte reading (CoAP/UDP/IPv6/Ethernet stack):

  • Uncompressed stack overhead 66 bytes (14+40+8+4): \(\eta = 4/(4+66) = 5.7\%\)
  • 6LoWPAN compressed stack overhead 22 bytes (8+6+4+4): \(\eta = 4/(4+22) = 15.4\%\)

For a 32-byte batched payload on the compressed stack:

\[ \eta = \frac{32}{32+22} = 59.3\% \]

This quantifies why both compression and payload batching are key to battery life and channel capacity in constrained IoT links.

37.4 Lab 1: ESP32 Protocol Packet Analyzer

Time: ~20 min | Level: Advanced | Code: P07.C06.U01

Objective: Analyze IoT protocol packets to understand overhead and compare different protocol stacks.

37.4.1 Code

#include <WiFi.h>

// Simulated protocol headers
struct ProtocolHeaders {
  // Data Link Layer
  uint8_t mac_dst[6];      // 6 bytes
  uint8_t mac_src[6];      // 6 bytes
  uint16_t mac_type;       // 2 bytes
  // Total Ethernet: 14 bytes (without FCS)

  // Network Layer (IPv6 simplified)
  uint8_t ip_version;      // 4 bits + traffic class/flow
  uint16_t ip_payload_len; // 2 bytes
  uint8_t ip_next_header;  // 1 byte
  uint8_t ip_hop_limit;    // 1 byte
  uint8_t ip_src[16];      // 16 bytes
  uint8_t ip_dst[16];      // 16 bytes
  // Total IPv6: 40 bytes

  // Transport Layer (UDP)
  uint16_t udp_src_port;   // 2 bytes
  uint16_t udp_dst_port;   // 2 bytes
  uint16_t udp_length;     // 2 bytes
  uint16_t udp_checksum;   // 2 bytes
  // Total UDP: 8 bytes

  // Application Layer (CoAP minimal)
  uint8_t coap_version_type_tkl;  // 1 byte
  uint8_t coap_code;              // 1 byte
  uint16_t coap_message_id;       // 2 bytes
  // Total CoAP: 4 bytes minimum

  // Payload
  uint8_t payload[4];     // 4 bytes actual data
};

void setup() {
  Serial.begin(115200);
  delay(2000);

  Serial.println("\n╔════════════════════════════════════════╗");
  Serial.println("║  IoT Protocol Packet Analyzer          ║");
  Serial.println("║  ESP32 Protocol Overhead Inspector     ║");
  Serial.println("╚════════════════════════════════════════╝\n");

  // Analyze different protocol stacks
  analyzeProtocolStacks();

  // Demonstrate 6LoWPAN compression benefit
  demonstrate6LoWPANCompression();

  // Show payload efficiency
  analyzePayloadEfficiency();
}

void loop() {
  // Analysis runs once
}

void analyzeProtocolStacks() {
  Serial.println("═══════════════════════════════════════════════════");
  Serial.println("PROTOCOL STACK OVERHEAD ANALYSIS (4-byte payload)");
  Serial.println("═══════════════════════════════════════════════════\n");

  // Stack 1: CoAP/UDP/IPv6/Ethernet (uncompressed)
  printStackAnalysis(
    "CoAP/UDP/IPv6/Ethernet",
    14,  // Ethernet
    40,  // IPv6
    8,   // UDP
    4,   // CoAP
    4    // Payload
  );

  // Stack 2: CoAP/UDP/IPv6/802.15.4 with 6LoWPAN
  printStackAnalysis(
    "CoAP/UDP/IPv6/802.15.4 (6LoWPAN)",
    8,   // 802.15.4 compressed
    6,   // IPv6 compressed
    4,   // UDP compressed
    4,   // CoAP
    4    // Payload
  );

  // Stack 3: MQTT/TCP/IPv6/Ethernet
  printStackAnalysis(
    "MQTT/TCP/IPv6/Ethernet",
    14,  // Ethernet
    40,  // IPv6
    20,  // TCP minimum
    2,   // MQTT minimum
    4    // Payload
  );

  // Stack 4: HTTP/TCP/IPv4/Ethernet
  printStackAnalysis(
    "HTTP/TCP/IPv4/Ethernet",
    14,  // Ethernet
    20,  // IPv4
    20,  // TCP
    50,  // HTTP minimum
    4    // Payload
  );
}

void printStackAnalysis(const char* name, int datalink, int network,
                       int transport, int application, int payload) {
  int total_overhead = datalink + network + transport + application;
  int total_packet = total_overhead + payload;
  float efficiency = (float)payload / total_packet * 100.0;

  Serial.println("─────────────────────────────────────────────────");
  Serial.printf("Stack: %s\n", name);
  Serial.println("─────────────────────────────────────────────────");
  Serial.printf("Data Link:    %3d bytes\n", datalink);
  Serial.printf("Network:      %3d bytes\n", network);
  Serial.printf("Transport:    %3d bytes\n", transport);
  Serial.printf("Application:  %3d bytes\n", application);
  Serial.println("                ─────────");
  Serial.printf("Total Overhead: %3d bytes\n", total_overhead);
  Serial.printf("Payload:        %3d bytes\n", payload);
  Serial.println("                ═════════");
  Serial.printf("TOTAL PACKET:   %3d bytes\n\n", total_packet);

  Serial.printf("Payload Efficiency: %.2f%%\n", efficiency);
  Serial.printf("Overhead Ratio: %.2f× payload\n\n", (float)total_overhead/payload);
}

void demonstrate6LoWPANCompression() {
  Serial.println("\n═══════════════════════════════════════════════════");
  Serial.println("6LoWPAN COMPRESSION BENEFIT");
  Serial.println("═══════════════════════════════════════════════════\n");

  Serial.println("IPv6 Header Compression:");
  Serial.println("  Uncompressed IPv6: 40 bytes");
  Serial.println("    - Version (4 bits)");
  Serial.println("    - Traffic Class (8 bits)");
  Serial.println("    - Flow Label (20 bits)");
  Serial.println("    - Payload Length (16 bits)");
  Serial.println("    - Next Header (8 bits)");
  Serial.println("    - Hop Limit (8 bits)");
  Serial.println("    - Source Address (128 bits = 16 bytes)");
  Serial.println("    - Destination Address (128 bits = 16 bytes)");
  Serial.println();

  Serial.println("  6LoWPAN Compressed: 6 bytes (85% reduction!)");
  Serial.println("    - Context-based compression");
  Serial.println("    - Link-local addresses derived from MAC");
  Serial.println("    - Omit hop limit (use default)");
  Serial.println("    - Omit flow label (not needed)");
  Serial.println();

  Serial.println("Total Savings:");
  Serial.println("  Before: 40 + 25 = 65 bytes (IPv6 + 802.15.4)");
  Serial.println("  After:   6 +  8 = 14 bytes (compressed)");
  Serial.println("  Savings: 51 bytes = 78% reduction");
  Serial.println();
}

void analyzePayloadEfficiency() {
  Serial.println("═══════════════════════════════════════════════════");
  Serial.println("PAYLOAD SIZE IMPACT ON EFFICIENCY");
  Serial.println("═══════════════════════════════════════════════════\n");

  Serial.println("CoAP/UDP/IPv6/802.15.4 (6LoWPAN compressed):");
  Serial.println("Fixed overhead: 22 bytes\n");

  Serial.println("Payload   Total Packet   Efficiency");
  Serial.println("(bytes)   (bytes)        (%)");
  Serial.println("──────────────────────────────────");

  int overhead = 22;
  int payloads[] = {4, 8, 16, 32, 64, 105};  // 105 = max for 127-byte packet

  for (int i = 0; i < 6; i++) {
    int payload = payloads[i];
    int total = overhead + payload;
    float efficiency = (float)payload / total * 100.0;

    char line[50];
    sprintf(line, "%4d      %4d           %.1f%%", payload, total, efficiency);
    Serial.println(line);
  }

  Serial.println("\n✓ Key Insight: Larger payloads dramatically improve efficiency!");
  Serial.println("  Aggregate multiple sensor readings when possible.");
}

Objective: Run the protocol packet analyzer in a Wokwi simulator to see how different IoT protocol stacks (CoAP/UDP/IPv6, MQTT/TCP/IPv6, HTTP/TCP/IPv4) compare in overhead, and why 6LoWPAN compression is critical for constrained 802.15.4 networks.

Copy the Lab 1 code above into the Wokwi editor and click Play. The serial monitor will display the complete overhead analysis for all four protocol stacks, 6LoWPAN compression benefits, and payload efficiency tables.

What to Observe:

  1. CoAP/UDP/IPv6 efficiency is only 5.71% for a 4-byte payload (66 bytes of headers for 4 bytes of data) – this is why payload aggregation matters
  2. 6LoWPAN compression reduces IPv6+802.15.4 overhead from 65 bytes to 14 bytes (78% reduction), making IPv6 feasible on tiny radios
  3. MQTT/TCP vs CoAP/UDP: MQTT/TCP adds 20 bytes of TCP overhead that CoAP/UDP avoids, but MQTT’s broker-based pub/sub is better for fan-out scenarios
  4. Payload size impact: Efficiency jumps from 15.4% (4 bytes) to 82.7% (105 bytes) with the same 22-byte compressed header – always batch sensor readings when possible

37.4.2 Expected Serial Output

╔════════════════════════════════════════╗
║  IoT Protocol Packet Analyzer          ║
║  ESP32 Protocol Overhead Inspector     ║
╚════════════════════════════════════════╝

═══════════════════════════════════════════════════
PROTOCOL STACK OVERHEAD ANALYSIS (4-byte payload)
═══════════════════════════════════════════════════

─────────────────────────────────────────────────
Stack: CoAP/UDP/IPv6/Ethernet
─────────────────────────────────────────────────
Data Link:     14 bytes
Network:       40 bytes
Transport:      8 bytes
Application:    4 bytes
                ─────────
Total Overhead:  66 bytes
Payload:         4 bytes
                ═════════
TOTAL PACKET:   70 bytes

Payload Efficiency: 5.71%
Overhead Ratio: 16.50× payload

[... similar for other stacks ...]

═══════════════════════════════════════════════════
6LoWPAN COMPRESSION BENEFIT
═══════════════════════════════════════════════════

IPv6 Header Compression:
  Uncompressed IPv6: 40 bytes
    - Version (4 bits)
    - Traffic Class (8 bits)
    - Flow Label (20 bits)
    - Payload Length (16 bits)
    - Next Header (8 bits)
    - Hop Limit (8 bits)
    - Source Address (128 bits = 16 bytes)
    - Destination Address (128 bits = 16 bytes)

  6LoWPAN Compressed: 6 bytes (85% reduction!)
    - Context-based compression
    - Link-local addresses derived from MAC
    - Omit hop limit (use default)
    - Omit flow label (not needed)

Total Savings:
  Before: 40 + 25 = 65 bytes (IPv6 + 802.15.4)
  After:   6 +  8 = 14 bytes (compressed)
  Savings: 51 bytes = 78% reduction

═══════════════════════════════════════════════════
PAYLOAD SIZE IMPACT ON EFFICIENCY
═══════════════════════════════════════════════════

CoAP/UDP/IPv6/802.15.4 (6LoWPAN compressed):
Fixed overhead: 22 bytes

Payload   Total Packet   Efficiency
(bytes)   (bytes)        (%)
──────────────────────────────────
   4        26           15.4%
   8        30           26.7%
  16        38           42.1%
  32        54           59.3%
  64        86           74.4%
 105       127           82.7%

✓ Key Insight: Larger payloads dramatically improve efficiency!
  Aggregate multiple sensor readings when possible.

37.4.3 Lab Analysis

Key Observations from Lab 1
  1. 6LoWPAN compression is essential: Reduces IPv6 overhead from 40 bytes to 6 bytes (85% reduction)

  2. Protocol stack matters more than application header: MQTT’s 2-byte header is smaller than CoAP’s 4-byte header, but MQTT requires TCP (20 bytes) vs UDP (8 bytes)

  3. Payload aggregation improves efficiency:

    • 4-byte payload: 15.4% efficiency
    • 64-byte payload: 74.4% efficiency
    • Consider batching sensor readings!
  4. HTTP is unsuitable for constrained devices: 104+ bytes of overhead for tiny payloads

Try It: Protocol Overhead Explorer

Adjust the payload size and see how efficiency changes across protocol stacks in real time.

Try It: Payload Batching Impact Calculator

Explore how batching multiple sensor readings into a single packet improves efficiency on a 6LoWPAN compressed stack (22-byte overhead).

37.5 Lab 2: Overhead Calculator Tool

Objective: Create a reusable calculator to compare protocol efficiency.

37.5.1 Python Implementation

#!/usr/bin/env python3
"""
IoT Protocol Overhead Calculator
Compare different protocol stacks for efficiency analysis
"""

# Protocol header sizes (bytes)
HEADERS = {
    # Data Link Layer
    'ethernet': 14,
    '802.15.4': 25,
    '802.15.4_compressed': 8,
    'ble': 10,
    'lorawan': 13,

    # Network Layer
    'ipv4': 20,
    'ipv6': 40,
    '6lowpan': 6,  # Compressed IPv6

    # Transport Layer
    'tcp': 20,
    'udp': 8,
    'udp_compressed': 4,  # With 6LoWPAN NHC

    # Application Layer
    'http': 50,  # Minimum
    'mqtt': 2,   # Minimum fixed header
    'coap': 4,   # Base header
    'amqp': 8,   # Frame header
}

# Common protocol stacks
STACKS = {
    'http_tcp_ipv4_eth': ['ethernet', 'ipv4', 'tcp', 'http'],
    'mqtt_tcp_ipv6_wifi': ['ethernet', 'ipv6', 'tcp', 'mqtt'],
    'mqtt_tcp_6lowpan': ['802.15.4_compressed', '6lowpan', 'tcp', 'mqtt'],
    'coap_udp_ipv6_eth': ['ethernet', 'ipv6', 'udp', 'coap'],
    'coap_udp_6lowpan': ['802.15.4_compressed', '6lowpan', 'udp_compressed', 'coap'],
    'lorawan_mac': ['lorawan'],  # LoRaWAN uses MAC-layer addressing
}

def calculate_overhead(stack_name):
    """Calculate total overhead for a protocol stack."""
    if stack_name not in STACKS:
        raise ValueError(f"Unknown stack: {stack_name}")

    stack = STACKS[stack_name]
    total = sum(HEADERS[layer] for layer in stack)
    return total, stack

def compare_stacks(payload_size):
    """Compare all stacks for a given payload size."""
    print(f"\n{'='*60}")
    print(f"PROTOCOL STACK COMPARISON (Payload: {payload_size} bytes)")
    print(f"{'='*60}\n")

    results = []
    for name in STACKS:
        overhead, layers = calculate_overhead(name)
        total = overhead + payload_size
        efficiency = (payload_size / total) * 100
        results.append((name, overhead, total, efficiency, layers))

    # Sort by efficiency (descending)
    results.sort(key=lambda x: x[3], reverse=True)

    print(f"{'Stack':<25} {'Overhead':>10} {'Total':>8} {'Efficiency':>12}")
    print("-" * 60)

    for name, overhead, total, eff, layers in results:
        print(f"{name:<25} {overhead:>10}B {total:>7}B {eff:>11.1f}%")

    # Best and worst
    best = results[0]
    worst = results[-1]
    print(f"\n✓ Best: {best[0]} ({best[3]:.1f}% efficiency)")
    print(f"✗ Worst: {worst[0]} ({worst[3]:.1f}% efficiency)")
    print(f"  Difference: {worst[2] - best[2]} bytes, {best[3]/worst[3]:.1f}x less efficient")

    return results

def battery_life_estimate(stack_name, payload_size, tx_interval_sec,
                         battery_mah=2000, tx_current_ma=20,
                         data_rate_bps=250000):
    """Estimate battery life for a protocol stack."""
    overhead, _ = calculate_overhead(stack_name)
    total_bytes = overhead + payload_size

    # Calculate transmission time per message
    tx_time_sec = (total_bytes * 8) / data_rate_bps

    # Messages per day
    messages_per_day = 86400 / tx_interval_sec

    # Daily active time
    daily_active_sec = messages_per_day * tx_time_sec

    # Daily energy consumption (mAh)
    daily_mah = (tx_current_ma * daily_active_sec) / 3600

    # Add sleep current (5 uA typical)
    sleep_mah = (0.005 * (86400 - daily_active_sec)) / 3600

    total_daily_mah = daily_mah + sleep_mah

    # Battery life in days
    battery_days = battery_mah / total_daily_mah
    battery_years = battery_days / 365

    return {
        'total_bytes': total_bytes,
        'tx_time_ms': tx_time_sec * 1000,
        'daily_messages': messages_per_day,
        'daily_mah': total_daily_mah,
        'battery_days': battery_days,
        'battery_years': battery_years
    }

# Example usage
if __name__ == "__main__":
    # Compare stacks for different payload sizes
    for payload in [4, 16, 64]:
        compare_stacks(payload)

    # Battery life comparison
    print(f"\n{'='*60}")
    print("BATTERY LIFE COMPARISON (10-minute intervals, 4-byte payload)")
    print(f"{'='*60}\n")

    stacks_to_compare = ['coap_udp_6lowpan', 'mqtt_tcp_6lowpan', 'http_tcp_ipv4_eth']

    for stack in stacks_to_compare:
        result = battery_life_estimate(stack, 4, 600)  # 10 minutes
        print(f"{stack}:")
        print(f"  Packet: {result['total_bytes']} bytes, TX time: {result['tx_time_ms']:.2f}ms")
        print(f"  Daily energy: {result['daily_mah']:.4f} mAh")
        print(f"  Battery life: {result['battery_years']:.1f} years\n")

37.5.2 Expected Output

============================================================
PROTOCOL STACK COMPARISON (Payload: 4 bytes)
============================================================

Stack                        Overhead    Total   Efficiency
------------------------------------------------------------
lorawan_mac                       13B      17B        23.5%
coap_udp_6lowpan                  22B      26B        15.4%
mqtt_tcp_6lowpan                  36B      40B        10.0%
coap_udp_ipv6_eth                 66B      70B         5.7%
mqtt_tcp_ipv6_wifi                76B      80B         5.0%
http_tcp_ipv4_eth                104B     108B         3.7%

✓ Best: lorawan_mac (23.5% efficiency)
✗ Worst: http_tcp_ipv4_eth (3.7% efficiency)
  Difference: 91 bytes, 6.4x less efficient

============================================================
BATTERY LIFE COMPARISON (10-minute intervals, 4-byte payload)
============================================================

coap_udp_6lowpan:
  Packet: 26 bytes, TX time: 0.83ms
  Daily energy: 0.1207 mAh
  Battery life: 45.4 years

mqtt_tcp_6lowpan:
  Packet: 40 bytes, TX time: 1.28ms
  Daily energy: 0.1210 mAh
  Battery life: 45.3 years

http_tcp_ipv4_eth:
  Packet: 108 bytes, TX time: 3.46ms
  Daily energy: 0.1228 mAh
  Battery life: 44.6 years

37.6 Lab Extension: Real-Time Packet Analysis

For real protocol analysis, use Wireshark with these filters:

CoAP Traffic:

coap && ip.dst == 192.168.1.100

MQTT Traffic:

mqtt && tcp.port == 1883

6LoWPAN over 802.15.4:

wpan && 6lowpan

Key Fields to Analyze:

  • Frame length (total bytes on wire)
  • Protocol header sizes at each layer
  • Payload extraction and efficiency calculation

Evaluate your network characteristics against this framework to determine if 6LoWPAN is essential, beneficial, or unnecessary:

Network Layer MTU Size Device RAM 6LoWPAN Decision Rationale
IEEE 802.15.4 127 bytes < 64 KB Essential Without compression, 40-byte IPv6 + 8-byte UDP leaves only 79 bytes for application data. With compression (6 + 4 bytes), you get 117 bytes—a 48% increase
Bluetooth LE 27-251 bytes < 256 KB Highly recommended BLE 4.x has 27-byte MTU; BLE 5.x supports up to 251 bytes but many devices still use 27. Compression critical for smaller MTUs
Thread 127 bytes < 256 KB Essential Thread IS based on 6LoWPAN by design. Using Thread without 6LoWPAN violates the specification
Wi-Fi 1500 bytes > 1 MB Not needed 40-byte IPv6 header is only 2.7% of 1500-byte MTU. Compression overhead exceeds benefits
Ethernet 1500 bytes > 1 MB Not needed Same as Wi-Fi. Standard IPv6 works fine
NB-IoT / LTE-M 1358 bytes > 512 KB Not needed Cellular uses RoHC (Robust Header Compression) at cellular layer instead. 6LoWPAN adds unnecessary processing
LoRaWAN 51-242 bytes < 256 KB N/A LoRaWAN uses MAC-layer addressing without IP stack. 6LoWPAN doesn’t apply

Additional factors to consider:

✓ Use 6LoWPAN when:

✗ Avoid 6LoWPAN when:

Example calculation for 802.15.4:

Without 6LoWPAN (4-byte sensor reading):

Frame: 127 bytes total
- MAC header: 25 bytes
- IPv6 header: 40 bytes
- UDP header: 8 bytes
- CoAP header: 4 bytes
- Payload: 4 bytes
- Security (AES): 16 bytes
- FCS: 2 bytes
Total overhead: 95 bytes
Available payload: 32 bytes maximum
Efficiency: 4/127 = 3.1%

With 6LoWPAN (same 4-byte reading):

Frame: 127 bytes total
- MAC header: 25 bytes (unchanged)
- 6LoWPAN IPHC: 2 bytes (compressed IPv6)
- NHC UDP: 4 bytes (compressed UDP)
- CoAP header: 4 bytes (unchanged)
- Payload: 4 bytes
- Security (AES): 16 bytes (unchanged)
- FCS: 2 bytes (unchanged)
Total overhead: 53 bytes
Available payload: 74 bytes maximum
Efficiency: 4/127 = 3.1% (same for tiny payload)
BUT maximum payload increased from 32 → 74 bytes (+130%)

Key insight: 6LoWPAN’s value isn’t always in improving efficiency for tiny payloads—it’s in increasing maximum usable payload. For an 802.15.4 network, 6LoWPAN enables sending 74-byte application messages instead of being capped at 32 bytes. This allows payload batching, reducing transmission frequency by 2.3×, which directly extends battery life by the same factor.

Implementation note: Most 6LoWPAN stacks require 16-32 KB RAM for the compression context and fragmentation/reassembly buffers. If your MCU has only 8 KB RAM, 6LoWPAN may not fit. :::

Common Pitfalls

Reading notes about a lab is not the same as redoing the critical steps. Fix: re-run the broker startup, publish, and subscribe sequence to confirm understanding before the assessment.

Students review each lab in isolation and miss cross-protocol patterns. Fix: create a comparison table listing measured latency, overhead, and packet loss for each protocol lab.

“It worked in the end” without understanding the error messages means the same errors will reappear in the assessment. Fix: document every error encountered and its solution in the lab review notes.

37.7 Summary

Key Takeaways from Labs

ESP32 Packet Analyzer (Lab 1):

  • Demonstrated header sizes for common protocol stacks
  • 6LoWPAN compression: 40-byte IPv6 header to 6 bytes (85% reduction)
  • Protocol efficiency varies from 3.7% (HTTP) to 82.7% (max CoAP payload)

Overhead Calculator (Lab 2):

  • LoRaWAN most efficient for small payloads (23.5% at 4 bytes)
  • CoAP/UDP/6LoWPAN best for IP-based constrained networks
  • HTTP unsuitable for battery-powered IoT devices

Battery Life Impact:

  • At low TX frequencies (e.g., every 10 min), sleep current dominates and protocol choice has minimal impact
  • At high TX frequencies (e.g., every 10 sec), protocol overhead becomes significant — use CoAP/UDP over MQTT/TCP
  • Aggregate payloads when possible to improve efficiency

Optimization Strategies:

  1. Use 6LoWPAN for 802.15.4 networks (mandatory for efficiency)
  2. Prefer UDP over TCP for constrained devices
  3. Batch sensor readings to maximize payload efficiency
  4. Consider LoRaWAN MAC-layer for LPWAN (no IP overhead)

37.8 Knowledge Check

37.9 Concept Relationships

Builds Upon:

Enables:

Related Concepts:

  • 6LoWPAN compression reduces IPv6 overhead by 85%
  • Payload efficiency improves dramatically with larger payloads (15.4% at 4 bytes → 82.7% at 105 bytes)
  • Battery life calculations require analyzing transmission energy, sleep current, and protocol overhead – sleep current often dominates at low TX frequencies

37.10 See Also

Protocol Deep Dives:

Practical Tools:

37.11 What’s Next

If you want to… Read this
Attempt the module assessment Protocol Assessment
Review protocol concepts Protocol Overview
Revisit the CoAP and MQTT lab CoAP and MQTT Lab
Revisit the Python implementations lab Python Implementations Lab