I'm working on an ESP32-based project with two separate ESP32 modules: one as a transmitter and the other as a receiver. Each ESP32 is mounted on a different breadboard. The transmitter ESP32 has additional components, including a buzzer, an LED, and a servo motor.
I’ve noticed an issue:
- When the ESP32 is connected to WiFi, pressing the physical buttons on the transmitter's breadboard immediately turns the system ON and OFF as expected.
- However, when WiFi is disconnected, it takes multiple button presses before the system actually turns ON or OFF.
I want to define a separate logic for both the transmitter and receiver when they are not connected to WiFi, ensuring that the system responds to button presses correctly without delays.
Has anyone encountered this issue before? What could be causing this delay, and how can I handle button presses properly when WiFi is disconnected?
The reason I’m using WiFi and Blynk is because I want to control the system via an app. Before adding Blynk, the system worked perfectly with the physical buttons, but once I integrated Blynk, the response became extremely delayed when WiFi is not available.
Transmitter
#define BLYNK_TEMPLATE_ID "---"
#define BLYNK_TEMPLATE_NAME "----"
#define BLYNK_AUTH_TOKEN "----"
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <BlynkSimpleEsp32.h>
char ssid[] = "---";
char pass[] = "---";
uint8_t receiverMacAddress[] = {0x20, 0x43, 0xA8, 0x63, 0x35, 0xA8};
#define BUTTON1_PIN 15
#define BUTTON2_PIN 23
#define LED1_PIN 5
#define LED2_PIN 21
#define SAMPLES 30
#define DEAD_BAND_SPEED 0.05
#define DEAD_BAND_DISTANCE 0.05
float rssiSamples[SAMPLES];
float kalmanFilteredRSSI = 0;
int sampleIndex = 0;
volatile int latestRSSI = 0;
float kalmanRSSI = 0;
float kalmanP = 1;
const float Q = 0.5;
const float R = 2.0;
static float prevRSSI = 0;
static unsigned long prevTime = 0;
unsigned long lastRSSIUpdate = 0;
unsigned long lastBlynkUpdate = 0;
unsigned long lastSendAttempt = 0;
struct PacketData {
byte activeButton;
int rssiValue;
};
PacketData data;
bool lastButton1State = false;
bool lastButton2State = false;
bool button1Active = false;
bool button2Active = false;
bool blynkConnected = false;
void promiscuousRxCB(void *buf, wifi_promiscuous_pkt_type_t type) {
if (type == WIFI_PKT_MGMT) {
wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf;
latestRSSI = pkt->rx_ctrl.rssi;
}
}
float kalmanUpdate(float measurement) {
kalmanP = kalmanP + Q;
float K = kalmanP / (kalmanP + R);
kalmanRSSI = kalmanRSSI + K * (measurement - kalmanRSSI);
kalmanP = (1 - K) * kalmanP;
return kalmanRSSI;
}
BLYNK_CONNECTED() {
blynkConnected = true;
Blynk.virtualWrite(V0, button1Active ? 1 : 0);
Blynk.virtualWrite(V1, kalmanFilteredRSSI);
}
BLYNK_DISCONNECTED() {
blynkConnected = false;
}
BLYNK_WRITE(V0) {
int buttonState = param.asInt();
if (buttonState == 1 && !button1Active) {
button1Active = true;
button2Active = false;
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
Serial.println("🔴 System ON (from Blynk)");
sendSystemState();
}
else if (buttonState == 0 && !button2Active) {
button1Active = false;
button2Active = true;
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, HIGH);
Serial.println("🟢 System OFF (from Blynk)");
sendSystemState();
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Connect to WiFi and Blynk
WiFi.begin(ssid, pass);
Blynk.config(BLYNK_AUTH_TOKEN);
Blynk.connect(100);
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("❌ ESP-NOW initialization failed");
ESP.restart();
}
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
memcpy(peerInfo.peer_addr, receiverMacAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("❌ Failed to add peer");
ESP.restart();
}
pinMode(BUTTON1_PIN, INPUT_PULLUP);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, HIGH);
esp_wifi_set_promiscuous(true);
esp_wifi_set_promiscuous_rx_cb(&promiscuousRxCB);
Serial.println("System ready");
}
void sendSystemState() {
if (millis() - lastSendAttempt < 100) return; // Rate limiting
data.activeButton = button1Active ? 1 : 2;
processRSSI();
data.rssiValue = (int)kalmanFilteredRSSI;
esp_err_t result = esp_now_send(receiverMacAddress, (uint8_t *)&data, sizeof(data));
lastSendAttempt = millis();
if (result != ESP_OK) {
Serial.print("❌ Failed to send data (code: ");
Serial.print(result);
Serial.println(")");
// Attempt ESP-NOW reconnection
esp_now_deinit();
if (esp_now_init() != ESP_OK) {
Serial.println("❌ ESP-NOW reinitialization failed");
}
}
}
void processRSSI() {
if (latestRSSI != 0) {
rssiSamples[sampleIndex] = latestRSSI;
sampleIndex = (sampleIndex + 1) % SAMPLES;
float avgRSSI = 0;
for (int i = 0; i < SAMPLES; i++) avgRSSI += rssiSamples[i];
avgRSSI /= SAMPLES;
kalmanFilteredRSSI = kalmanUpdate(avgRSSI);
if (abs(kalmanFilteredRSSI - prevRSSI) < DEAD_BAND_DISTANCE) {
kalmanFilteredRSSI = prevRSSI;
}
unsigned long now = millis();
float deltaT = (now - prevTime) / 1000.0;
float speed = deltaT > 0 ? (kalmanFilteredRSSI - prevRSSI) / deltaT : 0;
prevTime = now;
prevRSSI = kalmanFilteredRSSI;
if (abs(speed) < DEAD_BAND_SPEED) speed = 0.0;
// Print RSSI every second
if (millis() - lastRSSIUpdate >= 1000) {
lastRSSIUpdate = millis();
Serial.print("RSSI: ");
Serial.println(kalmanFilteredRSSI);
}
// Update Blynk every 0.5 seconds
if (blynkConnected && millis() - lastBlynkUpdate >= 500) {
lastBlynkUpdate = millis();
Blynk.virtualWrite(V1, kalmanFilteredRSSI);
}
}
}
void loop() {
Blynk.run();
bool currentButton1State = !digitalRead(BUTTON1_PIN);
if (currentButton1State && !lastButton1State) {
button1Active = true;
button2Active = false;
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
Serial.println("🔴 System ON (from physical button)");
if (blynkConnected) Blynk.virtualWrite(V0, 1);
sendSystemState();
delay(100);
}
lastButton1State = currentButton1State;
bool currentButton2State = !digitalRead(BUTTON2_PIN);
if (currentButton2State && !lastButton2State) {
button1Active = false;
button2Active = true;
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, HIGH);
Serial.println("🟢 System OFF (from physical button)");
if (blynkConnected) Blynk.virtualWrite(V0, 0);
sendSystemState();
delay(100);
}
lastButton2State = currentButton2State;
if (!blynkConnected && WiFi.status() == WL_CONNECTED) {
Blynk.connect(3000);
}
processRSSI();
delay(30);
}
Reciver
#include <ESP32Servo.h>
#include <esp_now.h>
#include <WiFi.h>
uint8_t transmitterMacAddress[] = {0x20, 0x43, 0xA8, 0x63, 0x62, 0x2C}; // Replace with actual transmitter MAC address
#define SERVO_PIN 26
#define RED_LED_PIN 32
#define GREEN_LED_PIN 25
#define BUZZER_PIN 27
Servo servo;
bool systemActive = false;
bool buzzerActive = false;
unsigned long lastBuzzerTime = 0;
int buzzerFreq = 1000;
bool increasing = true;
struct PacketData {
byte activeButton;
};
PacketData receivedData;
// Updated function signature
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
memcpy(&receivedData, incomingData, sizeof(receivedData));
Serial.println(receivedData.activeButton);
Serial.print("Button state: ");
if (receivedData.activeButton == 1 && !systemActive) {
activateSystem();
Serial.println("Activating system");
} else if (receivedData.activeButton == 2 && systemActive) {
deactivateSystem();
Serial.println("Deactivating system");
}
}
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initial state - system off
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
noTone(BUZZER_PIN);
// Initialize WiFi
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
ESP.restart();
}
// Add peer
esp_now_peer_info_t peerInfo;
memset(&peerInfo, 0, sizeof(peerInfo));
memcpy(peerInfo.peer_addr, transmitterMacAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
ESP.restart();
}
// Register callback with updated signature
esp_now_register_recv_cb(OnDataRecv);
// Initialize servo
servo.attach(SERVO_PIN);
servo.write(90);
delay(200);
servo.detach();
Serial.println("Receiver ready");
}
void activateSystem() {
systemActive = true;
servo.attach(SERVO_PIN);
servo.write(180);
delay(500);
servo.detach();
digitalWrite(RED_LED_PIN, HIGH);
digitalWrite(GREEN_LED_PIN, LOW);
buzzerActive = true;
}
void deactivateSystem() {
systemActive = false;
servo.attach(SERVO_PIN);
servo.write(0);
delay(500);
servo.detach();
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
buzzerActive = false;
noTone(BUZZER_PIN);
}
void loop() {
updateSiren();
delay(30);
}
void updateSiren() {
if (buzzerActive) {
unsigned long currentMillis = millis();
if (currentMillis - lastBuzzerTime >= 50) {
lastBuzzerTime = currentMillis;
buzzerFreq += increasing ? 100 : -100;
if (buzzerFreq >= 3000) increasing = false;
if (buzzerFreq <= 1000) increasing = true;
tone(BUZZER_PIN, buzzerFreq);
}
} else {
noTone(BUZZER_PIN);
}
}