Networking & Connectivity

Wireless Technologies for IoT

Compare WiFi, Bluetooth LE, Zigbee, Z-Wave, LoRa, NB-IoT, and 5G — understand the trade-offs of range, power, bandwidth, and cost for your IoT application.

Wireless Technologies for IoT

No single wireless technology fits every IoT use case. Choosing the wrong one can mean poor battery life, insufficient range, or an overcomplicated system. This topic gives you a deep enough understanding to make the right call.


The Trade-off Triangle

Every wireless technology balances three competing factors:

           RANGE
            /\
           /  \
          /    \
         /      \
     LoRa        5G
       /            \
      /   Zigbee     \
     /   BLE  WiFi   \
    /________________\
  POWER            DATA RATE

  You can maximize at most two of the three.

WiFi — High Speed, Short Range

WiFi is the fastest and most familiar wireless technology. It's excellent when your device is near a router and mains-powered.

python
# MicroPython ESP32 — WiFi connection with retry
import network
import time

def connect_wifi(ssid, password, retries=5, delay=2):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    if wlan.isconnected():
        return wlan.ifconfig()

    print(f"Connecting to '{ssid}'...")
    wlan.connect(ssid, password)

    for attempt in range(retries):
        if wlan.isconnected():
            ip, subnet, gateway, dns = wlan.ifconfig()
            rssi = wlan.status('rssi')  # Signal strength (dBm)
            print(f"Connected! IP: {ip}  RSSI: {rssi} dBm")
            return wlan.ifconfig()
        print(f"  Attempt {attempt + 1}/{retries}...")
        time.sleep(delay)

    raise RuntimeError(f"Failed to connect to '{ssid}' after {retries} attempts")

# WiFi in Access Point mode — ESP32 as hotspot
def start_ap(ssid="ESP32-Config", password="setup1234"):
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=ssid, password=password, authmode=3)  # WPA2
    print(f"AP active: {ssid}")
    print(f"AP IP: {ap.ifconfig()[0]}")

config = connect_wifi("MyHome", "MyPassword")
print(f"Network config: {config}")
FeatureWiFi 4 (n)WiFi 5 (ac)WiFi 6 (ax)
Frequency2.4/5 GHz5 GHz2.4/5/6 GHz
Max speed600 Mbps3.5 Gbps9.6 Gbps
Range (indoor)~50 m~35 m~50 m
PowerMediumMediumMedium
IoT standardCommonCommonESP32-C6

Bluetooth Low Energy (BLE)

BLE is optimized for short bursts of data from sensors — a heart rate monitor, a temperature beacon, or a lock.

python
# MicroPython ESP32 — BLE beacon (advertise sensor data)
import bluetooth
import struct
import time
from micropython import const

_ADV_TYPE_FLAGS      = const(0x01)
_ADV_TYPE_COMPLETE   = const(0x09)  # Complete local name
_ADV_TYPE_MANUF_DATA = const(0xFF)  # Manufacturer specific

def encode_advertisement(temperature, humidity):
    """Pack sensor data into BLE advertisement payload."""
    # Manufacturer specific data: 2-byte company ID + 4 bytes data
    COMPANY_ID = 0xFFFF  # Test/internal use
    temp_int = int(temperature * 100)  # 24.5 → 2450
    hum_int  = int(humidity * 100)     # 61.2 → 6120

    manuf_data = struct.pack("<HHH", COMPANY_ID, temp_int, hum_int)

    payload = bytearray()
    # Flags
    payload += bytes([2, _ADV_TYPE_FLAGS, 0x06])
    # Name
    name = b"EnvSensor"
    payload += bytes([len(name) + 1, _ADV_TYPE_COMPLETE]) + name
    # Manufacturer data
    payload += bytes([len(manuf_data) + 1, _ADV_TYPE_MANUF_DATA]) + manuf_data

    return payload

ble = bluetooth.BLE()
ble.active(True)

temperature, humidity = 24.5, 61.2
adv = encode_advertisement(temperature, humidity)

# Advertise every 100 ms, 30-second duration
ble.gap_advertise(100_000, adv_data=adv)  # interval in µs
print(f"Advertising: T={temperature}°C H={humidity}%")
time.sleep(30)
ble.gap_advertise(None)  # Stop advertising

BLE Profiles & GATT

BLE GATT Hierarchy:
  Service (e.g. Environmental Sensing Service: 0x181A)
    └── Characteristic (e.g. Temperature: 0x2A6E)
          ├── Properties: Read, Notify
          └── Descriptor: Units (Celsius), precision

Common BLE Services:
  0x181A  Environmental Sensing (temp, humidity, pressure)
  0x180D  Heart Rate
  0x1800  Generic Access (device name)
  0x180F  Battery Service

Zigbee — Mesh Networking for Smart Homes

Zigbee creates a self-healing mesh where every device can route data for others, greatly extending range.

Zigbee network:
  Coordinator (1 per network)
      │
   ───┼──────────────────
      │         │
   Router    Router ──── End Device (light bulb)
      │         │
  End Dev   End Device
  (switch)   (sensor)

