### Problem:
I want the default behavior to be promiscuous mode when the device is not connected to a hotspot. Once the ESP32 connects to a hotspot, it should switch to using ESP-NOW for RSSI calculations. When the device disconnects from the hotspot, it should revert back to promiscuous mode for RSSI calculations.
No matter what I try, I can't seem to combine the two methods effectively.
### Code 1: RSSI in Promiscuous Mode (without Blynk and Hotspot)
Code: Select all
#include <esp_now.h>
#include <WiFi.h>
#include <algorithm>
#include <esp_wifi.h> // Required for promiscuous mode
// ESP-NOW Receiver MAC Address
uint8_t receiverMacAddress[] = {0x20, 0x43, 0xA8, 0x63, 0x35, 0xA8};
// Hardware Pins
#define BUTTON1_PIN 15
#define BUTTON2_PIN 23
#define LED1_PIN 5
#define LED2_PIN 21
// RSSI Settings
#define SAMPLES 30
#define WINDOW_SIZE 5
#define DEAD_BAND_SPEED 0.05
#define MIN_DEADBAND 0.1
#define MAX_DEADBAND 2.0
// Kalman Filter Parameters
const float Q = 0.1; // Process noise
const float R = 1.5; // Measurement noise
struct PacketData {
byte activeButton;
};
struct PacketData2 {
int rssiValue;
};
// Global Variables
float rssiSamples[SAMPLES];
float kalmanFilteredRSSI = 0;
int sampleIndex = 0;
int latestRSSI = 0;
float kalmanRSSI = 0;
float kalmanP = 1;
float prevRSSI = 0;
unsigned long prevTime = 0;
PacketData data;
PacketData2 data2;
bool lastButton1State = false;
bool lastButton2State = false;
bool button1Active = false;
bool button2Active = true; // מערכת כבויה כברירת מחדל
// Enhanced Filtering Functions
float applyMovingAverage(float newValue) {
static float buffer[WINDOW_SIZE] = {0};
static byte index = 0;
static float sum = 0;
sum -= buffer[index];
buffer[index] = newValue;
sum += buffer[index];
index = (index + 1) % WINDOW_SIZE;
return sum / WINDOW_SIZE;
}
float kalmanUpdate(float measurement) {
kalmanP = kalmanP + Q;
float K = kalmanP / (kalmanP + R);
kalmanRSSI = kalmanRSSI + K * (measurement - kalmanRSSI);
kalmanP = (1 - K) * kalmanP;
return kalmanRSSI;
}
float calculateDynamicDeadband() {
float variance = 0;
for(int i=0; i<SAMPLES; i++) {
variance += pow(rssiSamples[i] - kalmanFilteredRSSI, 2);
}
variance /= SAMPLES;
return constrain(DEAD_BAND_SPEED * (1 + variance*0.1), MIN_DEADBAND, MAX_DEADBAND);
}
void updateRSSI() {
// Take burst samples
float burstSamples[5];
for(int i=0; i<5; i++) {
burstSamples[i] = latestRSSI;
delay(2);
}
// Median filter
std::sort(burstSamples, burstSamples+5);
float medianRSSI = burstSamples[2];
// Apply processing chain
float smoothed = applyMovingAverage(medianRSSI);
kalmanFilteredRSSI = kalmanUpdate(smoothed);
}
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;
}
}
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
memcpy(&data2, incomingData, sizeof(data2));
if (data2.rssiValue != 0) {
rssiSamples[sampleIndex] = data2.rssiValue;
sampleIndex = (sampleIndex + 1) % SAMPLES;
updateRSSI();
float dynamicDeadband = calculateDynamicDeadband();
if (abs(kalmanFilteredRSSI - prevRSSI) < dynamicDeadband) {
kalmanFilteredRSSI = prevRSSI;
}
prevTime = millis();
prevRSSI = kalmanFilteredRSSI;
Serial.printf("Raw: %6.2f | Filtered: %6.2f | Deadband: %4.2f\n",
data2.rssiValue, kalmanFilteredRSSI, dynamicDeadband);
}
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
// Initialize hardware
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); // LED2 דלוק כברירת מחדל
// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW Init 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();
}
// Register callbacks
esp_now_register_recv_cb(OnDataRecv);
esp_wifi_set_promiscuous(true);
esp_wifi_set_promiscuous_rx_cb(&promiscuousRxCB);
Serial.println("Transmitter Ready - System OFF (Default)");
}
void loop() {
// Button handling
bool currentButton1State = !digitalRead(BUTTON1_PIN);
if (currentButton1State && !lastButton1State) {
button1Active = true;
button2Active = false;
data.activeButton = 1;
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
Serial.println("🔴 System ON");
}
lastButton1State = currentButton1State;
bool currentButton2State = !digitalRead(BUTTON2_PIN);
if (currentButton2State && !lastButton2State) {
button1Active = false;
button2Active = true;
data.activeButton = 2;
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, HIGH);
Serial.println("🟢 System OFF");
}
lastButton2State = currentButton2State;
// Send data
esp_now_send(receiverMacAddress, (uint8_t *)&data, sizeof(data));
delay(30);
}Code number 2 (Blynk and hotspot on RSSI is good, when Blynk and hotspot off RSSI is bad): (In the comments.
What I Need Help With:
How can I effectively switch between promiscuous mode and ESP-NOW depending on the WiFi connection status?
How can I ensure that the RSSI values are calculated correctly in both modes without interference?
Any suggestions on cleaning up or combining the code better for my use case?
I would really appreciate any help or suggestions!