Hướng Dẫn Kết Nối ESP32 SIM7600 A7680 A7682 với MQTT
Giới Thiệu
Đây là dự án kết nối module SIM7600 4G với ESP32 để giao tiếp qua giao thức MQTT, cho phép thiết bị IoT của bạn gửi/nhận dữ liệu từ xa thông qua mạng di động.
Tính Năng
- Kết nối Internet qua mạng 4G (GPRS)
- Giao tiếp với MQTT Broker (HiveMQ)
- Điều khiển LED từ xa qua MQTT
- Tự động gửi message test mỗi 30 giây
- Tự động kết nối lại khi mất kết nối
- Hiển thị thông tin chi tiết trên Serial Monitor
Phần Cứng Cần Thiết
- Mạch ESP32 Modbus RTU RS485 ISOLATED ZenoRTU0106
- SIM 4G có data
- Nguồn cấp đủ cho module (khuyến nghị 24V/1A)
Cài Đặt Thư Viện
Mở Arduino IDE → Tools → Manage Libraries, tìm và cài đặt:
- TinyGSM by Volodymyr Shymanskyy
- PubSubClient by Nick O'Leary
Cấu Hình Code
Chỉnh sửa các thông số sau trong code:
const char apn[] = "v-internet"; // APN của nhà mạng
APN phổ biến tại Việt Nam:
Viettel: v-internet hoặc e-connect
Mobifone: m-wap
Vinaphone: m3-world/**************************************************************
* ESP32 + SIM7600 MQTT Test
* Pinout:
* - MODEM_RX: GPIO 27
* - MODEM_TX: GPIO 26
* - MODEM_RESET: GPIO 25
* - LED: GPIO 2
**************************************************************/
#define TINY_GSM_MODEM_SIM7600
// Set serial for debug console
#define SerialMon Serial
// Set serial for AT commands
#define SerialAT Serial2
// See all AT commands
#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG SerialMon
// GPRS credentials
const char apn[] = "v-internet"; // Thay bằng APN của nhà mạng bạn
const char gprsUser[] = "";
const char gprsPass[] = "";
// MQTT details
const char* broker = "broker.hivemq.com";
const char* topicLed = "zenopcb/led";
const char* topicInit = "zenopcb/init";
const char* topicLedStatus = "zenopcb/ledStatus";
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
PubSubClient mqtt(client);
// Pin definitions
#define MODEM_RX 27
#define MODEM_TX 26
#define MODEM_RESET_PIN 25
#define LED_PIN 2
int ledStatus = LOW;
uint32_t lastReconnectAttempt = 0;
void mqttCallback(char* topic, byte* payload, unsigned int len) {
SerialMon.print("Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();
// Toggle LED when message received
if (String(topic) == topicLed) {
ledStatus = !ledStatus;
digitalWrite(LED_PIN, ledStatus);
mqtt.publish(topicLedStatus, ledStatus ? "1" : "0");
}
}
boolean mqttConnect() {
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker
boolean status = mqtt.connect("GsmClientTest");
if (status == false) {
SerialMon.println(" fail");
return false;
}
SerialMon.println(" success");
mqtt.publish(topicInit, "GsmClientTest started");
mqtt.subscribe(topicLed);
return mqtt.connected();
}
void modemHardwareReset() {
pinMode(MODEM_RESET_PIN, OUTPUT);
digitalWrite(MODEM_RESET_PIN, HIGH);
delay(50);
SerialMon.println("Resetting modem...");
digitalWrite(MODEM_RESET_PIN, LOW);
delay(1000);
digitalWrite(MODEM_RESET_PIN, HIGH);
SerialMon.println("Waiting for modem to boot...");
delay(10000);
}
void setup() {
// Set LED pin
pinMode(LED_PIN, OUTPUT);
pinMode(MODEM_RX,INPUT_PULLUP);
digitalWrite(LED_PIN, LOW);
// Set console baud rate
SerialMon.begin(115200);
delay(1000);
SerialMon.println("\n\n========================================");
SerialMon.println("ESP32 + SIM7600 MQTT Test");
SerialMon.println("========================================\n");
// Hardware reset modem
modemHardwareReset();
// Set modem serial
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Clear serial buffer
while (SerialAT.available()) {
SerialAT.read();
}
SerialMon.println("Initializing modem...");
modem.restart();
String modemInfo = modem.getModemInfo();
SerialMon.print("Modem Info: ");
SerialMon.println(modemInfo);
SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork(60000L)) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isNetworkConnected()) {
SerialMon.println("Network connected");
}
// Check signal quality
int csq = modem.getSignalQuality();
SerialMon.print("Signal quality: ");
SerialMon.println(csq);
// GPRS connection
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
// Get IP address
IPAddress local = modem.localIP();
SerialMon.print("Local IP: ");
SerialMon.println(local);
// MQTT Broker setup
mqtt.setServer(broker, 1883);
mqtt.setCallback(mqttCallback);
SerialMon.println("\n========================================");
SerialMon.println("Setup complete!");
SerialMon.println("========================================\n");
}
void loop() {
// Check network connection
if (!modem.isNetworkConnected()) {
SerialMon.println("Network disconnected");
if (!modem.waitForNetwork(180000L, true)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isNetworkConnected()) {
SerialMon.println("Network re-connected");
}
// Check GPRS connection
if (!modem.isGprsConnected()) {
SerialMon.println("GPRS disconnected!");
SerialMon.print("Connecting to ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isGprsConnected()) {
SerialMon.println("GPRS reconnected");
}
}
}
// Check MQTT connection
if (!mqtt.connected()) {
SerialMon.println("=== MQTT NOT CONNECTED ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 10000L) {
lastReconnectAttempt = t;
if (mqttConnect()) {
lastReconnectAttempt = 0;
}
}
delay(100);
return;
}
// MQTT loop
mqtt.loop();
// Publish test message every 30 seconds
static uint32_t lastPublish = 0;
if (millis() - lastPublish > 30000) {
lastPublish = millis();
String msg = "ZENOPCB ESP32 - Uptime: ";
msg += millis() / 1000;
msg += "s";
SerialMon.print("Publishing: ");
SerialMon.println(msg);
mqtt.publish(topicInit, msg.c_str());
}
}Với các Topic mẫu trong Code hiện tại của tôi
Topic: zenopcb/init
-> Thiết bị sẽ tự gửi Uptime thời gian online của thiết bị lên sau mỗi 30sTopic: zenopcb/ledStatus
-> Thiết bị sẽ gửi trạng thái của LED 0 1Topic Publish: zenopcb/led
-> Gửi toggle đến thiết bị để đổi trạng thái LED từ Bật sáng Tắt và ngược lại

