无法将数据发布到我的本地 mqtt 服务器
cannot publish data to my local mqtt server
我希望有人能帮我解决这个问题。几个星期以来我一直在努力,我对此很陌生。
我想将数据从 ESP32 SIM800L 发送到 mqtt 代理。
mqtt服务器在我本地机器上运行,ESP32 SIM800可以完美连接APN。
我看到很多教程使用 WIFI 连接而不是 GPRS(我正在使用的)。
我终于找到了:tinyGSM and this :arduino mqtt mongodb
然后我做了如下调整,还是连接失败:
// Your GPRS credentials (leave empty, if not needed)
const char apn[] = "internet.tn"; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password
// SIM card PIN (leave empty, if not defined)
const char simPIN[] = "";
uint32_t lastReconnectAttempt = 0;
// TTGO T-Call pins
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#include <Wire.h>
#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
// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
const char* broker = "localhost";
const char* topicInit = "GsmClientTest/init";
// Function prototypes
void subscribeReceive(char* topic, byte* payload, unsigned int length);
// TinyGSM Client for Internet connection
// gsm and MQTT related objects
TinyGsmClient client(modem);
PubSubClient mqtt(client);
long mqtttimer = 0; // Timer for counting 5 seconds and retrying mqtt connection
byte mqtttarea = 1;
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 3600 /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */
void mqttCallback(char* topic, byte* payload, unsigned int len) {
SerialMon.print("Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();}
boolean mqttConnect() {
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker
boolean status = mqtt.connect("GsmClientTest");
// Or, if you want to authenticate MQTT:
//boolean status = mqtt.connect("GsmClientName", "mqtt_user", "mqtt_pass");
if (status == false) {
SerialMon.println(" fail");
return false;
}
SerialMon.println(" success");
mqtt.publish(topicInit, "GsmClientTest started");
// mqtt.subscribe(topicLed);
return mqtt.connected();}
void setup() {
SerialMon.begin(9600);
// Start I2C communication
I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
// Set GSM module baud rate and UART pins
SerialAT.begin(9600, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Restart SIM800 module, it takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// use modem.init() if you don't need the complete restart
// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
modem.simUnlock(simPIN);
}
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
}
else {
SerialMon.println(" OK");
}
// MQTT Broker setup
mqtt.setServer(broker, 1883);
mqtt.setCallback(mqttCallback);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
}
void loop() {
// This is needed at the top of the loop!
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.publish(topicInit, "Hello");
mqtt.loop();
}
您将经纪人的名称设置为 localhost
:
const char* broker = "localhost";
localhost
和 IP 地址 127.0.0.1 表示“此代码所在的主机 运行”。当您在 运行 代理计算机上键入命令时,localhost
将表示该计算机。它不可能在 ESP32 上运行。
您需要 运行 经纪人的计算机名称或 IP 地址。您如何找到它取决于您使用的操作系统 运行。
如果该计算机在您的本地网络上,它可能正在使用私有 IP 地址,例如 10.0.1.x
或 192.168.1.x
。如果是这种情况,您将需要在路由器中使用端口转发将数据包转发给它(然后您将使用路由器的 IP 地址,而不是代理的 IP 地址)。
如果您使用的是路由器的 IP 地址,该地址可能会在没有警告的情况下发生变化,因此您需要使用 Dynamic DNS 之类的东西来更新其当前 IP 地址。
您可能会更好地 运行 在 cloud-based 虚拟服务器上使用网络外部的代理,或者使用那里的几种商业 MQTT 服务之一。他们中的大多数都有免费套餐,每月允许合理的流量。
无论如何,localhost
永远不会在这里工作。您需要您经纪人的真实 public IP 地址或名称。
我希望有人能帮我解决这个问题。几个星期以来我一直在努力,我对此很陌生。
我想将数据从 ESP32 SIM800L 发送到 mqtt 代理。 mqtt服务器在我本地机器上运行,ESP32 SIM800可以完美连接APN。 我看到很多教程使用 WIFI 连接而不是 GPRS(我正在使用的)。
我终于找到了:tinyGSM and this :arduino mqtt mongodb
然后我做了如下调整,还是连接失败:
// Your GPRS credentials (leave empty, if not needed)
const char apn[] = "internet.tn"; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password
// SIM card PIN (leave empty, if not defined)
const char simPIN[] = "";
uint32_t lastReconnectAttempt = 0;
// TTGO T-Call pins
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#include <Wire.h>
#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
// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
const char* broker = "localhost";
const char* topicInit = "GsmClientTest/init";
// Function prototypes
void subscribeReceive(char* topic, byte* payload, unsigned int length);
// TinyGSM Client for Internet connection
// gsm and MQTT related objects
TinyGsmClient client(modem);
PubSubClient mqtt(client);
long mqtttimer = 0; // Timer for counting 5 seconds and retrying mqtt connection
byte mqtttarea = 1;
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 3600 /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */
void mqttCallback(char* topic, byte* payload, unsigned int len) {
SerialMon.print("Message arrived [");
SerialMon.print(topic);
SerialMon.print("]: ");
SerialMon.write(payload, len);
SerialMon.println();}
boolean mqttConnect() {
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker
boolean status = mqtt.connect("GsmClientTest");
// Or, if you want to authenticate MQTT:
//boolean status = mqtt.connect("GsmClientName", "mqtt_user", "mqtt_pass");
if (status == false) {
SerialMon.println(" fail");
return false;
}
SerialMon.println(" success");
mqtt.publish(topicInit, "GsmClientTest started");
// mqtt.subscribe(topicLed);
return mqtt.connected();}
void setup() {
SerialMon.begin(9600);
// Start I2C communication
I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
// Set GSM module baud rate and UART pins
SerialAT.begin(9600, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Restart SIM800 module, it takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// use modem.init() if you don't need the complete restart
// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
modem.simUnlock(simPIN);
}
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
}
else {
SerialMon.println(" OK");
}
// MQTT Broker setup
mqtt.setServer(broker, 1883);
mqtt.setCallback(mqttCallback);
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
}
void loop() {
// This is needed at the top of the loop!
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.publish(topicInit, "Hello");
mqtt.loop();
}
您将经纪人的名称设置为 localhost
:
const char* broker = "localhost";
localhost
和 IP 地址 127.0.0.1 表示“此代码所在的主机 运行”。当您在 运行 代理计算机上键入命令时,localhost
将表示该计算机。它不可能在 ESP32 上运行。
您需要 运行 经纪人的计算机名称或 IP 地址。您如何找到它取决于您使用的操作系统 运行。
如果该计算机在您的本地网络上,它可能正在使用私有 IP 地址,例如 10.0.1.x
或 192.168.1.x
。如果是这种情况,您将需要在路由器中使用端口转发将数据包转发给它(然后您将使用路由器的 IP 地址,而不是代理的 IP 地址)。
如果您使用的是路由器的 IP 地址,该地址可能会在没有警告的情况下发生变化,因此您需要使用 Dynamic DNS 之类的东西来更新其当前 IP 地址。
您可能会更好地 运行 在 cloud-based 虚拟服务器上使用网络外部的代理,或者使用那里的几种商业 MQTT 服务之一。他们中的大多数都有免费套餐,每月允许合理的流量。
无论如何,localhost
永远不会在这里工作。您需要您经纪人的真实 public IP 地址或名称。