Module 4G A7680C với ESP32: gửi SMS, bật tắt relay bằng tin nhắn, vì sao SIM800L không còn dùng được
Sóng 2G ở Việt Nam đã tắt nên SIM800L không còn dùng được; chọn module 4G thay thế, nối A7680C với ESP32, dùng lệnh AT gửi SMS, nhận lệnh từ số chủ máy để bật tắt relay.
Ở nơi không có Wi-Fi như trang trại, nhà kho, trạm bơm, tin nhắn SMS vẫn là cách đơn giản để thiết bị báo tin và nhận lệnh: mất điện thì nhắn báo, nhắn "BAT" thì bật máy bơm. Trước đây ai cũng dùng module SIM800L, nhưng ở Việt Nam sóng 2G đã tắt hẳn nên module này không còn hoạt động. Bài này giải thích vì sao, cách chọn module 4G thay thế, rồi nối module 4G (loại SIMCom A7680C) với ESP32 để gửi SMS và bật tắt relay bằng tin nhắn từ điện thoại.
1. Vì sao không dùng SIM800L nữa

SIM800L, SIM800C, SIM900 là module chỉ chạy mạng 2G (GSM). Lộ trình tắt sóng 2G ở Việt Nam:
- Từ 16/10/2024, các nhà mạng dừng phục vụ thiết bị chỉ hỗ trợ 2G, trừ một số khu vực đặc biệt.
- Từ giữa tháng 9/2026, sóng 2G tắt hẳn trên cả nước. Băng tần 2G được chuyển cho 4G, 5G.
Vì vậy module 2G cắm SIM vào sẽ không đăng ký được mạng. Dự án cũ dùng SIM800L cần đổi sang module 4G. Nếu module mua từ lâu không ghi rõ loại mạng, tra mã module trên mạch trước khi dùng.
2. Chọn module 4G
- Module 4G LTE Cat 1 như A7680C, A7670, EC200: phổ biến nhất cho thiết bị IoT, đủ cho SMS, dữ liệu 4G tốc độ vừa phải, giá vừa phải. Phiên bản bán ở thị trường châu Á thường hỗ trợ các băng 4G mà mạng Việt Nam dùng (B1, B3, B8). Kiểm tra lại bảng băng tần của phiên bản cụ thể trước khi mua.
- Module 4G Cat 4 như SIM7600: tốc độ cao hơn, đắt hơn, hợp với truyền hình ảnh.
- SMS và gọi thoại trên mạng chỉ có 4G phụ thuộc vào firmware của module (hỗ trợ VoLTE, IMS) và việc nhà mạng mở các dịch vụ này cho SIM. Dữ liệu 4G thì dùng được ngay. Trước khi làm dự án cần SMS hay gọi điện, thử với chính SIM sẽ dùng, hoặc hỏi nhà mạng.
Các module A76xx dùng chung bộ lệnh AT cơ bản với SIM800 (gửi tin nhắn bằng AT+CMGS, cài đặt bằng AT+CMGF, AT+CNMI), nên chương trình cũ chuyển sang khá dễ. Riêng lệnh kiểm tra đăng ký mạng 4G là AT+CEREG? thay cho AT+CREG? của 2G.
3. Linh kiện cần chuẩn bị
- ESP32 DevKit V1 30 chân (hoặc loại 38 chân).
- Mạch module 4G (A7680C hoặc tương đương) có khe SIM, anten 4G, chân TX/RX mức 3,3 V. SIM có gói SMS (SIM thường của điện thoại cũng được).
- Nguồn 5 V chịu được 2 A riêng cho module 4G: adapter 12 V qua mạch hạ áp LM2596 chỉnh ra 5 V là cách dễ làm.
- Module relay 1 kênh 5 V, dây cắm, dây USB nạp code.
4. Sơ đồ nối dây

