5  Networking Basics: MAC

Key Concepts
  • MAC Protocol: A set of rules governing how devices share a common communication medium and avoid or resolve access conflicts
  • Contention-Based MAC: Devices compete for channel access without coordination; efficient at low loads but degrades under high traffic (CSMA/CA, ALOHA)
  • Scheduled MAC (TDMA): The channel is divided into time slots assigned to specific devices; collision-free but requires synchronisation
  • TSCH (Time-Slotted Channel Hopping): A MAC protocol combining TDMA slots with channel hopping; used in IEEE 802.15.4e for industrial IoT
  • Beacon: A periodic broadcast from a network coordinator synchronising device clocks and announcing network parameters
  • GTS (Guaranteed Time Slot): A reserved slot in IEEE 802.15.4 beacon-enabled mode for collision-free transmission of time-critical data
  • CCA (Clear Channel Assessment): A check that a device performs before transmitting to verify the channel is unoccupied

5.1 In 60 Seconds

Medium Access Control (MAC) protocols determine how IoT devices share a wireless channel without collisions. The three main categories are contention-based (CSMA/CA in Wi-Fi – devices listen before transmitting), contention-free (TDMA – devices get assigned time slots), and hybrid approaches. The choice directly impacts battery life, latency, and scalability of IoT deployments.

Previous: ← Introduction

Next: Hands-On Labs →


5.2 Learning Objectives

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

  • Classify MAC protocols into contention-based, contention-free, and hybrid categories
  • Compare CSMA/CA, TDMA, and ALOHA trade-offs in power consumption, latency, and scalability
  • Select the appropriate MAC protocol for IoT scenarios based on traffic patterns and energy budgets
  • Configure ESP32 Wi-Fi connections and interpret RSSI signal strength values
  • Build Python network scanners to discover active IoT devices on a local network

5.3 MAC Protocol Classification

⏱️ ~10 min | ⭐⭐ Intermediate | 📋 P07.C14.U03

MAC stands for Medium Access Control. Think of it as the “traffic rules” for how devices share a network channel:

  • The Problem: Multiple devices want to send data at the same time on the same channel
  • The Solution: MAC protocols provide rules so devices can take turns without interfering
  • Real-World Analogy: Like people in a meeting raising hands to speak (polling), or taking turns in order (TDMA), or just talking when there’s silence (CSMA)

Different MAC protocols make different trade-offs between fairness, efficiency, and complexity.

“I keep trying to send my data, but another sensor transmits at the exact same time and our messages crash!” complained Sammy the Sensor. Max the Microcontroller explained, “That is a collision. You need MAC protocols – rules for sharing the channel.”

“There are three main approaches,” said Lila the LED. “First, CSMA/CA – Listen Before You Talk. Before transmitting, you check if the channel is quiet. If it is, go ahead. If not, wait. Wi-Fi uses this method. Second, TDMA – Time Slots. Everyone gets assigned a specific time to transmit, like a school schedule. No collisions possible, but you waste your time slot if you have nothing to send.”

“And third is the Hybrid approach,” added Max, “which combines both. Some devices get guaranteed time slots for critical data, while others share a pool of time for less urgent messages.”

Bella the Battery had strong opinions. “TDMA is my favorite because devices can sleep when it is not their time slot – huge energy savings! CSMA wastes energy because you have to keep listening to the channel. For a battery-powered sensor that sends data once an hour, TDMA lets me sleep 99.9% of the time!”

At the Data Link Layer, the Medium Access Control (MAC) sublayer determines how devices share access to the physical medium. For IoT, choosing the right MAC protocol directly impacts battery life, latency, and scalability.

5.3.1 MAC Protocol Taxonomy

Hierarchical tree diagram classifying MAC protocols into three branches: contention-based (ALOHA, CSMA/CA), contention-free (TDMA, FDMA, CDMA, Polling, Token), and hybrid approaches combining both strategies.
Figure 5.1: Medium Access Control Protocol Classification Tree

