5G IoT với ESP32: Kết nối NB-IoT & LTE-M từ modem đến MQTT
Hướng dẫn thực tế để nối modem NB-IoT/LTE-M với ESP32: chọn mạng, cấp nguồn, đấu UART, dùng TinyGSM và gửi telemetry đầu tiên.
Chia sẻ

Nếu Wi-Fi không với tới chỗ đặt cảm biến, mình thường không cố kéo thêm một repeater. Một modem cellular nhỏ, gửi vài byte telemetry mỗi vài phút, đôi khi là cách gọn hơn nhiều. Bài này là đường đi ngắn để bạn nối ESP32 với modem LPWA như SIM7080G và đẩy dữ liệu lên MQTT/HTTP.
Một lưu ý để gọi tên cho đúng: NB-IoT và LTE-M là công nghệ LPWA chuẩn hoá từ 4G/LTE, không phải băng thông “5G” như điện thoại. Cụm “5G IoT” ở đây nói về hướng kết nối IoT cellular diện rộng, tiết kiệm pin trong giai đoạn mạng 5G; đừng kỳ vọng stream video từ một SIM7080G.
Mình dựa vào open source nào?
Mình chọn TinyGSM làm lớp giao tiếp chính. Đây là thư viện Arduino mã nguồn mở hỗ trợ SIM7000, SIM7070/SIM7080, Quectel BG95/BG96, u-blox SARA và ESP32 HardwareSerial. Nếu bạn dùng board tích hợp sẵn modem, hãy đọc thêm ví dụ của LilyGO T-SIM7080G: repo có test AT, GNSS, sleep và các ví dụ NB-IoT/LTE-M theo board.
Mình không copy nguyên project rồi gọi là “hướng dẫn”. Phần dưới giữ lại flow đáng tin cậy của các repo đó: bật modem → kiểm tra SIM → đăng ký mạng → mở PDP/APN → truyền dữ liệu, còn chân nguồn và cấu hình radio phải theo đúng board, modem và nhà mạng của bạn.
Chọn NB-IoT hay LTE-M trước khi mua
| Nếu thiết bị của bạn cần | Nghiêng về | Ghi chú ngắn |
|---|---|---|
| Gói tin rất nhỏ, cảm biến pin lâu, vị trí sâu trong nhà | NB-IoT | Độ trễ có thể cao; không hợp điều khiển tức thời. |
| Telemetry thường xuyên hơn, di chuyển, OTA nhỏ hoặc phản hồi nhanh hơn | LTE-M / Cat-M1 | Thường dễ dùng hơn cho node di động; vẫn phải kiểm tra coverage. |
| Ảnh, audio, dashboard “real-time” nặng | Không phải cả hai | Cân nhắc LTE Cat-1/4G hoặc Wi-Fi. |
Đây không phải lựa chọn chỉ theo datasheet. Trước khi đặt hàng, mình sẽ hỏi nhà cung cấp SIM ba điều: khu vực triển khai có NB-IoT hay LTE-M, SIM/APN nào dùng được, và modem có đúng band + firmware mà mạng đó yêu cầu không. Một modem “global” không tự tạo ra coverage.
Bộ phần cứng tối thiểu
- ESP32 DevKit hoặc ESP32-S3.
- Modem SIM7080G/SIM7070G (hoặc modem được TinyGSM hỗ trợ), anten LTE đúng dải tần và SIM có data LPWA.
- Nguồn riêng theo yêu cầu breakout. Với modem cellular, mình ưu tiên nguồn 5 V ổn định, ít nhất 2 A ở đầu vào breakout nếu tài liệu board yêu cầu; không lấy dòng từ chân 3V3 của ESP32.
- Dây UART và mass chung. Nếu breakout không xác nhận mức logic 3.3 V, cần level shifting phù hợp.

