ESP32 Wifi and Promiscuous mode

Tomerbt
Posts: 3
Joined: Sun Apr 06, 2025 2:17 pm

ESP32 Wifi and Promiscuous mode

Postby Tomerbt » Sun Apr 06, 2025 2:29 pm

I'm working on a project where I need to calculate the RSSI values from a receiver using ESP32. I have two separate codes: one calculates RSSI in promiscuous mode (without WiFi connection) and the other calculates RSSI while connected to a hotspot and Blynk. However, I'm having trouble combining these two methods.

### 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!

Who is online

Users browsing this forum: No registered users and 1 guest