This variant visualizes the same MAC protocols but arranges them by their key trade-offs: Latency Predictability vs Energy Efficiency. Different IoT use cases prioritize different quadrants.

Two-axis quadrant chart plotting MAC protocols by latency predictability (horizontal) and energy efficiency (vertical). TDMA occupies the high-efficiency, high-predictability quadrant; CSMA/CA occupies the low-efficiency, low-predictability quadrant; ALOHA is high-efficiency but low-predictability; Polling/Token are high-predictability but lower-efficiency.
Figure 5.2: MAC Protocol Trade-off Quadrant - Visualizes energy efficiency vs latency predictability for different IoT scenarios

Reading the Quadrant:

  • Top-Right (Best for Battery + Real-Time): TDMA excels - scheduled slots enable deep sleep AND predictable timing
  • Bottom-Right (Battery Priority): ALOHA maximizes sleep time but has unpredictable collisions
  • Top-Left (Latency Priority): Polling/Token ensure timing but require constant coordination
  • Bottom-Left (General Purpose): CSMA/CA offers flexibility at cost of both metrics

5.3.2 MAC Protocol Performance Comparison

Protocol Throughput Latency Fairness Energy Efficiency Best For
ALOHA Low (18% max) Variable, high collisions Poor Low overhead Very simple, low traffic (LoRaWAN Class A)
CSMA/CA Medium (50-70%) Variable, backoff delays Fair Medium Wi-Fi, Zigbee, general wireless
TDMA High (90%+) Fixed, predictable Excellent Excellent (sleep in unused slots) Scheduled IoT (Bluetooth, 802.15.4)
Polling Medium Bounded, depends on cycle Excellent Medium (wait for poll) Deterministic industrial systems
CDMA High Low, simultaneous Good Medium (complex radio, no idle waste) Cellular (NB-IoT, LTE-M)
Token Passing High (90%+) Bounded, token wait Perfect Medium Industrial buses (CAN, Profibus)
Key Trade-Offs

Contention-Based (Orange):

  • ✅ Simple, scalable, no synchronization needed
  • ❌ Variable latency, collisions waste energy
  • IoT Impact: Good for bursty, unpredictable traffic (sensor alerts)

Contention-Free (Teal):

  • ✅ Predictable latency, no collisions, excellent for sleep scheduling
  • ❌ Requires synchronization, fixed overhead even when idle
  • IoT Impact: Best for battery-powered, scheduled reporting (smart meters)

Hybrid (Gray):

  • ✅ Combines benefits, adapts to traffic patterns
  • ❌ More complex implementation
  • IoT Impact: Industrial IoT with mixed traffic (time-critical + best-effort)

5.3.3 IoT MAC Protocol Selection Guide

Choosing MAC for Battery-Powered IoT

Low Traffic, Simple Devices (e.g., soil moisture sensor reporting 3x/day): - Use: ALOHA variants (LoRaWAN Class A) - Why: 99% of time sleeping, rare collisions, minimal overhead

Scheduled, Predictable Traffic (e.g., smart meter reading every 15 min): - Use: TDMA (Bluetooth, 802.15.4 beacon mode) - Why: Devices wake only for assigned slot, predictable latency

Bursty, Unpredictable Traffic (e.g., motion sensor sending alerts): - Use: CSMA/CA with aggressive sleep (Wi-Fi PSM) - Why: Flexible access, sleep when idle, listen before send reduces collisions

Real-Time, Deterministic (e.g., industrial robot control): - Use: TDMA or Polling (TSN, 802.15.4 GTS) - Why: Guaranteed latency bounds, no collisions

High Density, Interference (e.g., stadium with 10,000+ devices): - Use: CDMA or FDMA (NB-IoT, LoRa channels) - Why: Orthogonal access, simultaneous transmissions without collision

5.3.4 Protocol Selection Decision Tree

Use this decision tree to select the appropriate MAC protocol for your IoT application:

Flowchart decision tree for MAC protocol selection. Starting from root question 'Need deterministic latency?', branches guide through questions about traffic periodicity, power constraints, device density, and collision tolerance to recommend TDMA, Polling, ALOHA, CSMA/CA, or CDMA/FDMA.
Figure 5.3: Interactive decision tree for selecting the optimal MAC protocol based on IoT system requirements including power constraints, latency needs, traffic patterns, and device density.

5.3.5 Real-World Examples

Wi-Fi (CSMA/CA):

  • Listen for silence (carrier sense)
  • Wait random backoff if busy
  • Send when clear
  • Acknowledgment required
  • IoT Use: Smart home devices with AC power

Bluetooth LE (TDMA):

  • Central device assigns 1.25ms time slots
  • Peripheral transmits only in assigned slot
  • Sleep between slots
  • IoT Use: Wearables, sensors with predictable 1-second updates

LoRaWAN Class A (ALOHA):

  • Device transmits whenever it wants
  • No carrier sense (ultra-low power radio off between sends)
  • Accepts ~1% packet loss due to collisions
  • IoT Use: Agricultural sensors, asset tracking (battery life > 10 years)

CAN Bus (CSMA/CR - Collision Resolution):

  • Listen before send (like CSMA)
  • If collision, highest priority message wins
  • Losers retry immediately
  • IoT Use: Automotive, industrial control (deterministic, fault-tolerant)
Energy Impact Example

Scenario: 100 battery-powered sensors, 1 reading/hour

ALOHA:

  • Device wakes, transmits immediately, sleeps
  • Average energy: ~5 mJ/transmission
  • Collision rate: ~1% (99 devices sleeping)
  • Battery life: 5-10 years (dominant factor is sleep current)

CSMA/CA:

  • Device wakes, listens for clear channel, sends, waits for ACK
  • Average energy: ~15 mJ/transmission (3× ALOHA due to listening)
  • Collision rate: <0.1%
  • Battery life: 2-3 years (listening overhead significant)

TDMA:

  • Device wakes only at assigned slot (e.g., slot 47 of 100)
  • Average energy: ~3 mJ/transmission (no listening, no collisions)
  • Collision rate: 0%
  • Battery life: 10+ years (minimal overhead, perfect sleep scheduling)

Verdict: For ultra-low-power IoT with infrequent transmissions, TDMA or ALOHA variants dominate.

CSMA/CA backoff windows grow exponentially after collisions. The contention window starts at \(W_0\) and doubles after each failure:

\[W_i = 2^{BE_i} - 1\]

where \(BE\) (backoff exponent) increases: \(BE_i = \min(BE_{i-1} + 1, BE_{\max})\).

For IEEE 802.11 Wi-Fi with \(BE_0 = 4\) (initial window = 15 slots): - Attempt 1: \(W = 2^4 - 1 = 15\) slots - Attempt 2 (collision): \(W = 2^5 - 1 = 31\) slots - Attempt 3 (collision): \(W = 2^6 - 1 = 63\) slots - Attempt 4 (collision): \(W = 2^7 - 1 = 127\) slots - Caps at \(BE_{\max} = 10\): \(W = 2^{10} - 1 = 1023\) slots

With 9μs slot time (IEEE 802.11a/g/n/ac; 802.11b uses 20μs): \(1023 \times 9\mu s \approx 9.2 \text{ ms}\) maximum backoff.

Pure ALOHA channel utilization maxes at: \[U = G \times e^{-2G} \approx 0.184 \text{ (18.4% at optimal load)}\]

where \(G\) is offered traffic. Slotted ALOHA improves this: \[U = G \times e^{-G} \approx 0.368 \text{ (36.8% at optimal load)}\]

This is why CSMA/CA achieves 50-70% utilization – carrier sensing before transmission dramatically reduces collisions compared to blind ALOHA transmission.

Try It: MAC Protocol Channel Utilization Calculator

Objective: Simulate CSMA/CA medium access control to visualize channel contention, backoff, and collision behavior.

Paste this code into the Wokwi editor:

