Building cellular IoT devices involves selecting a module (SIM7000 for NB-IoT, SIM7070 for LTE-M, BG96 for dual-mode), connecting it via UART to a microcontroller, configuring APN settings with AT commands, and implementing HTTP or MQTT clients for cloud communication. The key difference from smartphone development is designing for constrained bandwidth (payloads under 1KB), intermittent connectivity (10-second wake delays from PSM), and aggressive power management (sleep 99.9% of the time).
Key Concepts
AT Commands: Standardized command set for configuring and controlling cellular modems; prefixed with “AT”; examples: AT+CEREG? (registration status), AT+NSOST (NB-IoT UDP send)
PPP (Point-to-Point Protocol): Legacy method for establishing IP connectivity through cellular modem via serial port; being replaced by ECM/NCM USB Ethernet emulation
ECM/NCM (Ethernet Control Model/Network Control Model): USB device classes emulating Ethernet interface over cellular modem; provides standard Linux network interface (eth0/usb0)
MQTT-SN (MQTT for Sensor Networks): MQTT adaptation for constrained networks; uses UDP transport; supports sleeping clients with broker-buffered messages for NB-IoT
CoAP (Constrained Application Protocol): UDP-based REST protocol optimized for M2M; confirmable messages provide reliability; used with DTLS for security on NB-IoT/LTE-M
LwM2M (Lightweight M2M): OMA standard device management protocol for cellular IoT; runs over CoAP/DTLS; provides firmware update, device management, and resource model
Quectel/SIMCom Modules: Popular cellular IoT module manufacturers; modules like Quectel BC660K (NB-IoT), BG96 (LTE-M+NB-IoT+GPS), EC21 (LTE Cat-1) expose AT command interface
Modem Firmware Update: Critical maintenance operation updating modem baseband firmware; requires specific tooling (Quectel QFlash, Sierra AT+WDSD), can brick device if interrupted
23.1 Learning Objectives
By the end of this chapter, you will be able to:
Justify Module Selection: Evaluate LTE-M, NB-IoT, and 4G module trade-offs and defend a selection for specific IoT application requirements
Assemble Hardware Connections: Wire SIM7000/SIM7600 modules to Arduino and ESP32 platforms with correct power supply, UART, and antenna configurations
Construct AT Command Sequences: Compose AT command flows for network registration, APN configuration, and data transmission over cellular links
Implement HTTP/MQTT Clients: Build cellular-connected applications that publish sensor data to cloud services and subscribe to command topics
Optimize Data Plans: Configure APN settings and calculate monthly data costs based on payload size, reporting frequency, and carrier pricing models
Diagnose Connectivity Failures: Systematically isolate power, serial, SIM, signal, and network registration faults using AT diagnostic commands
Quizzes Hub - Test your cellular IoT implementation knowledge
23.2 Prerequisites
Before diving into this chapter, you should be familiar with:
Cellular IoT Fundamentals: Understanding of NB-IoT, LTE-M technologies, their specifications, and when to use each cellular technology is essential for module selection and configuration
IoT Protocols Fundamentals: Knowledge of the IoT protocol stack, UDP vs TCP transport layers, and application protocols helps you understand how cellular modules fit into the overall architecture
Networking Basics: Familiarity with IP addressing, DNS, network routing, and basic networking concepts is needed to configure APNs and troubleshoot connectivity issues
For Beginners: Cellular IoT Made Simple
Cellular IoT lets your devices connect to the internet anywhere there’s cell coverage—just like your phone. This chapter teaches you how to actually build with cellular modules.
What You Need:
Cellular Module: A small board with a radio (like SIM7000)
SIM Card: Just like in your phone (get an IoT data plan)
Microcontroller: Arduino, ESP32, or Raspberry Pi
Antenna: Usually included with the module
Power Supply: Cellular modules need more power than Wi-Fi
The Basic Connection:
Microcontroller → Serial UART → Cellular Module → Antenna → Cell Tower → Internet
Why Cellular for IoT?
Works anywhere with cell coverage (no Wi-Fi needed)
Low power modes (NB-IoT, LTE-M)
Secure and reliable
Pay-per-device data plans (~$2-10/month)
Sensor Squad: Building with Cellular Modules!
“Today we are actually building something!” Sammy the Sensor said eagerly. “To connect me to a cell tower, you need a cellular module – a little board with a radio and a SIM card slot. You wire it to a microcontroller, type in some AT commands, and suddenly I can send my data to the cloud from anywhere with cell coverage!”
“AT commands are like texting instructions to the module,” Lila the LED explained. “You type ‘AT+CGATT=1’ to attach to the network, ‘AT+CIPSTART’ to open a connection, and ‘AT+CIPSEND’ to send data. It sounds complicated, but it is really just a conversation between the microcontroller and the cellular radio – ask a question, get an answer!”
Max the Microcontroller grinned. “I handle all the tricky parts – like configuring the APN (that is the gateway name your carrier uses), managing the serial connection to the module, and handling retries when the signal is weak. The key difference from phone development is that we send tiny packets – maybe 50 to 100 bytes – and then go right back to sleep.”
“Power management is everything,” Bella the Battery emphasized. “Cellular radios are hungry – they can draw 200 milliamps during transmission! But the secret is that we only transmit for a few seconds, then sleep for minutes or hours. With PSM enabled, the device sleeps at just 5 microamps. That is the difference between lasting two weeks and lasting ten years!”
23.3 Understanding Check: Asset Tracking with NB-IoT
⏱️ ~15 min | ⭐⭐⭐ Advanced | 📋 P09.C19.U01
Scenario: You’re tracking 500 shipping containers across North America. Each container reports GPS location + temperature every 30 minutes. You need 10-year battery life on 2× D-cell batteries (19,000 mAh @ 3.6V). Containers travel through rural areas with spotty coverage. Budget: $50K for 500 devices (hardware + 5-year connectivity).
Think about:
Should you use NB-IoT or LTE-M modules? Why?
How do you achieve 10-year battery life when cellular transmission consumes 200mA for 2 seconds?
Key Insight: Use NB-IoT modules (e.g., SIM7020 at $15 each) with Power Saving Mode (PSM) and extended DRX. NB-IoT’s superior coverage (164 dB MCL vs 156 dB for LTE-M) ensures connectivity in rural areas and inside metal containers. LTE-M would offer mobility handoff but drain battery 3× faster for this stationary use case.
Power calculation: Each transmission cycle (wake → connect → send 100 bytes → PSM) consumes ~400 mWh. At 48 transmissions/day × 365 days × 10 years = 175,200 transmissions. Total energy: 70 Wh. Two D-cells provide 68 Wh (19Ah × 3.6V) × 85% efficiency ≈ 58 Wh—close but achievable with careful firmware optimization and reducing retries.
Cost: 500 modules × $15 = $7,500 + SIM cards ($5 each) = $10,000 hardware. Connectivity: NB-IoT data plan at $2/month × 500 devices × 60 months = $60,000 (exceeds budget—negotiate bulk discount to $1.20/month = $36K total, or use annual prepaid plans).
Verify Your Understanding:
Why would LTE-M’s mobility features actually waste battery for stationary containers?
How does PSM differ from eDRX for power savings?
Cross-Hub Connections
Hands-On Practice:
Simulations Hub - Try the Power Budget Calculator to verify 10-year battery life calculations
Videos Hub - Watch cellular module setup tutorials and AT command demonstrations
Self-Assessment:
Quizzes Hub - Test your understanding of module selection, AT commands, and power optimization
Knowledge Reinforcement:
Knowledge Gaps Hub - Clarify common misconceptions about cellular IoT power consumption and connectivity costs
Common Misconception: “Cellular IoT is Just Like a Phone”
Myth: You can use cellular IoT modules just like a smartphone—always connected, instant data transfer.
Reality: IoT modules optimize for battery life, not speed. Key differences:
Power Consumption: Smartphone: ~500mA continuous (2-hour battery). IoT module with PSM: 5µA sleep + 200mA for 2sec bursts (10-year battery).
Connection Time: Smartphone: Always connected (0ms). NB-IoT: 5-10 seconds to establish connection from PSM sleep. LTE-M with eDRX: 1-2 seconds.
Cost Model: Smartphone: Unlimited data ($50/month). IoT SIM: Pay-per-MB ($0.10/MB) or fixed 10MB/month ($2).
Quantified Impact: A developer assumed NB-IoT had “4G speeds” and designed a video streaming application. Reality check: Streaming 1MB video at 26 kbps takes 5 minutes (vs 0.08 seconds on 4G). After 1 week, 500 devices × 1GB/day × $0.10/MB = $50,000/week connectivity bill (expected $1,400/week). Cost overrun: 3,571%.
Best Practice: Design for constrained bandwidth (send JSON payloads <1KB), intermittent connectivity (tolerate 10-second delays), and aggressive power management (sleep 99.9% of the time). This is the opposite of smartphone app development.
Putting Numbers to It
The monthly data cost for cellular IoT depends on payload size and reporting frequency:
Switching from bloated JSON to binary saves $34,272/month (95% reduction). For 10,000 devices, the difference is $685,000/month. Payload optimization is critical at IoT scale.
Try It: Cellular IoT Data Cost Calculator
Estimate your monthly connectivity costs based on device count, reporting frequency, and payload size — matching the cost formula from the section above.
Figure 23.1: Cellular IoT module selection decision tree by mobility and data rate
Alternative View: Module Cost vs Capability
Module cost vs capability quadrant chart
This quadrant chart positions modules by cost and capability, helping designers choose the right module for their budget and performance requirements.
23.4.2 Hardware Connection: SIM7000 + ESP32
Complete Wiring Diagram:
Figure 23.2: SIM7000 to ESP32 wiring diagram with LiPo battery power
Critical Hardware Notes:
Power Supply: SIM7000 draws 2A peak during transmission. Use LiPo battery (not USB power—causes brownouts). Add 1000µF capacitor near VBAT for current spikes.
UART Serial: Connect ESP32 GPIO17 (TX) → SIM7000 RX, GPIO16 (RX) → SIM7000 TX. Baud rate: 115200. Use hardware serial, not software serial (timing critical).
PWR_KEY: Hold GPIO4 LOW for 1 second to power on module. LED blinks slowly (1s) when connected to network, rapidly (200ms) when searching.
Antenna:MUST connect external antenna before powering on. Running without antenna damages RF amplifier.
SIM Card: Insert before powering on. Check PIN code is disabled (or use AT+CPIN=1234 to unlock).
23.5 AT Command Fundamentals
23.5.1 AT Command Flow
Cellular modules communicate via AT commands (Hayes command set). Basic pattern:
Figure 23.3: AT command sequence for cellular IoT network registration and data transmission
23.5.2 Essential AT Commands
Basic Module Control:
AT // Test connection (returns OK)ATI // Module informationAT+CGMR // Firmware versionAT+CFUN=1// Full functionality modeAT+CFUN=0// Minimum functionality (radio off)
SIM and Network:
AT+CPIN?// Check SIM status (READY/SIM PIN/ERROR)AT+CPIN=1234// Unlock SIM with PIN codeAT+COPS?// Check registered network operatorAT+COPS=?// Scan available networks (slow: 20-60s)AT+COPS=0// Auto-select network (best signal)AT+CSQ // Signal quality (0-31 RSSI, 99=unknown)// Good: >15 (-93 dBm), Excellent: >25 (-73 dBm)AT+CREG?// Network registration status// 0,1 = registered home network// 0,5 = registered roamingAT+CGATT?// GPRS attach status (1=attached)
Data Connection (APN Configuration):
// Configure APN (Access Point Name) - carrier-specificAT+CGDCONT=1,"IP","iot.1nce.net"// 1NCE IoT SIMAT+CGDCONT=1,"IP","hologram"// Hologram global SIMAT+CGDCONT=1,"IP","m2m.com.attz"// AT&T IoT SIMAT+CGDCONT=1,"IP","iot.truphone.com"// Truphone IoTAT+CGDCONT=1,"IP","soracom.io"// Soracom global IoT// Activate PDP context (get IP address)AT+CGACT=1,1// Activate context ID 1AT+CGPADDR=1// Query assigned IP addressAT+CGDATA="PPP",1// Enter data mode (PPP connection)
HTTP Client (Quick Cloud Integration):
AT+HTTPINIT // Initialize HTTPAT+HTTPPARA="CID",1// Set PDP context IDAT+HTTPPARA="URL","http://api.thingspeak.com/update"AT+HTTPPARA="CONTENT","application/json"// Set content typeAT+HTTPDATA=50,5000// Prepare 50 bytes, 5s timeout// After DOWNLOAD prompt, send payload:{"api_key":"ABC123","field1":23.5}AT+HTTPACTION=1// Execute POST (0=GET, 1=POST, 2=HEAD)AT+HTTPREAD // Read responseAT+HTTPTERM // Terminate HTTP
MQTT Client (Persistent Connections):
// Configure MQTT brokerAT+SMCONF="URL","mqtt.example.com","1883"// Broker address and portAT+SMCONF="CLIENTID","device001"// Client IDAT+SMCONF="USERNAME","user"// Username (if required)AT+SMCONF="PASSWORD","pass"// PasswordAT+SMCONF="KEEPTIME",60// Keep-alive interval (seconds)// Connect to brokerAT+SMCONN // Connect (returns OK or ERROR)AT+SMSTATE?// Check connection state (1=connected)// Publish messageAT+SMPUB="sensors/temp",20,1,0// Topic, length, QoS, retain// After > prompt, send payload:{"temperature":23.5}// Subscribe to topicAT+SMSUB="commands/led",1// Topic, QoS// Received messages trigger URC: +SMSUB: "commands/led"// DisconnectAT+SMDISC // Disconnect from broker
Power Saving Modes:
// Power Saving Mode (PSM) - deepest sleepAT+CPSMS=1,"","","00000100","00000001"// Enable PSM// T3324 (active timer): 4 seconds, T3412 (periodic TAU): 1 hour// Module sleeps for ~1 hour between wake-ups// Extended DRX (eDRX) - periodic pagingAT+CEDRXS=1,5,"0101"// Enable eDRX for LTE-M// Paging interval: 20.48 seconds (balance power vs latency)// Light sleep (clock gating)AT+CSCLK=2// Auto sleep when UART idle// Module enters 1mA sleep between commands (wakes on UART RX)// Airplane mode (radio off, 0.1mA)AT+CFUN=4// Airplane modeAT+CFUN=1// Return to full functionality
Try It: PSM Timer Decoder
Decode the T3324 (Active Timer) and T3412 (Periodic TAU) values used in AT+CPSMS commands. These 8-bit binary strings control how long the module stays reachable after communication and how often it wakes for Tracking Area Updates.
Show code
viewof psmT3324 = Inputs.text({label:"T3324 Active Timer (8-bit binary):",value:"00000100",placeholder:"e.g. 00000100"})viewof psmT3412 = Inputs.text({label:"T3412 Periodic TAU (8-bit binary):",value:"00000001",placeholder:"e.g. 00000001"})
Objective: Cellular modules use AT commands to send HTTP requests. This Wokwi lab demonstrates the same HTTP client pattern using ESP32 Wi-Fi, so you can understand the cloud communication flow before working with actual cellular hardware.
The connection flow mirrors cellular AT commands: attach to network, check signal, send data, sleep
Each HTTP POST shows payload size and round-trip time – on real NB-IoT this would be 2-10 seconds instead of milliseconds
The JSON payload is under 100 bytes – critical for cellular IoT where data costs $0.10/MB
In production, you would replace delay(15000) with ESP32 deep sleep + RTC wakeup for years of battery life
Quick Check: AT Command Sequence
23.6 Complete Arduino Implementation
23.6.1 Hardware Serial Cellular Library
Example: ESP32 + SIM7000 Sending Sensor Data
The core pattern connects via AT commands, sends data over HTTP, then enters PSM sleep:
HardwareSerial sim7000(1);// UART1 on ESP32#define SIM_TX 17#define SIM_RX 16#define SIM_PWR_KEY 4void setup(){ sim7000.begin(115200, SERIAL_8N1, SIM_RX, SIM_TX); powerOnModule();// Hold PWR_KEY LOW 1s then HIGH initCellular();// AT -> CPIN? -> CGDCONT -> CREG? -> CGACT}void loop(){float temp =23.5+ random(-50,50)/10.0; sendData(temp,60.0);// HTTP GET to ThingSpeak enterSleepMode(600);// PSM + ESP32 deep sleep 10 min}
Full Implementation (click to expand)
#include <HardwareSerial.h>// SIM7000 on ESP32 hardware serialHardwareSerial sim7000(1);// UART1#define SIM_TX 17#define SIM_RX 16#define SIM_PWR_KEY 4// APN configuration (change for your carrier)constchar* APN ="iot.1nce.net";constchar* SERVER ="api.thingspeak.com";constchar* API_KEY ="YOUR_API_KEY";void setup(){ Serial.begin(115200);// Debug console sim7000.begin(115200, SERIAL_8N1, SIM_RX, SIM_TX);// SIM7000 serial// Power on module pinMode(SIM_PWR_KEY, OUTPUT); powerOnModule();// Wait for module ready delay(5000);// Initialize cellular connectionif(initCellular()){ Serial.println("Cellular connected!");}else{ Serial.println("Connection failed");}}void loop(){// Simulate sensor readingfloat temperature =23.5+ random(-50,50)/10.0;float humidity =60.0+ random(-100,100)/10.0;// Send data to cloud sendData(temperature, humidity);// Sleep for 10 minutes enterSleepMode(600);// 600 seconds}void powerOnModule(){ digitalWrite(SIM_PWR_KEY, LOW); delay(1000);// Hold for 1 second digitalWrite(SIM_PWR_KEY, HIGH); delay(2000); Serial.println("Module powered on");}bool sendATCommand(String cmd, String expected,int timeout){ sim7000.println(cmd);long start = millis(); String response ="";while(millis()- start < timeout){while(sim7000.available()){char c = sim7000.read(); response += c; Serial.write(c);// Echo to console}if(response.indexOf(expected)!=-1){returntrue;}}returnfalse;}bool initCellular(){ Serial.println("Initializing cellular...");// Test moduleif(!sendATCommand("AT","OK",2000)){ Serial.println("Module not responding");returnfalse;}// Check SIM cardif(!sendATCommand("AT+CPIN?","READY",5000)){ Serial.println("SIM card error");returnfalse;}// Configure APN String apnCmd ="AT+CGDCONT=1,\"IP\",\""+ String(APN)+"\"";if(!sendATCommand(apnCmd,"OK",2000)){ Serial.println("APN config failed");returnfalse;}// Wait for network registration (can take 30-60 seconds) Serial.println("Waiting for network... (30-60s)");int retries =30;while(retries-->0){if(sendATCommand("AT+CREG?","+CREG: 0,1",2000)|| sendATCommand("AT+CREG?","+CREG: 0,5",2000)){ Serial.println("Registered on network!");break;} delay(2000);}if(retries <=0){ Serial.println("Network registration timeout");returnfalse;}// Activate PDP contextif(!sendATCommand("AT+CGACT=1,1","OK",30000)){ Serial.println("PDP activation failed");returnfalse;}// Check signal quality sim7000.println("AT+CSQ"); delay(500);while(sim7000.available()){ Serial.write(sim7000.read());}returntrue;}bool sendData(float temp,float humidity){ Serial.println("Sending data via HTTP...");// Initialize HTTPif(!sendATCommand("AT+HTTPINIT","OK",2000)){returnfalse;}// Set CIDif(!sendATCommand("AT+HTTPPARA=\"CID\",1","OK",2000)){ sendATCommand("AT+HTTPTERM","OK",2000);returnfalse;}// Build URL with GET parameters String url ="http://"+ String(SERVER)+"/update?api_key="+ String(API_KEY)+"&field1="+ String(temp)+"&field2="+ String(humidity); String urlCmd ="AT+HTTPPARA=\"URL\",\""+ url +"\"";if(!sendATCommand(urlCmd,"OK",2000)){ sendATCommand("AT+HTTPTERM","OK",2000);returnfalse;}// Execute GET requestif(!sendATCommand("AT+HTTPACTION=0","+HTTPACTION: 0,200",10000)){ Serial.println("HTTP request failed"); sendATCommand("AT+HTTPTERM","OK",2000);returnfalse;} Serial.println("Data sent successfully!");// Terminate HTTP sendATCommand("AT+HTTPTERM","OK",2000);returntrue;}void enterSleepMode(int seconds){ Serial.println("Entering power saving mode...");// Enable PSM (customize T3324 and T3412 timers as needed) sendATCommand("AT+CPSMS=1","OK",2000);// Light sleep (module wakes on timer or UART activity) sendATCommand("AT+CSCLK=2","OK",2000);// Put ESP32 to deep sleep Serial.flush(); esp_sleep_enable_timer_wakeup(seconds *1000000ULL);// microseconds esp_deep_sleep_start();}
Key Implementation Notes:
Hardware Serial: Use HardwareSerial, not SoftwareSerial. SIM7000 requires precise timing (115200 baud) that software serial can’t guarantee.
Power-On Sequence: Hold PWR_KEY LOW for 1 second, then HIGH. LED should start blinking. Wait 5 seconds for RDY message.
Network Registration Time: Can take 30-60 seconds in weak signal areas. NB-IoT takes longer than LTE-M due to cell search process.
HTTP vs MQTT: Use HTTP for simple publish (stateless, no persistent connection). Use MQTT for bidirectional, low-latency communication (persistent connection).
Power Saving: Combining ESP32 deep sleep (10µA) + SIM7000 PSM (5µA) achieves ~15µA total system sleep current.
23.7 Complete IoT Pipeline Architecture
End-to-End System:
Figure 23.4: End-to-end cellular IoT architecture from sensor to cloud dashboard
Data Flow Timeline:
Device Wake-Up (10ms): ESP32 wakes from deep sleep, reads DHT22 sensor via I2C
Module Power-On (1s): ESP32 toggles PWR_KEY to wake SIM7000 from PSM
Network Attach (5-10s): SIM7000 sends TAU (Tracking Area Update) to eNodeB, receives IP address
Publish Data (500ms): MQTT PUBLISH with 50-byte JSON payload {"temp":23.5,"hum":60}
MQTT Broker (100ms): HiveMQ receives, distributes to subscribers, stores in InfluxDB
Dashboard Update (200ms): Grafana queries InfluxDB, updates chart in web browser
Return to Sleep (2s): MQTT DISCONNECT, SIM7000 enters PSM, ESP32 enters deep sleep
Total Active Time: ~10 seconds (0.003% duty cycle for 1-hour reporting interval)
23.8 Troubleshooting Guide
Common Issues and Solutions:
Figure 23.5: Cellular IoT troubleshooting flowchart for common connection issues
Diagnostic Commands:
// Module health checkAT+CGMR // Firmware version (should return version string)AT+CCID // SIM card ICCID (20-digit number)AT+CIMI // SIM card IMSI (15-digit number)// Signal diagnosticsAT+CSQ // Signal quality (15-31 = good, <10 = poor)AT+CPSI?// Detailed signal info (RSRP, RSRQ, SNR)// Example: +CPSI: LTE NB-IOT,Online,// RSRP -95 dBm, RSRQ -10 dB, SNR 5 dB// Network diagnosticsAT+COPS?// Current operator (e.g., "AT&T", "Verizon")AT+CREG=2// Enable network registration URCsAT+CREG?// Registration status + location (LAC, CID)AT+CGPADDR=1// Assigned IP address (e.g., 10.45.23.12)// Data usage trackingAT+CGDCONT?// Active PDP contexts (shows APN configuration)AT+CGACT?// PDP context activation status (1=active, 0=inactive)// Power diagnosticsAT+CPSMS?// PSM configuration (timers T3324, T3412)AT+CEDRXS?// eDRX configuration (paging interval)AT+CPMUTEMP // Module temperature (°C) - should be <60°C
Try It: Signal Quality Interpreter
Enter the CSQ value returned by AT+CSQ to see the corresponding RSSI in dBm and signal quality rating — useful when debugging connectivity in the field.
Show code
viewof csqValue = Inputs.range([0,31], {value:18,step:1,label:"AT+CSQ RSSI value (0-31)"})
Configure your cellular IoT power profile to estimate battery life. Adjust sleep current, transmission parameters, and battery capacity to match the power budget table from the chapter.
Understanding modem architecture helps explain why proper power supply design (LiPo battery, not USB) and antenna connection are critical for reliable cellular IoT implementations.
Visual: Cellular IoT Evolution
Cellular IoT Evolution from 2G to 5G
This evolution diagram provides context for why NB-IoT and LTE-M (Release 13) represent optimized cellular technologies specifically designed for IoT applications rather than simply using smartphone connectivity.
Visual: Cellular Handover Mechanism
Cellular Handover for mobile assets
The handover mechanism is essential for mobile asset tracking implementations where vehicles or containers move between cell coverage areas while maintaining continuous connectivity.
Worked Example: Debugging “Module Not Responding” Issue
Scenario: You’ve wired a SIM7000 NB-IoT module to an ESP32, powered it on, but serial commands get no response. Here’s a systematic diagnostic approach.
Step 1: Verify Power Supply (Most Common Issue)
Symptom
Cause
Solution
Module LED doesn’t blink at all
No power reaching VBAT
Check wiring: ESP32 5V → module VBAT
LED blinks once then stops
USB power browns out during TX (2A spike)
Use LiPo battery (3.7V), not USB
Module resets every 5-10 seconds
Insufficient capacitance
Add 1000 µF capacitor near VBAT
Diagnostic Command:
// Measure voltage at VBAT pin during transmissionAT+CBC // Check battery voltage (should be >3.6V, stable)
Expected:+CBC: 0,95,3.7 (charging=0, 95%, 3.7V) Actual (with USB):+CBC: 0,65,3.1 (voltage sags to 3.1V during TX → resets)
Fix:
// Replace USB power with LiPo// Before: ESP32 USB 5V → SIM7000 VBAT (causes brownouts)// After: LiPo 3.7V → SIM7000 VBAT + ESP32 VIN (stable)
Step 2: Verify Serial Communication
Test
Command
Expected Response
Diagnosis
Module alive?
AT
OK
Basic UART working
Echo enabled?
ATE1
OK
See commands echoed back
Baud rate?
Try 115200, 9600, 57600
OK at correct rate
Wrong baud = garbage
Hardware serial?
Check GPIO pins
UART1/UART2
SoftwareSerial unreliable
Common Serial Issues:
// WRONG: SoftwareSerial (causes timing issues at 115200 baud)#include <SoftwareSerial.h>SoftwareSerial sim(16,17);// RX, TXsim.begin(115200);// Too fast for SoftwareSerial → garbage// CORRECT: Hardware SerialHardwareSerial sim(1);// UART1sim.begin(115200, SERIAL_8N1,16,17);// RX=16, TX=17
Run this diagnostic, and within 90 seconds you’ll identify which stage fails:
Stage 1 fail → Power issue
Stage 2 fail → SIM card issue
Stage 3 fail → Antenna or location issue
Stage 4 fail → Coverage or operator issue
Stage 5 fail → APN configuration issue
Save hours of debugging by following this systematic approach instead of randomly trying commands.
🏷️ Label the Diagram
💻 Code Challenge
23.11 Summary
Module Selection Strategy guides your choice between NB-IoT and LTE-M based on mobility, data rate, and battery requirements. Use NB-IoT (SIM7020) for stationary sensors requiring 10-year battery life, and LTE-M (SIM7070) for mobile tracking with voice support.
Hardware Configuration requires careful attention to power supply (LiPo battery, not USB), antenna connection before power-on, and hardware serial for reliable AT command communication at 115200 baud.
AT Command Mastery enables network registration, APN configuration, and data transmission. The complete sequence from power-on to data upload typically takes 10-20 seconds, with network registration being the longest step (30-60 seconds in weak signal areas).
Power Optimization combines ESP32 deep sleep (10 microamps) with SIM7000 PSM (5 microamps) to achieve 15 microamps total system current, enabling 10-year battery life with 38,000 mAh D-cell batteries.
Data Plan Economics favor prepaid plans like 1NCE ($10 for 500MB/10 years) for low-data applications, while pay-as-you-go providers suit variable usage patterns. A 100-byte payload every 30 minutes consumes only 1.75 MB/year.
Troubleshooting Diagnostics rely on key AT commands: AT+CSQ for signal quality (aim for >15), AT+CPIN? for SIM status, AT+CREG? for network registration, and AT+CGACT? for PDP context activation.
Common Pitfall Avoidance requires designing for constrained bandwidth (under 1 KB payloads) and intermittent connectivity, not smartphone-style always-on connections. Misunderstanding this causes cost overruns exceeding 3,500%.
Task: Build and test a cellular IoT sensor that reports to the cloud.
Hardware Needed:
ESP32 development board
SIM7000 cellular module (or BG96)
IoT SIM card (1NCE, Hologram, or carrier SIM)
LiPo battery (3.7V, 2000+ mAh)
DHT22 temperature/humidity sensor
External LTE antenna
Challenge Steps:
1. Hardware Assembly
Wire SIM7000 to ESP32 hardware serial (TX→16, RX→17)
Connect LiPo battery to SIM7000 VBAT (add 1000µF capacitor)
Attach external antenna to SIM7000 antenna connector
Wire DHT22 sensor to ESP32 GPIO pin
2. Basic Connectivity Test Write Arduino code to: - Power on module with PWR_KEY - Check SIM card status (AT+CPIN?) - Register on network (AT+CREG?) - Get signal quality (AT+CSQ) and log RSSI - Activate PDP context (AT+CGACT=1,1) - Get IP address (AT+CGPADDR=1)
3. Sensor Data Transmission Extend code to: - Read DHT22 temperature and humidity every 5 minutes - Format data as JSON: {"temp":23.5,"humidity":60.2,"device":"ESP32-001"} - Send via HTTP POST to ThingSpeak or your cloud endpoint - Enter PSM sleep mode between transmissions
4. Power Optimization Measure and optimize: - Baseline current during transmission: _____ mA - PSM sleep current: _____ µA - Calculated battery life with 2000 mAh battery: _____ days - Target: Achieve >30 days on single charge
5. Troubleshooting Exercise Deliberately introduce these faults and diagnose: - Remove antenna → Should see AT+CSQ return low RSSI - Wrong APN → AT+CGACT=1,1 fails - Insufficient power → Module resets during transmission - Use your diagnostic script to identify each fault
Expected Learning Outcomes:
Understand AT command flow from power-on to data transmission
Experience real network registration delays (30-60s)
Learn to interpret signal quality and coverage issues
Calculate actual power consumption vs theoretical
Build troubleshooting intuition for field deployments
Bonus Challenge:
Implement MQTT instead of HTTP for persistent connection
Add geofencing alerts using GPS coordinates
Create a dashboard to visualize sensor data over time
Optimize payload size to minimize data costs (<100 bytes/message)
Common Pitfalls
1. Not Implementing AT Command Flow Control
Sending AT commands to cellular modems without hardware flow control (RTS/CTS) or software flow control (XON/XOFF) causes buffer overflows on high-speed UART at rates >115200 baud. Buffer overflow results in corrupted AT responses, missed URCs (Unsolicited Result Codes), and modem unresponsiveness. Always configure UART hardware flow control and implement a command queue with response timeout of at least 300 ms for standard AT commands.
2. Assuming Immediate Registration After Power-Up
Cellular modems require 5–60 seconds to complete network registration after power-up, depending on signal strength, coverage class, and PLMN selection. Firmware that sends data immediately after modem initialization without checking AT+CEREG registration status will fail silently. Poll AT+CEREG every 2 seconds with a 90-second timeout; fall back to restarting the modem if registration fails within the timeout period.
3. Using TCP for All Cellular IoT Communication
TCP’s three-way handshake, ACK overhead, and keep-alive traffic consume significant data on metered cellular plans. A TCP connection with 10-second keep-alive generates 1,440 packets/day of pure overhead — using ~7 MB/month on a device with a 10 MB data plan. Use UDP + application-layer acknowledgment (CoAP confirmable, MQTT-SN with QoS 1) for short sensor messages; reserve TCP for high-reliability command channels where session continuity is needed.
4. Hardcoding Carrier APN Settings
APN settings vary by carrier, country, and M2M vs consumer plan. Hardcoding a specific APN (e.g., “m2m.verizon.com”) means the device fails on a different carrier or when the user changes carriers via eSIM. Store APN settings in non-volatile configuration, allow runtime modification via device management protocol (LwM2M object /11/0/1), and provide a fallback discovery mechanism (try known APNs in order if user-configured APN fails).
23.16 What’s Next
Chapter
Focus
Link
Cellular IoT Comprehensive Review
NB-IoT vs LTE-M comparison, network architecture review
In the next chapter, Cellular IoT Comprehensive Review, we compare NB-IoT vs LTE-M in depth, explore network architecture, and review quiz questions to solidify your understanding.