Lập trình ESP32 – Bài 16: Module SIM 4G A7680C – Gọi điện thoại, in thông tin SIM/Module, trạng thái 4G

Kết nối ESP32 với module 4G A7680C, đọc & in thông tin SIM/thiết bị (IMEI, ICCID, IMSI, phiên bản), nhấn nút để gọi đến số mặc định, và in trạng thái kết nối 4G (CSQ, nhà mạng, đăng ký mạng, địa chỉ IP) bằng lệnh AT.

Mục lục

  1. Giới thiệu
  2. Phần cứng & nguồn cấp
  3. Sơ đồ kết nối
  4. Danh mục lệnh AT sử dụng
  5. Mã nguồn đầy đủ (Arduino)
  6. Giải thích nhanh
  7. Kết quả kỳ vọng
  8. Lỗi thường gặp & cách khắc phục
  9. Gợi ý mở rộng

1) Giới thiệu

Module 4G A7680C cho phép điện thoại/GPRS/4G qua AT command. Trong demo này, ESP32 sẽ:

  • In thông tin SIM & module (IMEI, ICCID, IMSI, model, firmware).
  • In trạng thái kết nối 4G: cường độ sóng (CSQ), nhà mạng (COPS), đăng ký mạng (CREG/CEREG), trạng thái gắn PDP (CGATT), địa chỉ IP (CGPADDR).
  • nút nhấn để gọi một số mặc định (demo ATD…).

Lưu ý: Một số tên lệnh có thể khác nhau giữa các biến thể firmware. Các lệnh dưới đây là “chuẩn phổ biến” trên modem 4G (SIMCom/ASR). Nếu A7680C của bạn dùng firmware khác, hãy đối chiếu tài liệu AT của nhà sản xuất.


2) Phần cứng & nguồn cấp

Linh kiệnSố lượngGhi chú
ESP32 DevKit V11UART2 dùng GPIO16 (RX2), GPIO17 (TX2)
Module 4G A7680C1Phiên bản có chân UART TTL
SIM 4G còn hạn1Có thoại & dữ liệu
Nguồn 5V ổn định1Khuyến nghị riêng cho module 4G (dòng đỉnh > 1A)
Nút nhấn1Kéo xuống GND, dùng INPUT_PULLUP
Dây nối, breadboardVài sợi

Nguồn cấp quan trọng:

  • Modem 4G có dòng đỉnh cao (lúc đính mạng/gọi) → nên cấp nguồn 4.0–5.0V riêng, mass chung với ESP32.

Logic UART:

  • Ưu tiên module IO 3.3V; nếu IO là 1.8/2.8V → cần mạch chuyển mức.

3) Sơ đồ kết nối (Connection Diagram)

  • Nguồn: ESP32 qua USB; A7680C qua 5V riêng (GND chung).
  • UART: ESP32 TX2 (GPIO17) → A7680C RXDESP32 RX2 (GPIO16) ← A7680C TXD.
  • PWRKEY (tuỳ chọn): ESP32 GPIO25 → PWRKEY (để bật/tắt module bằng phần mềm, thường kéo xuống ~1–2s).
  • Nút gọi: BUTTON → GPIO4, chân còn lại → GND (dùng INPUT_PULLUP).

4) Danh mục lệnh AT dùng trong demo

  • Thông tin cơ bản:
    • AT (echo, kiểm tra)
    • ATI hoặc AT+CGMR/AT+CGMM/AT+CGMI (phiên bản, model, NSX)
    • AT+CGSN (IMEI)
    • AT+CCID (ICCID – số seri SIM)
    • AT+CIMI (IMSI – thuê bao)
  • Mạng/4G:
    • AT+CSQ (cường độ sóng)
    • AT+COPS? (nhà mạng đăng ký)
    • AT+CREG? / AT+CEREG? (trạng thái đăng ký mạng 2G/4G)
    • AT+CGATT? (gắn PDP)
    • AT+CGPADDR=1 (địa chỉ IP PDP #1)
    • (Tuỳ firmware) AT+CPSI? hoặc AT+QNWINFO (công nghệ mạng/ban nhạc)
  • Gọi thoại:
    • ATD<so>; (gọi) — ví dụ ATD0987654321;
    • ATH (ngắt cuộc gọi)

5) Mã nguồn đầy đủ (Arduino – ESP32)

