所以我使用了两个 ESP32。一个 ESP 使用 freeRTOS 来读取红外传感器并跟踪访客人数,一个用于在访客人数 > 0 时打开和关闭我的灯。
我的第一个 ESP 工作得很好。每次它检测到访问者数量的变化时,它都会将数据实时发送到我的 NodeRED 仪表板。我的问题是,当我的第一个 ESP 发送更新时,我的第二个 ESP 不会做任何事情,奇怪的是,我的中继 ESP 仅在我从 MQTTX 应用程序手动发布数据时更新其状态。
这是一个示例:
第一个 ESP 将 8 发布到访问者主题--> 第二个 ESP 不会使用 MQTTX 更新任何
已发布 8 到访问者主题--> 第二个 ESP 更新其中继状态
我附上了我的代码。我哪里做错了?
编辑:通过区分 MQTT 的客户端名称解决了问题
Relay ESP
[Codebox]#include
#include
#define LDR_PIN 36 //LDR pada pin A0
#define RELAY_PIN 32
const char* ssid = "suastuti_3";
const char* pass = "notaristutiek";
const char* mqtt_server = "192.168.1.4";
WiFi客户端espClient;
PubSubClient客户端(espClient);
双光强度= 0;
双平均光强 = 0;
bool wifiIndState = false;
字符串消息数据;
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
引脚模式(LED_BUILTIN,输出);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(回调);
}
void setup_wifi() {
延迟(10);
// 我们首先连接到 WiFi 网络
Serial.println();
Serial.print("连接到");
序列号.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
wifiIndState = !wifiIndState;
数字写入(LED_BUILTIN,wifiIndState);
延迟(100);
}
digitalWrite(LED_BUILTIN, HIGH);
序列号.println("");
Serial.println("WiFi 已连接");
Serial.println("IP地址:");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("消息到达主题:");
Serial.print(主题);
Serial.print(". 消息:");
字符串消息温度;
对于 (int i = 0; i < length; i++) {
Serial.print((char)message );
messageTemp += (char) 消息;
}
Serial.println();
// 随意添加更多 if 语句以使用 MQTT 控制更多 GPIO
// 如果在主题 esp32/output 上收到消息,则检查消息是“打开”还是“关闭”。
if (String(topic) == "capstoneA16/lampStatus") {
if(messageTemp == "ON"){
digitalWrite(RELAY_PIN, HIGH);
}
else if(messageTemp == "OFF"){
digitalWrite(RELAY_PIN, LOW);
}
}
}
void reconnect() {
// 循环直到我们重新连接
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// 尝试连接
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// 订阅
client.subscribe("capstoneA16/lampStatus");
} else {
Serial.print("
Serial.print(client.state());
Serial.println("5秒后重试");
// 重试前等待 5 秒
delay(5000);
}
}
}
void loop() {
if(!client.connected()) {
Serial.println("断开连接");
重新连接();
}
客户端循环();
}[/Codebox]
访客ESP
代码:全选
#include
#include
#include
#define OUTER_PIR_PIN 34
#define INNER_PIR_PIN 35
#define WIFI_SSID "suastuti_3"
#define WIFI_PASS "notaristutiek"
#define MQTT_BROKER "192.168.1.4"
#define MQTT_PORT 1883
#define MQTT_TOPIC "capstoneA16/visitor"
int outerPirState = 0;
int innerPirState = 0;
unsigned int outerPirTime = 0;
unsigned int innerPirTime = 0;
unsigned int lastOuterPirTime = 0;
unsigned int lastInnerPirTime = 0;
unsigned int visitorCount = 0;
unsigned int lastVisitorCount = 0;
bool wifiIndState = false;
WiFiClient espClient;
PubSubClient client(espClient);
void handleOuterPir(void *parameters) {
for (;;) {
outerPirState = digitalRead(OUTER_PIR_PIN);
if (!outerPirState) {
Serial.println("Motion detected on OUTER SENSOR");
outerPirTime = millis();
outerPirState = 1;
vTaskDelay(500);
}
}
}
void handleInnerPir(void *parameters) {
for (;;) {
innerPirState = digitalRead(INNER_PIR_PIN);
// Serial.println(innerPirState);
if (!innerPirState) {
Serial.println("Motion detected on INNER SENSOR");
innerPirTime = millis();
innerPirState = 1;
vTaskDelay(500);
}
}
}
void handleVisitorCount(void *parameters) {
for (;;) {
Serial.print("");
if (innerPirTime != 0 && outerPirTime != 0) {
int visitorState = innerPirTime - outerPirTime;
if (visitorState > 0) {
visitorCount++;
Serial.print("Visitor count: ");
Serial.println(visitorCount);
Serial.println("Visitor in");
} else {
if (visitorCount > 0) {
visitorCount--;
Serial.print("Visitor count: ");
Serial.println(visitorCount);
Serial.println("Visitor out");
}
}
vTaskDelay(500);
innerPirTime = 0;
outerPirTime = 0;
}
}
}
void publishToTopic(void *parameters) {
for (;;) {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
if (lastVisitorCount != visitorCount) {
while (!client.connected()) {
reconnect();
}
}
Serial.println("connected");
}
}
if (lastVisitorCount != visitorCount) {
while (!client.connected()) {
reconnect();
}
char msg_out[20];
sprintf(msg_out, "%d", visitorCount);
client.publish("capstoneA16/visitor", msg_out);
// vTaskDelay(1000);
Serial.println("Published");
lastVisitorCount = visitorCount;
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Subscribe
client.subscribe("esp32/output");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
vTaskDelay(500);
}
}
}
void callback(char *topic, byte *message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
pinMode(OUTER_PIR_PIN, INPUT);
pinMode(INNER_PIR_PIN, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
//
// pinMode(OUTER_PIR_PIN, INPUT);
// pinMode(INNER_PIR_PIN, INPUT);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
wifiIndState = !wifiIndState;
digitalWrite(LED_BUILTIN, wifiIndState);
delay(100);
}
digitalWrite(LED_BUILTIN, HIGH);
client.setServer(MQTT_BROKER, MQTT_PORT);
client.setCallback(callback);
xTaskCreatePinnedToCore(handleOuterPir, "Handle outside sensor", 1000, NULL,
1, NULL, 1);
xTaskCreatePinnedToCore(handleInnerPir, "Handle inside sensor", 1000, NULL, 1,
NULL, 1);
xTaskCreatePinnedToCore(handleVisitorCount, "Handle visitor", 1000, NULL, 1,
NULL, 1);
xTaskCreatePinnedToCore(publishToTopic, "Send data to mqtt", 5000, NULL, 1,
NULL, 1);
}
void loop() {}