Weird behavior from my ESP32
Posted: Tue Nov 15, 2022 9:46 am
So I'm using two ESP32s. One ESP uses freeRTOS for reading infrared sensor and keeping track of visitor count and one for turning on and off my lamp when the visitor count(s) > 0.
My first ESP works perfectly fine. Every time it detects a change in visitor count, it'll send the data real time to my NodeRED dashboard. My problem is my second ESP won't do anything when my first ESP sent an update and the weird thing is my relay ESP only update its status when I published the data manually from my MQTTX application.
Here's an example:
1st ESP publish 8 to visitor topic--> 2nd ESP wont update anything
Published 8 to visitor topic using MQTTX --> 2nd ESP update its relay status
I've attached my code. Where did I go wrong?
Thank you in advance.
-----------
EDIT: Solved the problem by differentiating MQTT's client name
-----------
Relay ESP
[Codebox]#include <WiFi.h>
#include <PubSubClient.h>
#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";
WiFiClient espClient;
PubSubClient client(espClient);
double lightIntensity = 0;
double averageLightIntensity = 0;
bool wifiIndState = false;
String messageData;
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
wifiIndState = !wifiIndState;
digitalWrite(LED_BUILTIN, wifiIndState);
delay(100);
}
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message);
messageTemp += (char)message;
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
if (String(topic) == "capstoneA16/lampStatus") {
if(messageTemp == "ON"){
digitalWrite(RELAY_PIN, HIGH);
}
else if(messageTemp == "OFF"){
digitalWrite(RELAY_PIN, LOW);
}
}
}
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("capstoneA16/lampStatus");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if(!client.connected()) {
Serial.println("Disconnected");
reconnect();
}
client.loop();
}[/Codebox]
Visitor ESP
My first ESP works perfectly fine. Every time it detects a change in visitor count, it'll send the data real time to my NodeRED dashboard. My problem is my second ESP won't do anything when my first ESP sent an update and the weird thing is my relay ESP only update its status when I published the data manually from my MQTTX application.
Here's an example:
1st ESP publish 8 to visitor topic--> 2nd ESP wont update anything
Published 8 to visitor topic using MQTTX --> 2nd ESP update its relay status
I've attached my code. Where did I go wrong?
Thank you in advance.
-----------
EDIT: Solved the problem by differentiating MQTT's client name
-----------
Relay ESP
[Codebox]#include <WiFi.h>
#include <PubSubClient.h>
#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";
WiFiClient espClient;
PubSubClient client(espClient);
double lightIntensity = 0;
double averageLightIntensity = 0;
bool wifiIndState = false;
String messageData;
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
wifiIndState = !wifiIndState;
digitalWrite(LED_BUILTIN, wifiIndState);
delay(100);
}
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message);
messageTemp += (char)message;
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp32/output, you check if the message is either "on" or "off".
// Changes the output state according to the message
if (String(topic) == "capstoneA16/lampStatus") {
if(messageTemp == "ON"){
digitalWrite(RELAY_PIN, HIGH);
}
else if(messageTemp == "OFF"){
digitalWrite(RELAY_PIN, LOW);
}
}
}
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("capstoneA16/lampStatus");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if(!client.connected()) {
Serial.println("Disconnected");
reconnect();
}
client.loop();
}[/Codebox]
Visitor ESP
Code: Select all
#include <PubSubClient.h>
#include <WiFi.h>
#include <freertos/FreeRTOS.h>
#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() {}