Mặc định dùng Serial2baud 115200. Nếu module của bạn dùng baud khác (9600/115200), hãy đổi trong Serial2.begin(...).

#include <Arduino.h>

#define RX2_PIN   16   // ESP32 nhận - nối TXD của A7680C
#define TX2_PIN   17   // ESP32 phát  - nối RXD của A7680C
#define BTN_CALL  4    // Nút nhấn gọi
#define PWRKEY    25   // Tùy chọn: điều khiển PWRKEY của module

// Số điện thoại mặc định để gọi (đổi theo bạn)
const char* DEFAULT_NUMBER = "+84901234567";

// Gửi lệnh AT và in toàn bộ phản hồi trong timeout (ms)
String sendAT(const String& cmd, uint32_t timeout = 2000, bool echo = true) {
  if (echo) Serial.printf(">> %s\n", cmd.c_str());
  Serial2.println(cmd);
  String resp;
  uint32_t t0 = millis();
  while (millis() - t0 < timeout) {
    while (Serial2.available()) {
      char c = (char) Serial2.read();
      resp += c;
    }
  }
  resp.trim();
  if (resp.length()) Serial.println(resp);
  return resp;
}

// Nhấn PWRKEY ~1.5s để bật module (nếu cần)
void powerOnModule() {
  pinMode(PWRKEY, OUTPUT);
  digitalWrite(PWRKEY, HIGH);
  delay(10);
  Serial.println("Pulsing PWRKEY to power on...");
  digitalWrite(PWRKEY, LOW);
  delay(1500);
  digitalWrite(PWRKEY, HIGH);
  delay(3000); // chờ module khởi động
}

void printSimAndModuleInfo() {
  sendAT("AT", 500);
  sendAT("ATE0", 500);                   // tắt echo (tùy chọn)
  sendAT("ATI", 1500);
  sendAT("AT+CGMI", 1500);               // Manufacturer
  sendAT("AT+CGMM", 1500);               // Model
  sendAT("AT+CGMR", 1500);               // Firmware
  sendAT("AT+CGSN", 1500);               // IMEI
  sendAT("AT+CCID", 1500);               // ICCID (SIM serial)
  sendAT("AT+CIMI", 1500);               // IMSI (subscriber)
}

void print4GStatus() {
  Serial.println("\n== 4G Network Status ==");
  sendAT("AT+CSQ", 1500);                // Signal
  sendAT("AT+COPS?", 2000);              // Operator
  sendAT("AT+CREG?", 1500);              // Circuit reg
  sendAT("AT+CEREG?", 1500);             // EPS reg (LTE)
  sendAT("AT+CGATT?", 1500);             // PDP attach
  sendAT("AT+CGDCONT?", 2000);           // APN context
  sendAT("AT+CGPADDR=1", 2000);          // IP address for CID=1
  // Tùy module/firmware, một trong 2 lệnh dưới sẽ trả công nghệ mạng/band:
  sendAT("AT+CPSI?", 2000);              // RAT/Band/Cell (nếu hỗ trợ)
  sendAT("AT+QNWINFO", 2000);            // Thông tin mạng (thiết bị Quectel/ASR)
}

void placeCall(const char* number, uint32_t holdMs = 10000) {
  String cmd = "ATD";
  cmd += number;
  cmd += ";";
  Serial.println("\n== Dialing number ==");
  sendAT(cmd, 5000);
  // giữ cuộc gọi một lúc (demo), rồi gác máy
  delay(holdMs);
  Serial.println("== Hang up ==");
  sendAT("ATH", 2000);
}