#include <Arduino.h>

#define NUM_DEVICES 5
#define SIMULATION_ROUNDS 20
#define SLOT_DURATION_MS 10

struct IoTDevice {
  const char* name;
  int backoffCounter;
  int backoffWindow;
  int txAttempts;
  int txSuccess;
  int collisions;
  bool wantsToSend;
  int energyUsed_uJ;  // microjoules
};

IoTDevice devices[NUM_DEVICES] = {
  {"TempSensor", 0, 4, 0, 0, 0, false, 0},
  {"HumSensor",  0, 4, 0, 0, 0, false, 0},
  {"MotionDet",  0, 4, 0, 0, 0, false, 0},
  {"DoorLock",   0, 4, 0, 0, 0, false, 0},
  {"LightCtrl",  0, 4, 0, 0, 0, false, 0}
};

bool channelBusy = false;
int totalCollisions = 0;
int totalSuccess = 0;

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

  Serial.println("==========================================");
  Serial.println("  CSMA/CA Medium Access Control Simulator");
  Serial.println("  5 IoT Devices Sharing One Channel");
  Serial.println("==========================================\n");

  // Run simulation
  for (int round = 0; round < SIMULATION_ROUNDS; round++) {
    Serial.printf("--- Slot %02d ---\n", round + 1);

    // Each device decides whether to send (30% probability)
    for (int i = 0; i < NUM_DEVICES; i++) {
      if (!devices[i].wantsToSend && random(0, 100) < 30) {
        devices[i].wantsToSend = true;
        devices[i].backoffCounter = random(0, devices[i].backoffWindow);
        Serial.printf("  [%s] New data! Backoff: %d slots\n",
          devices[i].name, devices[i].backoffCounter);
      }
    }

    // Carrier sense phase
    int readyCount = 0;
    int readyDevices[NUM_DEVICES];
    for (int i = 0; i < NUM_DEVICES; i++) {
      if (devices[i].wantsToSend) {
        if (devices[i].backoffCounter > 0) {
          devices[i].backoffCounter--;
          devices[i].energyUsed_uJ += 5;  // Listen energy
          Serial.printf("  [%s] Listening... backoff=%d\n",
            devices[i].name, devices[i].backoffCounter);
        } else {
          readyDevices[readyCount++] = i;
          devices[i].txAttempts++;
        }
      }
    }

    // Transmission phase
    if (readyCount == 0) {
      Serial.println("  Channel idle (no transmissions)\n");
    } else if (readyCount == 1) {
      // Successful transmission
      int idx = readyDevices[0];
      devices[idx].txSuccess++;
      devices[idx].wantsToSend = false;
      devices[idx].backoffWindow = 4;  // Reset window
      devices[idx].energyUsed_uJ += 50;  // TX energy
      totalSuccess++;
      Serial.printf("  [%s] TX SUCCESS! (no collision)\n\n",
        devices[idx].name);
    } else {
      // COLLISION!
      totalCollisions++;
      Serial.printf("  ** COLLISION! %d devices transmitted: ", readyCount);
      for (int j = 0; j < readyCount; j++) {
        int idx = readyDevices[j];
        devices[idx].collisions++;
        devices[idx].backoffWindow = min(64, devices[idx].backoffWindow * 2);
        devices[idx].backoffCounter = random(0, devices[idx].backoffWindow);
        devices[idx].energyUsed_uJ += 50;  // Wasted TX energy
        Serial.printf("%s ", devices[idx].name);
      }
      Serial.println("**");
      Serial.println("  [All colliders: double backoff window, retry]\n");
    }

    delay(100);
  }

  // Print statistics
  Serial.println("\n=== CSMA/CA Simulation Results ===\n");
  Serial.println("  Device       | Attempts | Success | Collisions | Energy (uJ)");
  Serial.println("  -------------|----------|---------|------------|----------");
  int totalEnergy = 0;
  for (int i = 0; i < NUM_DEVICES; i++) {
    Serial.printf("  %-13s| %8d | %7d | %10d | %10d\n",
      devices[i].name, devices[i].txAttempts, devices[i].txSuccess,
      devices[i].collisions, devices[i].energyUsed_uJ);
    totalEnergy += devices[i].energyUsed_uJ;
  }
  Serial.printf("\n  Total: %d successful, %d collisions (%.0f%% success rate)\n",
    totalSuccess, totalCollisions,
    totalSuccess > 0 ? 100.0 * totalSuccess / (totalSuccess + totalCollisions) : 0);
  Serial.printf("  Channel utilization: %.0f%%\n",
    100.0 * totalSuccess / SIMULATION_ROUNDS);
  Serial.printf("  Total energy: %d uJ (%.0f uJ wasted on collisions)\n",
    totalEnergy, totalCollisions * 50.0 * 2);

  Serial.println("\n  Compare with TDMA (no collisions):");
  Serial.printf("    TDMA energy: %d uJ (%.0f%% savings)\n",
    totalSuccess * 50, 100.0 * (totalEnergy - totalSuccess * 50) / totalEnergy);
}