TX/RX nối chéo, chung mass; nguồn modem nên đi riêng theo yêu cầu breakout.
Đấu dây và luồng hoạt động
Ví dụ an toàn, thường gặp với ESP32 UART2: modem TXD → GPIO16 (RX2), modem RXD → GPIO17 (TX2), GND ↔ GND. Chân PWRKEY/RST mỗi breakout khác nhau, nên hãy lấy từ schematic/tài liệu board — đừng suy đoán theo tên module.
Tách rõ lớp sensor, modem, mạng và ứng dụng giúp khoanh vùng lỗi nhanh hơn.
Sơ đồ chỉ tách vai trò để dễ debug. ESP32 xử lý sensor, lịch wake/sleep và payload. Modem sở hữu mạng cellular và PDP context. MQTT hoặc HTTP là lớp ứng dụng phía trên; nếu mạng đã vào được nhưng publish lỗi, hãy kiểm tra DNS/TLS/broker thay vì đổi dây UART.
Sketch TinyGSM: kết nối data trước, MQTT sau
Cài TinyGSM từ Library Manager. Đổi YOUR_APN, PIN SIM và chân UART cho board của bạn. Đoạn này cố ý chỉ mở data session và in IP: đó là checkpoint nhỏ, dễ biết lỗi nằm ở SIM, mạng hay app.
#define TINY_GSM_MODEM_SIM7080
#define TINY_GSM_RX_BUFFER 1024
#include <TinyGsmClient.h>
constexpr int MODEM_RX = 16; // ESP32 receives from modem TXD
constexpr int MODEM_TX = 17; // ESP32 sends to modem RXD
constexpr uint32_t MODEM_BAUD = 115200;
const char APN[] = "YOUR_APN";
const char SIM_PIN[] = "";
HardwareSerial SerialAT(2);
TinyGsm modem(SerialAT);
void setup() {
Serial.begin(115200);
SerialAT.begin(MODEM_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
// Bật PWRKEY theo tài liệu breakout trước khi tới đây.
if (!modem.init()) Serial.println("Modem init failed");
if (strlen(SIM_PIN) && modem.getSimStatus() != 3) modem.simUnlock(SIM_PIN);
if (!modem.waitForNetwork(180000L)) Serial.println("Network registration failed");
if (!modem.gprsConnect(APN, "", "")) Serial.println("PDP/APN failed");
Serial.print("IP: ");
Serial.println(modem.localIP());
}
void loop() {}
Khi đã có IP, TinyGsmClient client(modem); là điểm nối sang HTTP client hoặc MQTT client. Với MQTT, mình giữ payload nhỏ, dùng QoS phù hợp và xử lý reconnect có backoff; không lặp connect() liên tục khi sóng yếu.
Nguồn: lý do board hay reset đúng lúc gửi dữ liệu
Modem có các đợt dòng đỉnh khi đăng ký mạng hoặc transmit. Triệu chứng rất quen: AT vẫn trả lời, nhưng vừa attach/PDP là ESP32 brownout hoặc modem reboot. Hãy đo ngay tại chân nguồn modem, dùng dây ngắn, tụ bulk theo khuyến nghị của board và nguồn đủ dòng. Anten cũng phải cắm trước khi phát.

Đo sụt áp ở chân modem trong lúc đăng ký mạng và gửi dữ liệu.
Đừng tối ưu deep sleep trước khi có một phiên truyền ổn định. Sau đó mới thử PSM/eDRX theo thông số nhà mạng, đo dòng thực tế và xác nhận modem thức lại được. Thời gian attach có thể dài hơn bạn quen với Wi-Fi; timeout 10 giây thường chỉ tạo thêm bug khó đoán.
Checklist debug 10 phút
- Gõ
ATvà thấyOKqua serial monitor. - Xác nhận SIM được nhận, PIN đúng và anten LTE đã cắm.
- Xem trạng thái đăng ký mạng (AT command cụ thể phụ thuộc modem); chờ đủ lâu ở lần đầu.
- Xác nhận APN đúng cho LPWA SIM, không lấy bừa APN của SIM điện thoại.
- Có IP rồi mới test DNS, HTTP hoặc MQTT.
- Nếu reset khi transmit, quay về đo nguồn và sụt áp trước khi sửa code.

Một node LPWA nhỏ phù hợp để gửi telemetry từ nơi Wi-Fi không phủ tới.
Điều mình sẽ làm tiếp
Node đầu tiên nên chỉ đọc một cảm biến và gửi JSON nhỏ, ví dụ {"t":29.4,"v":3.98}. Khi nó chạy ổn ngoài vị trí thật vài ngày, mình mới thêm TLS, buffer offline, OTA và enclosure. Làm như vậy chậm hơn một buổi, nhưng nhanh hơn rất nhiều so với debug cả radio, pin, broker và firmware cùng lúc.
Tham khảo
Chia sẻ
Tiếp tục khám phá
Đọc tiếp
Bài viết liên quan
Real-Time Operating System (RTOS): FreeRTOS trên ESP32
Hướng dẫn dùng FreeRTOS trên ESP32 cho firmware multitasking: tạo task, truyền dữ liệu bằng queue, dùng notification, mutex và kiểm tra stack theo cách dễ bắt đầu.
Industrial IoT với ESP32: Modbus và điều khiển real-time
Hướng dẫn thực tế về Modbus TCP, Modbus RTU qua RS-485 và cách kết nối ESP32 với PLC cho các prototype Industrial IoT đáng tin cậy hơn.
OTA Firmware Updates: Thiết kế và triển khai cập nhật firmware từ xa
Hướng dẫn thiết kế OTA an toàn cho ESP32 và STM32, từ partition, image có chữ ký, rollback, rollout theo nhóm đến delta update.