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

Mốc tắt sóng 2G ở Việt Nam: tháng 10 năm 2024 dừng phục vụ máy chỉ hỗ trợ 2G, giữa tháng 9 năm 2026 tắt hẳn sóng 2G, kèm bảng các loại module di động và khả năng dùng ở Việt Nam
Mốc tắt sóng 2G ở Việt Nam và các loại module di động (thông tin tới 25/10/2026).

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ị

4. Sơ đồ nối dây

Sơ đồ nối module 4G A7680C với ESP32: 5V từ nguồn riêng 2 A, GND chung, TXD vào RX2, RXD vào TX2; module relay IN vào D26, VCC vào VIN
Module 4G dùng nguồn 5 V riêng và UART2 của ESP32; relay ở D26 (hình minh họa).
Module 4GNối vàoGhi chú
5VNguồn 5 V riêngChịu được 2 A, dây to, ngắn
GNDGND nguồn và GND ESP32Bắt buộc nối chung
TXDRX2 (GPIO16)TX nối chéo sang RX
RXDTX2 (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

Trình tự lệnh AT gửi và nhận SMS: AT+CMGF=1, AT+CNMI, AT+CMGS kèm số điện thoại, nội dung kết thúc bằng Ctrl+Z, trả lời +CMGS và tin nhắn đến dạng +CMT
Các lệnh chương trình gửi và trả lời của module (số điện thoại là chữ giữ chỗ).

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
ATKiểm tra module có trả lời không
ATE0Tắ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+CSQCường độ sóng, 0–31, càng lớn càng tốt; 99 là chưa đo được
AT+CMGF=1Tin nhắn dạng chữ (text mode)
AT+CNMI=2,2,0,0,0Tin 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ấy ERROR hoặc hết giờ. Mọi lệnh khác đều đi qua hàm này.
  • guiSms() gửi AT+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

Điện thoại nhắn BAT và TRANG THAI, thiết bị trả lời Da BAT relay và Relay BAT song 21/31; lưu đồ nhận +CMT, kiểm tra số chủ máy, làm lệnh, gửi SMS trả lời
Điện thoại nhắn lệnh, ESP32 kiểm tra số gửi rồi làm lệnh và nhắn trả lời (hình minh họa).

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

Serial Monitor in SIM sẵn sàng, đã đăng ký mạng 4G, đã gửi SMS khởi động, tin nhắn BAT từ số chủ máy, đã trả lời, tin của số lạ bị bỏ qua
Chạy bình thường và khi module chưa trả lời (số điện thoại là chữ giữ chỗ).

10. Xử lý lỗi thường gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
"Module khong tra loi AT"Đảo TX/RX, sai tốc độ baud, module chưa bật (PWRKEY), nguồn yếuTXD 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ạnCắ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ỗiFirmware module, nhà mạng chưa hỗ trợ SMS trên 4G cho SIM này; số sai định dạngDù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 tinSụt nguồn lúc phát sóngNguồ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 ứngSai 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


Tin tức liên quan

Dải LED WS2812B với ESP32: điều khiển từng bóng bằng RMT không cần thư viện, tính dòng và chọn nguồn
Dải LED WS2812B với ESP32: điều khiển từng bóng bằng RMT không cần thư viện, tính dòng và chọn nguồn

Bên trong bóng WS2812B, tín hiệu một dây 24 bit GRB, cách tính dòng để chọn nguồn, nối dải LED với ESP32 và tạo tín hiệu bằng bộ RMT không cần thư viện, kèm ba hiệu ứng.

Làm gateway LoRa sang MQTT bằng ESP32: node cảm biến chạy pin gửi dữ liệu về broker
Làm gateway LoRa sang MQTT bằng ESP32: node cảm biến chạy pin gửi dữ liệu về broker

Hướng dẫn làm hệ thống LoRa hoàn chỉnh với ESP32 và SX1278: node chạy pin đo điện áp, gửi gói rồi ngủ sâu; gateway nhận gói LoRa và publish dữ liệu JSON lên broker MQTT qua Wi-Fi.

Vẽ đồ thị dữ liệu ESP32 trên ThingSpeak: theo dõi pin 18650, ngủ sâu và ước tính thời gian chạy pin
Vẽ đồ thị dữ liệu ESP32 trên ThingSpeak: theo dõi pin 18650, ngủ sâu và ước tính thời gian chạy pin

ESP32 chạy pin 18650 thức dậy mỗi 10 phút, đo điện áp pin, gửi lên ThingSpeak rồi ngủ sâu; cách tạo kênh, ước tính thời gian chạy pin và giảm dòng lúc ngủ.

Hướng dẫn kết nối Wi-Fi trên ESP32: quét mạng, tự kết nối lại, IP tĩnh và phát Wi-Fi riêng
Hướng dẫn kết nối Wi-Fi trên ESP32: quét mạng, tự kết nối lại, IP tĩnh và phát Wi-Fi riêng

Hướng dẫn các thao tác Wi-Fi cần dùng nhất trên ESP32 với Arduino IDE: quét mạng, kết nối có thời gian chờ, xem IP và cường độ sóng, tự kết nối lại, đặt IP tĩnh, phát Wi-Fi riêng.

LED ma trận MAX7219 và LED 7 đoạn TM1637 với ESP32: chữ chạy 32 × 8 và đồng hồ, không cần thư viện
LED ma trận MAX7219 và LED 7 đoạn TM1637 với ESP32: chữ chạy 32 × 8 và đồng hồ, không cần thư viện

So sánh LED ma trận MAX7219 và LED 7 đoạn TM1637, nối với ESP32 an toàn mức điện áp, giải thích khung 16 bit và ba lệnh TM1637, hai chương trình chữ chạy và đồng hồ không cần thư viện.

Đồng hồ và dự báo thời tiết trên OLED: ESP32 lấy dữ liệu Open-Meteo qua HTTP API
Đồng hồ và dự báo thời tiết trên OLED: ESP32 lấy dữ liệu Open-Meteo qua HTTP API

ESP32 lấy giờ NTP và thời tiết Open-Meteo qua HTTPS mỗi 15 phút, đọc JSON bằng ArduinoJson, hiện nhiệt độ, độ ẩm, gió và dự báo 3 ngày trên OLED 0.96 inch.

ESP-NOW nhiều node với ESP32: nhiều mạch gửi về một trạm thu, hiển thị trên OLED
ESP-NOW nhiều node với ESP32: nhiều mạch gửi về một trạm thu, hiển thị trên OLED

Hướng dẫn dựng mô hình ESP-NOW nhiều node: tối đa bốn ESP32 gửi số đo về một trạm thu, trạm thu hiện điện áp, RSSI và tình trạng từng node trên màn hình OLED 0.96 inch.

ESP32-CAM là gì: sơ đồ chân, cách nạp code, xem video trên trình duyệt, chụp ảnh lưu thẻ nhớ
ESP32-CAM là gì: sơ đồ chân, cách nạp code, xem video trên trình duyệt, chụp ảnh lưu thẻ nhớ

Giới thiệu mạch ESP32-CAM AI Thinker, sơ đồ chân, nạp code bằng đế MB hoặc USB-TTL, chương trình xem video MJPEG trên trình duyệt, chụp ảnh có đèn flash và lưu vào thẻ microSD.


Bình luận
Đã thêm vào giỏ hàng