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.
# 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}")| Feature | WiFi 4 (n) | WiFi 5 (ac) | WiFi 6 (ax) |
|---|---|---|---|
| Frequency | 2.4/5 GHz | 5 GHz | 2.4/5/6 GHz |
| Max speed | 600 Mbps | 3.5 Gbps | 9.6 Gbps |
| Range (indoor) | ~50 m | ~35 m | ~50 m |
| Power | Medium | Medium | Medium |
| IoT standard | Common | Common | ESP32-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.
# 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 advertisingBLE 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 ServiceZigbee — 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 batteriesZigbee 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.
# 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
| Feature | LoRa | LoRaWAN |
|---|---|---|
| Layer | Physical (radio) | Network + application layers |
| Addressing | Point-to-point | Device EUI, network server |
| Infrastructure | Your own gateway | Public (TTN) or private |
| Security | None built-in | AES-128 encryption |
| Use case | Private networks | Wide 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.
| Feature | NB-IoT | LTE-M |
|---|---|---|
| Bandwidth | 200 kHz | 1.4 MHz |
| Data rate | 250 kbps DL | 1 Mbps DL |
| Latency | 1.5–10 s | 10–15 ms |
| Mobility | No (stationary) | Yes (vehicles) |
| Power | Ultra-low | Low |
| Range | Indoor penetration | Wide area |
| Best for | Smart meters, sensors | Vehicle tracking |
# 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
| Requirement | Recommended Technology |
|---|---|
| Indoor, near router, mains power | WiFi |
| Wearable, mobile phone pairing | Bluetooth LE |
| Smart home mesh (hundreds of nodes) | Zigbee / Matter |
| Building-wide sensor network | Zigbee or 868 MHz LoRa |
| Rural sensor, no infrastructure | LoRa point-to-point |
| Nationwide coverage, no WiFi | NB-IoT or LTE-M |
| Vehicle tracking | LTE-M or 4G with GPS |
| Sub-GHz home automation | Z-Wave (868/908 MHz) |
| Ultra-low power beacon | BLE (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.