void setup() {
  Serial.begin(115200);
  delay(200);

  // UART với module 4G
  Serial2.begin(115200, SERIAL_8N1, RX2_PIN, TX2_PIN);

  pinMode(BTN_CALL, INPUT_PULLUP);
  pinMode(PWRKEY, OUTPUT);
  digitalWrite(PWRKEY, HIGH);

  // Bật module (nếu cần). Nếu module của bạn tự khởi động, có thể bỏ.
  powerOnModule();

  // In thông tin SIM & Module
  printSimAndModuleInfo();

  // In trạng thái kết nối 4G
  print4GStatus();

  Serial.println("\nNhấn nút (GPIO4) để gọi thử số mặc định...");
}

bool prevBtn = true;

void loop() {
  // Pass-thru: cho phép gõ tay từ Serial Monitor -> Module (debug)
  if (Serial.available()) Serial2.write(Serial.read());
  if (Serial2.available()) Serial.write(Serial2.read());

  // Nhấn nút gọi (cạnh xuống)
  bool curBtn = digitalRead(BTN_CALL);
  if (prevBtn && !curBtn) {
    placeCall(DEFAULT_NUMBER, 8000);
  }
  prevBtn = curBtn;

  // Có thể đọc trạng thái định kỳ
  static uint32_t t0 = 0;
  if (millis() - t0 > 15000) {
    print4GStatus();
    t0 = millis();
  }
}

6) Giải thích nhanh

  • Serial2 (GPIO16/17) dùng để nói chuyện với A7680C qua AT command.
  • powerOnModule() tạo xung PWRKEY để bật module (nhiều board cần thao tác này).
  • printSimAndModuleInfo() gọi chuỗi lệnh AT IMEI/ICCID/IMSI/model/firmware.
  • print4GStatus() in CSQ/COPS/CREG/CEREG/CGATT/CGDCONT/IP — bộ “chuẩn” để kiểm tra 4G.
  • placeCall() dùng ATD<number>; để gọi, đợi vài giây và ATH để gác.

7) Kết quả kỳ vọng

Trên Serial Monitor (115200) bạn sẽ thấy:

  • Thông tin module/SIM (NSX, Model, Firmware, IMEI, ICCID, IMSI).
  • CSQ (0–31), COPS (tên nhà mạng), CREG/CEREG (đăng ký mạng), CGATT (PDP attach), CGPADDR (IP).
  • Khi nhấn nút, xuất hiện lệnh ATD… và chuỗi trạng thái cuộc gọi, sau đó ATH để kết thúc.

8) Lỗi thường gặp & cách khắc phục

  • Không có phản hồi AT → Kiểm tra baud, đảo TX/RX, kiểm tra GND chung.
  • Không bật được module → Kiểm tra PWRKEY (cần kéo xuống ~1–2s), hoặc công tắc nguồn.
  • Rớt nguồn khi đính mạng → Nguồn yếu; tăng dòng; thêm tụ 470–1000µF gần module.
  • CSQ = 99 → Không có sóng; đổi vị trí/anten; kiểm tra SIM còn hạn.
  • Không có IP → Cài APN đúng với nhà mạng: AT+CGDCONT=1,"IP","<APN>" rồi attach lại.
  • Gọi không được → Kiểm tra SIM có dịch vụ thoại, chuẩn bị micro/loa nếu thử thoại 2 chiều.

9) Gợi ý mở rộng

  • Tạo Web UI để đọc trạng thái 4G, nhập số điện thoại, bấm gọi/hủy.
  • Gửi SMS (AT+CMGF=1, AT+CMGS="...") để báo trạng thái.
  • Dùng TLS + MQTT của modem để publish dữ liệu (tiết kiệm tài nguyên ESP32).
  • Tự động reconnect nếu CSQ thấp hoặc CEREG mất.

Comments

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *