Ошибка чтения скорости ветра из esp32

Мне нужна ваша помощь в решении проблемы. Я собрал метеостанцию. В этом проекте использовалась плата ESP32. Я использовал датчик Холла с магнитом в модуле измерения скорости ветра (анемометр). Раньше я использовал метод, когда датчик Холла регистрировал 20 импульсов магнита, он отсчитывал время для 20 импульсов и выводил среднюю скорость ветра. Код работал нормально с платой ESP32. Но для большей точности я изменил метод. Теперь метод заключается в том, что в течение 20 секунд количество импульсов магнита, зарегистрированных в течение 20 секунд, будет выводиться как средняя скорость ветра. С тех пор показания скорости ветра не отображаются на последовательном мониторе. (У меня есть часть кода, отвечающая за скорость ветра, написанная для Arduino Uno, и она отлично работает с обоими методами). Скетч Arduino представлен ниже. Единственное изменение, которое я внес в два метода, это

if (revolutions>=20) { было изменено на if ((millis()-timeold)==30000) {

    //Define all libraries in here....

#include<FirebaseESP32.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include "DHT.h"

#define FIREBASE_HOST "https://digital-weather-station-default-rtdb.firebaseio.com/"
#define FIREBASE_AUTH "jbqMg4BPxhCTTicMJAXXvV3LiuFW85PZVb8e8GZY"

const char *ssid = "SVITIN-70A0";
const char *password = "10237684";
String D;

#define DHTPIN 4     
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define Offset 0;

// Connect pin 1 (on the left) of the sensor to GROUND 
// Connect pin 2 of the sensor to +3.3V
// Connect pin 3 (on the right) of the sensor to whatever your DHTPIN is

DHT dht(DHTPIN, DHTTYPE);

FirebaseData firebaseData;

//Variables For Humidity & Temperature
float h=0;  //Define Humidity value Default Value = 0
float t=0;  //Define Temp value in celcius Default Value = 0

//Variables For Wind Speed
volatile byte revolutions;
float rpmilli;
float Speed;
unsigned long timeold=0;

//Variables For Wind Direction
int VaneValue;// raw analog value from wind vane
int Direction;// translated 0 - 360 direction
int CalDirection;// converted value with offset applied
int LastValue;



//Defined new void funtion for get temp and hum...
void Temp(){
   // Wait a two seconds between measurements.
  delay(2000); // Reading temperature or humidity takes about 250 milliseconds!
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

 
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  

  if (Firebase.pushFloat(firebaseData, "/Weather Results/Temperature",t))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }

  if (Firebase.pushFloat(firebaseData, "/Weather Results/Humidity",h))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
 }
 else
 {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
  }


void WSpeed(){
    // if (revolutions>=20) {
   if ((millis ()-timeold)==30000) { 
    //Update RPM every 30 seconds, increase this for better RPM resolution,
    //decrease for faster update

    // calculate the revolutions per milli(second)
    rpmilli = ((float)revolutions)/(millis()-timeold);

    timeold = millis();
    revolutions = 0;

    // WHEELCIRC = 2 * PI * radius (in meters)
    // speed = rpmilli * WHEELCIRC * "milliseconds per hour" / "meters per kilometer"

    // simplify the equation to reduce the number of floating point operations
    // speed = rpmilli * WHEELCIRC * 3600000 / 1000
    // speed = rpmilli * WHEELCIRC * 3600

    Speed = rpmilli * 0.7665 * 3600;

    Serial.print("RPM:");
    Serial.print(rpmilli * 60000);
    Serial.print(" Speed:");
    Serial.print(Speed);
    Serial.println(" kmph");
    
  if (Firebase.pushFloat(firebaseData, "/Weather Results/Speed",Speed))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
  }
}

  void rpm_fun()
{
  revolutions++;
}

void WDirection(){
VaneValue = analogRead(34);
Direction = map(VaneValue, 0, 4095, 0, 360);
CalDirection = Direction + Offset;

// Only update serial monitor if change greater than 5 degrees.
if(abs(CalDirection - LastValue) > 1){
Serial.print(VaneValue); Serial.print("\t\t");
Serial.print(CalDirection); Serial.print("\t\t");
getHeading(CalDirection);
LastValue = CalDirection;
}
  }

// Converts compass direction to heading
void getHeading(int Direction) {
if(Direction < 35){
Serial.println("N");
 D="N";
}

else if (Direction < 100){
 Serial.println("NE");
 D = "NE" ;
}

else if (Direction < 170){
  Serial.println("E");
  D = "E" ;
  }

else if (Direction < 200 ){
  Serial.println("SE");
  D = "SE" ;
  }

else if (Direction < 210){
  Serial.println("S");
  D = "S" ;
  }

else if (Direction < 245){
  Serial.println("SW");
  D = "SW" ; 
  }

else if (Direction < 259){
  Serial.println("W");
  D = "W" ; 
  }

else if (Direction < 268){
  Serial.println("NW");
  D = "NW" ; 
  }

else
Serial.println();

if (Firebase.pushString(firebaseData, "/Weather Results/Wind Direction",D))
  {
    Serial.println("PASSED");
    Serial.println("PATH: " + firebaseData.dataPath());
    Serial.println("TYPE: " + firebaseData.dataType());
    Serial.println("ETag: " + firebaseData.ETag());
    Serial.println("------------------------------------");
    Serial.println();
  }
  else
  {
    Serial.println("FAILED");
    Serial.println("REASON: " + firebaseData.errorReason());
    Serial.println("------------------------------------");
    Serial.println();
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println(F("DHTxx test!"));
  dht.begin();                                                               //DHT and TEMP sensor starting.....
  attachInterrupt(digitalPinToInterrupt(27), rpm_fun, RISING);                // Attaching Interrupt funtion for wind speed....
  revolutions = 0;
  rpmilli = 0;
  timeold = 0;
  LastValue = 1;
  Serial.println("Vane Value\tDirection\tHeading");

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  Firebase.reconnectWiFi(true);
}



void loop() {
  Temp();
  delay(2000);
  WSpeed();
 delay(2000);
  WDirection();
 delay(2000);
  }

, 👍2

Обсуждение

проблема, вероятно, в == ... подумайте об этом, @jsotola


1 ответ


1

Если millis()-timeold не равен точно 30000 миллисекунд, вы указываете на сбой. Значение оборотов, ваш предыдущий успешный параметр для использования, не так точно, и вы использовали фильтр >= вместо фильтра равенства (==). Таким образом, вы не так легко указали на сбой. И вы не можете исправить ситуацию, заново присваивая 'timeold'.

Еще одно наблюдение заключается в том, что вы уже выполнили выборку для millis()-timeold один раз; нет смысла делать ее еще раз через несколько строк, и вполне может получиться небольшой, но другой результат.

Решение: вычислить millis()-timeold один раз, возможно, сохранить результат как unsigned long и сравнивать по принципу >=, а не ==. Это позволит избежать задержек с выполнением условия и получать очень частые отчёты о скорости ветра. Наконец, я бы инициализировал в setup() значение timeold = millis() и не равным нулю.

,