I'm working on an ESP32-based project that estimates distance using RSSI. My setup consists of two ESP32 modules: one is stationary and continuously transmits signals, while the other is mobile and measures the received signal strength (RSSI). When the RSSI drops below a certain threshold for 3 seconds, an alarm system (LED, buzzer, and servo motor) activates. If the RSSI remains strong for 3 seconds, the system deactivates.
Here’s my main issue:
- RSSI fluctuations are quite high, even when the distance remains the same.
- The signal is affected by obstacles and reflections, making it unreliable.
- I’m using ESP-NOW for communication and also tried promiscuous mode to capture packets directly.
My questions:
- How can I make the RSSI measurements more stable? Would filtering techniques like an average filter or Kalman filter help?
- Are there any alternative methods to estimate distance more accurately using ESP32?
- I’m considering using the NEO-6M GPS module alongside RSSI. Would this improve distance estimation?
- Is it possible to combine both RSSI-based estimation and GPS data for better accuracy? If so, how?
reciver code
#include <ESP32Servo.h>
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#define SERVO_PIN 26
#define RED_LED_PIN 33
#define GREEN_LED_PIN 25
#define BUZZER_PIN 27
Servo servo;
bool systemActive = false;
int RSSI_THRESHOLD = -58;
volatile int latestRSSI = 0;
unsigned long weakSignalStartTime = 0; // Timer for weak signal detection
unsigned long strongSignalStartTime = 0; // Timer for strong signal detection
const unsigned long triggerDelay = 3000; // 3-second delay
bool buzzerActive = false;
unsigned long lastBuzzerTime = 0;
int buzzerFreq = 1000;
bool increasing = true;
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 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);
}
}
void activateSystem() {
Serial.println("🔴 System Activated!");
systemActive = true;
servo.attach(SERVO_PIN);
servo.write(180);
delay(300);
digitalWrite(RED_LED_PIN, HIGH);
digitalWrite(GREEN_LED_PIN, LOW);
buzzerActive = true;
}
void deactivateSystem() {
Serial.println("🟢 System Deactivated!");
systemActive = false;
servo.write(0);
delay(300);
servo.detach();
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
buzzerActive = false;
}
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
Serial.print("📡 RSSI: ");
Serial.println(latestRSSI);
if (latestRSSI < RSSI_THRESHOLD) {
Serial.println("📉 Weak signal detected!");
if (weakSignalStartTime == 0) {
weakSignalStartTime = millis();
Serial.println("⏳ Starting 3-second timer for activation...");
}
strongSignalStartTime = 0; // Reset the deactivation timer
if (!systemActive && (millis() - weakSignalStartTime >= triggerDelay)) {
Serial.println("🚨 Weak signal for 3 seconds! Activating system...");
activateSystem();
}
} else {
Serial.println("📶 Strong signal detected!");
if (strongSignalStartTime == 0) {
strongSignalStartTime = millis();
Serial.println("⏳ Starting 3-second timer for deactivation...");
}
weakSignalStartTime = 0; // Reset the activation timer
if (systemActive && (millis() - strongSignalStartTime >= triggerDelay)) {
Serial.println("✅ Strong signal for 3 seconds! Deactivating system...");
deactivateSystem();
}
}
}
void setup() {
Serial.begin(115200);
Serial.println("📡 Initializing ESP32...");
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
if (esp_now_init() != ESP_OK) {
Serial.println("❌ ESP-NOW initialization failed!");
return;
}
Serial.println("✅ ESP-NOW initialized successfully.");
esp_now_register_recv_cb(OnDataRecv);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);
noTone(BUZZER_PIN);
servo.attach(SERVO_PIN);
delay(200);
servo.write(0);
delay(500);
servo.detach();
esp_wifi_set_promiscuous(true);
esp_wifi_set_promiscuous_rx_cb(&promiscuousRxCB);
Serial.println("🚀 System is ready!");
}
void loop() {
updateSiren();
}
transmitter code
#include <esp_now.h>
#include <WiFi.h>
uint8_t receiverMacAddress[] = {0x20, 0x43, 0xA8, 0x63, 0x35, 0xA8}; // Update with the receiver's MAC address
struct PacketData {
byte switch1Value;
};
PacketData data;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("🔵 Packet Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "✅ Success" : "❌ Failure");
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("❌ ESP-NOW initialization failed!");
return;
}
Serial.println("✅ ESP-NOW initialized successfully.");
esp_now_register_send_cb(OnDataSent);
esp_now_peer_info_t 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.");
return;
}
Serial.println("✅ Peer added successfully.");
}
void loop() {
data.switch1Value = 1;
esp_err_t result = esp_now_send(receiverMacAddress, (uint8_t *)&data, sizeof(data));
if (result == ESP_OK) {
Serial.println("📡 Packet sent successfully.");
} else {
Serial.println("❌ Error sending packet.");
}
delay(1000);
}