void loop() {
  delay(30000);
}

What to Observe:

  1. Devices with pending data perform carrier sense (listen) before transmitting
  2. Collisions occur when two devices finish their backoff at the same slot
  3. Binary exponential backoff doubles the contention window after each collision
  4. Energy statistics show the cost of collisions vs a TDMA scheme with zero collisions

The decision tree above works well in theory. Here is how it plays out in a real 20-story office building with mixed IoT requirements:

Sensor Type Count Traffic Pattern Protocol Choice Rationale
Temperature/humidity 500 1 reading every 5 min LoRaWAN (ALOHA) Infrequent small packets; 10-year battery target; 1-2% loss acceptable
Occupancy (motion) 200 Event-driven alerts Zigbee (TDMA) Predictable wake schedule; mesh routing for floor coverage
Security cameras 50 Continuous HD video Wi-Fi (CSMA/CA) High bandwidth; AC-powered; bursty during motion events
Industrial HVAC 20 <10 ms control loop Profibus (Polling) Deterministic latency; guaranteed response time per PLC

Each device class is matched to the protocol that fits its traffic pattern and power budget. Mixing protocols in one deployment is common and often the optimal solution – the MAC layer is invisible to the application above it.

Check Your Understanding: MAC Protocol Selection

5.4 Videos

Networking Fundamentals (Part 1)
Networking Fundamentals (Part 1)
From Lesson 4 — core concepts used throughout IoT networking.
Networking Fundamentals (Part 2)
Networking Fundamentals (Part 2)
From Lesson 4 — building blocks for layered models and protocols.

5.5 Hands-On: Network Configuration

⏱️ ~15 min | ⭐⭐ Intermediate | 📋 P07.C14.U04

5.5.1 Example 1: ESP32 Wi-Fi Connection

// ESP32 Wi-Fi Setup
#include <WiFi.h>

const char* ssid = "YourNetworkName";
const char* password = "YourPassword";

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

    // Connect to Wi-Fi
    WiFi.begin(ssid, password);
    Serial.print("Connecting to Wi-Fi");

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("\nConnected!");

    // Print network information
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    Serial.print("MAC Address: ");
    Serial.println(WiFi.macAddress());

    Serial.print("Gateway: ");
    Serial.println(WiFi.gatewayIP());

    Serial.print("Subnet Mask: ");
    Serial.println(WiFi.subnetMask());

    Serial.print("DNS: ");
    Serial.println(WiFi.dnsIP());

    Serial.print("RSSI (Signal Strength): ");
    Serial.print(WiFi.RSSI());
    Serial.println(" dBm");
}

void loop() {
    // Your IoT application code here
}
Try It: Interactive ESP32 Wi-Fi Simulator

Run this code yourself! The simulator below lets you experiment with ESP32 Wi-Fi connections without any hardware. Watch the Serial Monitor to see connection status, IP address, and signal strength.