Range: 10–100 m per hop
Hops: up to 30 hops (effectively building-wide coverage)
Frequency: 2.4 GHz (global), 868 MHz (EU), 915 MHz (US)
Data rate: 250 kbps
Power: Very low — sensors run for years on 2 AA batteries

Zigbee is behind Philips Hue, IKEA TRADFRI, and many smart home ecosystems. The Matter standard (2022+) unifies Zigbee, Thread, and WiFi devices under one umbrella.


LoRa / LoRaWAN — Long Range for Remote Sensors

LoRa (Long Range) uses chirp spread spectrum modulation to achieve 2–15 km range at extremely low power.

python
# MicroPython with SX1276 LoRa module (e.g., Heltec LoRa32)
from machine import SPI, Pin
from sx127x import SX127x
import time

# LoRa radio configuration
lora = SX127x(
    spi=SPI(1, baudrate=10000000, sck=Pin(5), mosi=Pin(27), miso=Pin(19)),
    cs=Pin(18),
    reset=Pin(14),
    frequency=868E6,    # 868 MHz (Europe) or 915E6 (US)
    spreading_factor=7, # SF7 = shorter range + faster; SF12 = max range
    bandwidth=125E3,    # 125 kHz bandwidth
    coding_rate=5       # 4/5 coding rate
)

def send_lora_packet(temperature, humidity, battery_pct):
    """Encode compact binary payload to minimize airtime."""
    import struct
    payload = struct.pack("!hhB",
        int(temperature * 100),  # 2 bytes, -327.68 to 327.67 °C
        int(humidity * 100),     # 2 bytes, 0 to 100.00 %
        battery_pct              # 1 byte, 0–100 %
    )
    lora.println(payload)
    print(f"LoRa sent: {len(payload)} bytes")

# LoRaWAN has duty cycle limits (1% in EU)
# At SF7/BW125: 25 ms airtime → max 36 packets/hour
# At SF12/BW125: 1.8 s airtime → max 2 packets/hour
send_lora_packet(24.5, 61, 87)
time.sleep(60)  # Respect duty cycle!

LoRa vs LoRaWAN

FeatureLoRaLoRaWAN
LayerPhysical (radio)Network + application layers
AddressingPoint-to-pointDevice EUI, network server
InfrastructureYour own gatewayPublic (TTN) or private
SecurityNone built-inAES-128 encryption
Use casePrivate networksWide area deployment

The Things Network (TTN) provides free LoRaWAN infrastructure in 175+ countries.


NB-IoT / LTE-M — Cellular IoT

Cellular IoT modules use licensed spectrum for guaranteed coverage anywhere mobile networks exist.

FeatureNB-IoTLTE-M
Bandwidth200 kHz1.4 MHz
Data rate250 kbps DL1 Mbps DL
Latency1.5–10 s10–15 ms
MobilityNo (stationary)Yes (vehicles)
PowerUltra-lowLow
RangeIndoor penetrationWide area
Best forSmart meters, sensorsVehicle tracking
python
# MicroPython — SIM7600 cellular module (AT commands via UART)
from machine import UART
import time

gsm = UART(2, baudrate=115200, tx=17, rx=16)

def at(cmd, wait=1):
    """Send AT command and return response."""
    gsm.write((cmd + '\r\n').encode())
    time.sleep(wait)
    resp = b''
    while gsm.any():
        resp += gsm.read()
    return resp.decode(errors='ignore').strip()

# Check module
print(at("AT"))           # OK
print(at("AT+CGSN"))     # IMEI number
print(at("AT+CSQ"))      # Signal quality (0-31, higher = stronger)
print(at("AT+COPS?"))    # Current carrier
print(at("AT+CEREG?"))   # Network registration status

# Send HTTP GET (simplified)
at("AT+HTTPINIT")
at('AT+HTTPPARA="URL","https://api.example.com/data"')
at("AT+HTTPACTION=0", wait=5)  # GET request
response = at("AT+HTTPREAD")
at("AT+HTTPTERM")
print(response)

Wireless Technology Selection Guide

RequirementRecommended Technology
Indoor, near router, mains powerWiFi
Wearable, mobile phone pairingBluetooth LE
Smart home mesh (hundreds of nodes)Zigbee / Matter
Building-wide sensor networkZigbee or 868 MHz LoRa
Rural sensor, no infrastructureLoRa point-to-point
Nationwide coverage, no WiFiNB-IoT or LTE-M
Vehicle trackingLTE-M or 4G with GPS
Sub-GHz home automationZ-Wave (868/908 MHz)
Ultra-low power beaconBLE (advertising only)

Summary

  • WiFi is fast and familiar but power-hungry — best for mains-powered devices near a router
  • BLE is ideal for wearables, beacons, and phone-paired sensors; very low power
  • Zigbee creates self-healing mesh networks, used extensively in smart home products
  • LoRa achieves 2–15 km range at the cost of very low data rates — ideal for remote agriculture and smart city sensors
  • NB-IoT/LTE-M uses cellular networks for guaranteed coverage without any local infrastructure
  • Always check duty cycle regulations (EU: 1%, US: less restricted) before deploying LoRa

Next, we'll do a deep dive into MQTT — the protocol that powers the majority of IoT deployments.