| Module 4G | Nối vào | Ghi chú |
|---|---|---|
| 5V | Nguồn 5 V riêng | Chịu được 2 A, dây to, ngắn |
| GND | GND nguồn và GND ESP32 | Bắt buộc nối chung |
| TXD | RX2 (GPIO16) | TX nối chéo sang RX |
| RXD | TX2 (GPIO17) |
Khi phát sóng, module di động kéo dòng tăng vọt trong vài mili giây. Nguồn yếu làm module khởi động lại hoặc mất mạng giữa chừng: đây là lỗi hay gặp nhất. Không lấy nguồn module từ chân 3V3 hay VIN của ESP32. Thêm một tụ 470–1000 µF sát chân nguồn của module càng tốt.
Một số mạch module có chân PWRKEY (hoặc nút bấm) để bật module: cần giữ PWRKEY ở mức thấp khoảng 1 giây sau khi cấp nguồn. Nhiều mạch đã tự nối sẵn để module tự bật; đọc mô tả của mạch đang dùng.
5. Gửi và nhận SMS bằng lệnh AT

Module di động nói chuyện với vi điều khiển bằng lệnh AT: dòng chữ bắt đầu bằng AT, module trả lời OK hoặc ERROR kèm dữ liệu. Các lệnh chương trình dùng:
| Lệnh | Ý nghĩa |
|---|---|
AT | Kiểm tra module có trả lời không |
ATE0 | Tắt lặp lại lệnh, trả lời gọn hơn |
AT+CPIN? | SIM đã sẵn sàng chưa (READY) |
AT+CEREG? | Đã đăng ký mạng 4G chưa (,1 là mạng nhà, ,5 là chuyển vùng) |
AT+CSQ | Cường độ sóng, 0–31, càng lớn càng tốt; 99 là chưa đo được |
AT+CMGF=1 | Tin nhắn dạng chữ (text mode) |
AT+CNMI=2,2,0,0,0 | Tin nhắn mới đưa thẳng ra UART dạng +CMT:, không cần đọc từ bộ nhớ SIM |
AT+CMGS="số" | Gửi tin: chờ dấu >, gõ nội dung, kết thúc bằng ký tự Ctrl+Z (0x1A) |
6. Chương trình gửi SMS, nhận lệnh bật tắt relay
Sửa SO_CHU_MAY thành số điện thoại của bạn, dạng +84 rồi bỏ số 0 đầu (ví dụ 09xx… thành +849xx…). Chọn bo ESP32 Dev Module rồi nạp. Bài dùng gói esp32 phiên bản 3.3.10, không cần thư viện thêm.
// PYWORLD.VN - Module 4G (SIMCom A7680C và các module A76xx) với ESP32: gửi SMS, nhận lệnh bằng tin nhắn để bật tắt relay
// Module: TXD vào RX2 (GPIO16), RXD vào TX2 (GPIO17), nguồn 5 V riêng chịu được 2 A, GND chung với ESP32; relay IN vào D26
// Chỉ nhận lệnh từ SO_CHU_MAY. Tin nhắn: BAT, TAT, TRANG THAI (không phân biệt hoa thường)
HardwareSerial modem(2);
const int CHAN_RX2 = 16;
const int CHAN_TX2 = 17;
const int CHAN_RELAY = 26;
const bool RELAY_KICH_MUC_THAP = true;
const char *SO_CHU_MAY = "+84000000000"; // sửa thành số điện thoại của bạn, dạng +84...
bool relayDangBat = false;
// Gửi một lệnh AT và gom trả lời cho tới khi thấy `cho` hoặc hết `thoiGianMs`. Trả về toàn bộ trả lời.
String guiAt(const String &lenh, const char *cho = "OK", uint32_t thoiGianMs = 2000) {
while (modem.available()) modem.read(); // bỏ dữ liệu cũ còn trong bộ đệm
if (lenh.length()) modem.println(lenh);
String traLoi;
uint32_t batDau = millis();
while (millis() - batDau < thoiGianMs) {
while (modem.available()) traLoi += (char)modem.read();
if (traLoi.indexOf(cho) >= 0 || traLoi.indexOf("ERROR") >= 0) break;
delay(5);
}
return traLoi;
}
// Cường độ sóng từ AT+CSQ: 0-31 (càng lớn càng tốt), 99 là chưa đo được.
int doSong() {
String r = guiAt("AT+CSQ");
int viTri = r.indexOf("+CSQ:");
return viTri < 0 ? 99 : r.substring(viTri + 5).toInt();
}
bool guiSms(const char *so, const String &noiDung) {
String r = guiAt(String("AT+CMGS=\"") + so + "\"", ">", 5000); // chờ dấu nhắc '>'
if (r.indexOf('>') < 0) return false;
modem.print(noiDung);
modem.write(0x1A); // Ctrl+Z: kết thúc tin nhắn và gửi đi
r = guiAt("", "+CMGS:", 60000); // nhà mạng có thể mất vài giây đến vài chục giây
return r.indexOf("+CMGS:") >= 0;
}
void datRelay(bool bat) {
relayDangBat = bat;
digitalWrite(CHAN_RELAY, (bat == RELAY_KICH_MUC_THAP) ? LOW : HIGH);
}
// +CMT: "+84xxxxxxxxx","","26/10/25,17:15:32+28" rồi dòng sau là nội dung tin nhắn.
void xuLyTinNhan(const String &dauDong, String noiDung) {
int a = dauDong.indexOf('"');
int b = dauDong.indexOf('"', a + 1);
String nguoiGui = (a >= 0 && b > a) ? dauDong.substring(a + 1, b) : "";
noiDung.trim();
noiDung.toUpperCase();
Serial.printf("SMS tu %s: %s\n", nguoiGui.c_str(), noiDung.c_str());
if (nguoiGui != SO_CHU_MAY) {
Serial.println("Khong phai so chu may: bo qua");
return;
}
String traLoi;
if (noiDung == "BAT") {
datRelay(true);
traLoi = "Da BAT relay";
} else if (noiDung == "TAT") {
datRelay(false);
traLoi = "Da TAT relay";
} else if (noiDung == "TRANG THAI") {
traLoi = String("Relay ") + (relayDangBat ? "BAT" : "TAT") + ", song " + doSong() + "/31";
} else {
traLoi = "Lenh: BAT, TAT, TRANG THAI";
}
Serial.println(guiSms(SO_CHU_MAY, traLoi) ? "Da tra loi: " + traLoi : "Loi gui SMS tra loi");
}
void setup() {
Serial.begin(115200);
pinMode(CHAN_RELAY, OUTPUT);
datRelay(false);
modem.begin(115200, SERIAL_8N1, CHAN_RX2, CHAN_TX2); // A76xx mặc định 115200 baud
delay(3000); // module cần vài giây khởi động
if (guiAt("AT").indexOf("OK") < 0) {
Serial.println("Module khong tra loi AT: kiem tra TX/RX, nguon 5V, nut PWRKEY");
return;
}
guiAt("ATE0"); // tắt lặp lại lệnh cho dễ đọc trả lời
Serial.println(guiAt("AT+CPIN?").indexOf("READY") >= 0 ? "SIM san sang" : "Khong thay SIM hoac SIM bi khoa PIN");
for (int i = 0; i < 30; i++) { // chờ đăng ký mạng 4G tối đa khoảng 60 giây
String r = guiAt("AT+CEREG?");
if (r.indexOf(",1") >= 0 || r.indexOf(",5") >= 0) { // 1: mạng nhà, 5: chuyển vùng
Serial.printf("Da dang ky mang 4G, song %d/31\n", doSong());
break;
}
delay(2000);
}
guiAt("AT+CMGF=1"); // tin nhắn dạng chữ (text mode)
guiAt("AT+CSCS=\"GSM\""); // bảng chữ GSM: không dấu
guiAt("AT+CNMI=2,2,0,0,0"); // tin nhắn mới đưa thẳng ra UART dạng +CMT
Serial.println(guiSms(SO_CHU_MAY, "ESP32 da khoi dong. Lenh: BAT, TAT, TRANG THAI") ? "Da gui SMS khoi dong" : "Loi gui SMS");
}
void loop() {
static String dong, dauCmt;
while (modem.available()) {
char c = modem.read();
if (c == '\n') {
dong.trim();
if (dauCmt.length() && dong.length()) { // dòng ngay sau +CMT là nội dung
xuLyTinNhan(dauCmt, dong);
dauCmt = "";
} else if (dong.startsWith("+CMT:")) {
dauCmt = dong;
}
dong = "";
} else if (c != '\r' && dong.length() < 200) {
dong += c;
}
}
}
7. Giải thích các phần chính
guiAt()xóa dữ liệu cũ, gửi lệnh, rồi gom trả lời cho tới khi thấy chuỗi chờ (thường làOK), thấyERRORhoặc hết giờ. Mọi lệnh khác đều đi qua hàm này.guiSms()gửiAT+CMGS, chờ dấu nhắc>, gửi nội dung và byte 0x1A. Nhà mạng có thể mất vài chục giây mới xác nhận, nên chờ tới 60 giây cho dòng+CMGS:.- Nhận tin: nhờ
AT+CNMI=2,2,0,0,0, mỗi tin nhắn tới hiện thành hai dòng: dòng+CMT:chứa số gửi và thời gian, dòng sau là nội dung.loop()nhớ dòng+CMT:rồi xử lý dòng kế tiếp. - Chỉ nhận số chủ máy: ai biết số SIM trên thiết bị cũng nhắn được. Chương trình bỏ qua mọi tin không đến từ
SO_CHU_MAY. Muốn chặt hơn, thêm mật mã vào đầu lệnh, ví dụ "1234 BAT". - Tin nhắn không dấu: bảng chữ GSM (
AT+CSCS="GSM") không có chữ tiếng Việt có dấu. Tin trả lời của chương trình đều viết không dấu. - Relay giữ trạng thái tới khi có lệnh mới. Nhắn "TRANG THAI" để biết relay đang bật hay tắt và cường độ sóng.
8. Điều khiển relay bằng tin nhắn

