双NodeMCU ESP8266-ESP12E社交距离项目1米范围蜂鸣器触发异常求助
双NodeMCU ESP8266-ESP12E社交距离检测优化方案
问题根因
你当前遇到的蜂鸣器间歇启停、偶发不触发,核心来自三个问题:
- RSSI信号本身存在随机波动,单次采样触发逻辑抗干扰能力极差
- 遍历WiFi列表的逻辑存在缺陷:每遍历到一个非目标SSID就会拉低蜂鸣器电平,哪怕后续遍历到符合条件的目标SSID,也会出现短暂的电平跳变
- 无漏扫兼容逻辑:单次扫描未抓到目标SSID时直接判定为距离超出,实际是2.4G信号遮挡、扫描周期短导致的偶发漏识别
具体优化措施
1. 新增RSSI滑动平均滤波
取最近5次扫描到的目标SSID的RSSI值做平均,过滤随机波动导致的误判。
2. 修正触发逻辑
调整为:遍历完全部WiFi列表后,再统一判断是否存在符合距离要求的目标设备,不要在遍历中途修改蜂鸣器电平。
3. 增加触发滞回区间
取消单阈值判定,设置两级阈值:
- 当平均RSSI > -37dBm时,开启蜂鸣器
- 当平均RSSI < -42dBm时,关闭蜂鸣器
临界区间内保持当前状态,避免阈值附近反复跳变。
4. 优化WiFi扫描参数
启用主动扫描、延长每信道扫描时间,提升目标SSID的检出率,避免漏触发。
5. 硬件适配优化
- 两个设备的板载天线保持同高度、平行放置,避免遮挡
- 蜂鸣器驱动可串联100Ω限流电阻,避免GPIO拉电流不足导致的启停异常
优化后代码
#include <ESP8266WiFi.h> const char* APssid = "Social Distancing"; //设备AP名称 const char* APpassword = "qwertyuiop"; // 滞回阈值设置 const int RSSI_ON_THRESH = -37; // 1米对应开启阈值 const int RSSI_OFF_THRESH = -42; // 关闭阈值 const int FILTER_COUNT = 5; // 滑动平均采样次数 int rssiBuffer[FILTER_COUNT] = {0}; int bufferIndex = 0; bool buzzerState = false; void setup() { WiFi.mode(WIFI_OFF); WiFi.disconnect(); delay(50); Serial.begin(115200); pinMode(14, OUTPUT); digitalWrite(14, LOW); // 初始关闭蜂鸣器 Serial.println(); WiFi.mode(WIFI_AP_STA); Serial.print("Configuring access point..."); WiFi.softAP(APssid, APpassword); Serial.println(WiFi.softAPIP()); } void loop() { Serial.println("Wifi is scanning"); // 主动扫描,每信道扫描120ms,提升检出率 int n = WiFi.scanNetworks(false, true, 0, 120); Serial.println("Wifi scan ended"); bool foundTarget = false; int currentRssi = RSSI_OFF_THRESH - 10; if (n > 0) { for (int i = 0; i < n; ++i) { if(WiFi.SSID(i) == APssid) { currentRssi = WiFi.RSSI(i); foundTarget = true; break; } } } // 更新RSSI滑动缓冲区 if(foundTarget) { rssiBuffer[bufferIndex] = currentRssi; bufferIndex = (bufferIndex + 1) % FILTER_COUNT; } // 计算平均RSSI int avgRssi = 0; int validCount = 0; for(int i=0; i<FILTER_COUNT; i++) { if(rssiBuffer[i] != 0) { avgRssi += rssiBuffer[i]; validCount++; } } if(validCount > 0) { avgRssi /= validCount; } else { avgRssi = RSSI_OFF_THRESH - 10; } // 滞回逻辑判断 if(buzzerState == false) { if(avgRssi > RSSI_ON_THRESH) { buzzerState = true; digitalWrite(14, HIGH); Serial.print("Trigger alert, average RSSI: "); Serial.println(avgRssi); } } else { if(avgRssi < RSSI_OFF_THRESH) { buzzerState = false; digitalWrite(14, LOW); Serial.print("Stop alert, average RSSI: "); Serial.println(avgRssi); } } WiFi.scanDelete(); delay(100); // 调整扫描周期,平衡响应速度和功耗 }
校准说明
如果实际测试1米触发距离不准,可以先把两个设备固定在1米位置,打印连续10次的RSSI值,取平均值作为RSSI_ON_THRESH的数值,滞回区间保持5dBm即可。
内容的提问来源于stack exchange,提问作者Lisa Marie
相关产品推荐
相关产品推荐