What to Try:

  1. Click the green Play button to start the simulation
  2. Watch the Serial Monitor (bottom panel) for connection output
  3. The simulated ESP32 connects to a virtual “Wokwi-GUEST” network
  4. Try modifying the code to add your own features!

Learning Activities:

  • Observe the MAC address – each ESP32 has a unique hardware identifier
  • Check the RSSI value – how strong is the simulated signal?
  • Try adding WiFi.disconnect() in the loop to test reconnection behavior
Understanding RSSI

RSSI (Received Signal Strength Indicator) measures Wi-Fi signal quality: - -30 dBm: Excellent (right next to router) - -67 dBm: Good (typical home use) - -70 dBm: Fair (edge of reliable range) - -80 dBm: Poor (frequent disconnections) - -90 dBm: Unusable

Try It: RSSI Signal Strength Interpreter

5.5.2 Example 2: Python Network Scanner

# Scan local network for IoT devices
import socket
import subprocess
import platform

def get_local_ip():
    """Get local IP address"""
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip

def ping_host(ip):
    """Check if host is alive"""
    param = '-n' if platform.system().lower() == 'windows' else '-c'
    command = ['ping', param, '1', '-W', '1', ip]
    return subprocess.call(command, stdout=subprocess.DEVNULL) == 0

def scan_network():
    """Scan local network for active devices"""
    local_ip = get_local_ip()
    print(f"Local IP: {local_ip}")

    # Extract network prefix (e.g., 192.168.1)
    network_prefix = '.'.join(local_ip.split('.')[:-1])
    print(f"Scanning {network_prefix}.0/24...")

    active_hosts = []
    for i in range(1, 255):
        ip = f"{network_prefix}.{i}"
        if ping_host(ip):
            try:
                hostname = socket.gethostbyaddr(ip)[0]
            except:
                hostname = "Unknown"
            active_hosts.append((ip, hostname))
            print(f"✓ Found: {ip} ({hostname})")

    return active_hosts

# Run scan
devices = scan_network()
print(f"\nFound {len(devices)} active devices")

5.6 Knowledge Check

5.7 Review Activities

Common Pitfalls

CSMA/CA degrades significantly above 30–40% channel utilisation. A 100-node deployment with frequent reporting can saturate the channel with retransmissions. Fix: use scheduled MAC (TDMA or TSCH) for high-density deployments with predictable traffic patterns.

A 10 ppm clock drift over 1 hour shifts timing by 36 ms. Without periodic resynchronisation, TDMA slots overlap and cause collisions. Fix: include beacon synchronisation with guard times wide enough to accommodate the expected clock drift over the maximum resynchronisation interval.

The MAC layer controls when the radio is active. A misconfigured MAC that wakes devices more often than necessary rapidly drains batteries. Fix: profile MAC-layer radio duty cycle separately from application transmit frequency to identify unexpected wakeups.

5.8 What’s Next

Having mastered MAC protocols and how devices share the wireless channel, the following chapters build on these fundamentals to explore complete networking stacks, routing strategies, and protocol-specific deployments in IoT systems.

Topic Chapter Description
Network Layer & IP Addressing Networking Basics: IP Addressing How IP addresses and subnets route packets across networks above the MAC layer
Physical Layer Fundamentals Networking Basics: Introduction Signals, modulation, and the physical foundations that MAC protocols operate on
Bluetooth LE MAC & Scheduling Bluetooth LE Connection Parameters TDMA slot scheduling in BLE connections, connection intervals, and latency tradeoffs
LoRaWAN ALOHA-Based Access LoRaWAN MAC Layer How LoRaWAN Class A/B/C devices use ALOHA variants and duty-cycle constraints
Zigbee TDMA & Superframes Zigbee MAC and PHY IEEE 802.15.4 superframe structure, guaranteed time slots, and beacon-enabled mode
Wi-Fi Power Save Mechanisms Wi-Fi Power Management How CSMA/CA interacts with PSM, TWT, and DTIM intervals to reduce IoT energy consumption