Mỗi tin nhắn trả lời tính phí như tin nhắn thường. Thiết bị báo tin liên tục (ví dụ mỗi lần nhiệt độ thay đổi) nên gộp báo cáo hoặc chỉ nhắn khi vượt ngưỡng.
9. Kết quả trên Serial Monitor

10. Xử lý lỗi thường gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| "Module khong tra loi AT" | Đảo TX/RX, sai tốc độ baud, module chưa bật (PWRKEY), nguồn yếu | TXD module vào RX2; thử 9600 nếu 115200 không được; kiểm tra đèn trạng thái module |
| Không thấy dòng "Da dang ky mang 4G" | Anten chưa cắm, module 2G, băng tần không hợp, SIM hết hạn | Cắm anten; kiểm tra mã module; lắp SIM vào điện thoại thử trước |
| Đăng ký mạng được nhưng gửi SMS báo lỗi | Firmware module, nhà mạng chưa hỗ trợ SMS trên 4G cho SIM này; số sai định dạng | Dùng dạng +84…; thử SIM nhà mạng khác; hỏi nhà mạng; cập nhật firmware module |
| Module khởi động lại khi gửi tin | Sụt nguồn lúc phát sóng | Nguồn 5 V 2 A riêng, dây ngắn, thêm tụ lớn |
| Nhắn lệnh mà thiết bị không phản ứng | Sai SO_CHU_MAY, tin nhắn có dấu hoặc thừa ký tự | Xem dòng "SMS tu …" trên Serial Monitor để biết số và nội dung thật nhận được |
11. Xem thêm
- ESP32 điều khiển module relay an toàn: đấu relay với máy bơm, đèn 220 V.
- UART là gì và cách dùng Serial2: nền tảng để giao tiếp với module bằng lệnh AT.
- LoRa với ESP32: lựa chọn không tốn cước khi thiết bị cách trạm vài km.
- MQTT với ESP32: khi module 4G có dữ liệu, gửi số đo lên máy chủ rẻ hơn nhắn tin.
Xem thêm