如何使用 Wi-Fi RSSI 精确计算距离?

问题描述

我有一个暑期练习项目,我需要一些 ESP-32S 板来告诉我我离这些板有多远(以米为单位)以及我在哪个区域(我有一个 WPF划分为 8 个不同的区域)。事情是我永远无法让它们精确到一半......这是我的奴隶代码

#include <common.h>
#include <FirebaseESP32.h>
#include <FirebaseFS.h>
#include <Utils.h>
#include <WiFi.h>

 

#define FIREBASE_HOST "keylessgps-default-rtdb.europe-west1.firebasedatabase.app" 
#define FIREBASE_AUTH "..."

 

// Enter your WiFi SSID and password
char ssid[] = "POCO X3 Pro";             
char pass[] = "12345678";    
int keyIndex = 0;                      // your network key Index number (needed only for WEP)

 

int status = WL_IDLE_STATUS;
FirebaseData firebaseData;

 

WiFiClient client;

 


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

 


  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);

 

  Firebase.begin(FIREBASE_HOST,FIREBASE_AUTH);

 

  WiFi.begin(ssid,pass);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println("");
  Serial.println("Connected to WiFi");
  }

 

void loop() {
 printWifiStatus();
}
void printWifiStatus() {
  int nrSamples=100;
  int values[nrSamples];
  int RSSi=0;
  int sum=0;
  for(int i=0;i<nrSamples;i++)
  {
    values[i]=WiFi.RSSI();
    sum+=values[i];
  }
  float mean=(float)(sum/nrSamples);
  int nr=nrSamples;
  for(int i=0;i<nrSamples;i++)
    if(abs(values[i]-mean)>7)
    {
      sum-=values[i];
      nr--;
    }
  RSSi=sum/nr;
  
  float ratio=(float)(-50 - RSSi)/20;
  float distance=pow(9.2,ratio);
  Serial.println("RSSi:");
  Serial.println(RSSi);
  Serial.println("distance:");
  Serial.println(distance);
  Firebase.setFloat(firebaseData,"distance2",distance);
  
  delay(1200);
   
}

这是主人的代码

#include <common.h>
#include <FirebaseESP32.h>
#include <FirebaseFS.h>
#include <Utils.h>
#include <WiFi.h>

 


#define FIREBASE_HOST "keylessgps-default-rtdb.europe-west1.firebasedatabase.app" 
#define FIREBASE_AUTH "hL2QBdcYXphHE0NI4AdquTqddPowOtwmbf2C8w1G"

 

// Enter your WiFi SSID and password
char ssid[] = "Oppo";             // your network SSID (name)
char pass[] = "prlsepupa";    // your network password (use for WPA,or use as key for WEP)
int keyIndex = 0;   
float distance1,distance2,distance3,distance4;

 

int status = WL_IDLE_STATUS;

 

FirebaseData firebaseData;

 

WiFiClient client;

 


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

 


  // attempt to connect to Wifi network:
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);

 

  Firebase.begin(FIREBASE_HOST,pass);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println("");
  Serial.println("Connected to WiFi");
  
  }

 

void loop() {
 printWifiStatus();
}

 


void printWifiStatus() {
  Firebase.getFloat(firebaseData,"distance1",distance1);
  Firebase.getFloat(firebaseData,distance2);
  Firebase.getFloat(firebaseData,"distance3",distance3);
  Firebase.getFloat(firebaseData,"distance4",distance4);
  
  std::vector<std::pair <char*,int>> pillars;
  
  pillars.push_back(std::pair<char*,int>("Pillar1",distance1));
  pillars.push_back(std::pair<char*,int>("Pillar2",distance2));
  pillars.push_back(std::pair<char*,int>("Pillar3",distance3));
  pillars.push_back(std::pair<char*,int>("Pillar4",distance4));
  
  for(int i=0;i<3;i++)
    for(int j=i+1;j<=3;j++)
      if(pillars[i].second>pillars[j].second)
         {
          std::pair<char*,int>aux=pillars[i];
          pillars[i]=pillars[j];
          pillars[j]=aux;
         }
  Serial.println(pillars[0].second);
  Serial.println(pillars[1].second);

 

  if((pillars[0].first=="Pillar1" && pillars[1].first=="Pillar2")||(pillars[1].first=="Pillar1" && pillars[0].first=="Pillar2"))
    {
      float mini=min(distance1,distance2);
      float x=(float)((distance1*distance1-distance2*distance2+1)/2);
      float y=sqrt(abs(mini*mini-x*x));
      
      Serial.println(distance1);
      Serial.println(distance2);
      Serial.println(x);
      Serial.println(y);
      Serial.println("");
      Firebase.setFloat(firebaseData,"Data/FrontRear",1);
      int side=0;
      if(x<0.3)
        side=0;
      if(x>0.7)
        side=1;
      if(x>=0.3 && x<=0.7)
        side=2;
      Firebase.setFloat(firebaseData,"Data/LeftRight",side);

 

    }
  if((pillars[0].first=="Pillar3" && pillars[1].first=="Pillar2")||(pillars[1].first=="Pillar3" && pillars[0].first=="Pillar2"))
  {
    Firebase.setFloat(firebaseData,2);
    Firebase.setFloat(firebaseData,1);
  }

 

  if((pillars[0].first=="Pillar1" && pillars[1].first=="Pillar4")||(pillars[1].first=="Pillar1" && pillars[0].first=="Pillar4"))
  {
    Firebase.setFloat(firebaseData,0);
  }

 

  if((pillars[0].first=="Pillar3" && pillars[1].first=="Pillar4")||(pillars[1].first=="Pillar3" && pillars[0].first=="Pillar4"))
  {
      float mini=min(distance3,distance4);
      float x=(float)((distance3*distance3-distance4*distance4+1)/2);
      float y=sqrt(abs(mini*mini-x*x));
      
      Serial.println(distance3);
      Serial.println(distance4);
      Serial.println(x);
      Serial.println(y);
      Serial.println("");
      Firebase.setFloat(firebaseData,0);
      int side=0;
      if(x<0.3)
        side=1;
      if(x>0.7)
        side=0;
      if(x>=0.3 && x<=0.7)
        side=2;
      Firebase.setFloat(firebaseData,side);
  }

 

   
}

总共有4个奴隶。我正在使用一种三角测量方法在这方法中,我看到哪个是最接近的 2 个奴隶,并且它们的轴变成了 Ox,然后,我尝试计算到该轴的距离。距离本身与我无关,但我需要计算区域。另外,有没有一种方法/合成器我可以使用,这样除非所有 4 个从站都连接到 firebase,否则主站不会开始执行它的工作?因为有时在更新 4 个奴隶的​​距离之间会有延迟,实际上大多数时候,它会变得很糟糕并且非常不稳定。任何帮助给我一个更好的公式来计算距离或重组我的代码,以便我的项目可以变得更加精确,我们将非常感激。抱歉我的英语不好,非常感谢你!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)