Is this the approach you recommended (assuming those zero wind distances)?
// Calibrated zero-wind distances for each sensor (in meters)
const float CalibratedDist1 = 0.2781275;
const float CalibratedDist2 = 0.265827;
// Function to calculate wind speed using the calibrated distances
float calculateWindSpeed(float d1, float d2, long t1, long t2) {
// Wind speed formula:
// (d1*1e6/t1 - d2*1e6/t2) / 2
return (d1 * 1e6 / t1 - d2 * 1e6 / t2) / 2;
}
void loop() {
// Measure the time for the pulse from sensor 1 to sensor 2
digitalWrite(TriggerPin, LOW);
delayMicroseconds(2);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
Duration1 = pulseIn(EchoPin2, HIGH); // Capture time on sensor 2
// Wait before reactivating
delay(50);
// Measure the time for the pulse from sensor 2 to sensor 1 AFTER the first measurement
digitalWrite(TriggerPin, LOW);
delayMicroseconds(2);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
Duration2 = pulseIn(EchoPin1, HIGH); // Capture time on sensor 1
// Calculate wind speed using the calibrated distances
float windSpeed = calculateWindSpeed(CalibratedDist1, CalibratedDist2, Duration1, Duration2);
}
Gives the following average outputs:
Sensor 1 Distance = 14.195 cm
Sensor 2 Distance = 13.209 cm
Time Difference = 58 microseconds
---------------------------
Sensor 1 Distance = 14.280 cm
Sensor 2 Distance = 13.226 cm
Time Difference = 62 microseconds
---------------------------
Sensor 1 Distance = 14.212 cm
Sensor 2 Distance = 13.209 cm
Time Difference = 59 microseconds
---------------------------
Sensor 1 Distance = 14.212 cm
Sensor 2 Distance = 13.226 cm
Time Difference = 58 microseconds
---------------------------
Which gives values a bit better than the previous ones i had with the same triggers, but still not the ones I'm aiming (not sure why, since i think that line of thought is definitely correct, i might have messed up somewhere). The altered code to get this is as follows:
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// Wi-Fi credentials
const char WIFI_SSID[] = "TESTE"; // Wi-Fi name
const char WIFI_PASSWORD[] = "TESTE"; // Wi-Fi password
// Variables synchronized with the Arduino IoT Cloud
float temperature;
float humidity;
float pressure;
float windSpeed;
float windDirection;
String beaufortCategory;
// Configuration of ultrasonic sensor pins
const int TriggerPin = 9; // Single trigger pin for both sensors
const int EchoPin1 = 10;
const int EchoPin2 = 12;
// Variables to store the time measured by the ultrasonic sensors
long Duration1 = 0;
long Duration2 = 0;
// Distance between sensors (in meters)
const float DistanceBetweenSensors = 0.3; // 30 cm
// Calibrated distances (zero-wind) for each sensor (in meters)
// Calculated from the speed of sound (341.68 m/s) and measured times
// DistTo1 = 341.68 m/s * 0.000814 s = 0.2781275 m
// DistTo2 = 341.68 m/s * 0.000778 s = 0.265827 m
const float CalibratedDist1 = 0.2781275;
const float CalibratedDist2 = 0.265827;
// I2C address for the BME280 sensor
#define BME280_ADDRESS 0x76
// Create an object for the BME280 sensor
Adafruit_BME280 bme;
// Function to calculate the speed of sound using the thermodynamic formula
float calculateThermodynamicSoundSpeed(float temperature) {
const float gamma = 1.4; // Ratio of specific heats for dry air
const float R = 8.314; // Universal gas constant [J/(mol·K)]
const float M = 0.0289644; // Molar mass of dry air [kg/mol]
// Convert temperature from Celsius to Kelvin
float temperatureK = temperature + 273.15;
// Apply the thermodynamic formula
return sqrt((gamma * R * temperatureK) / M);
}
// Function to calculate the wind speed using the calibrated distances
float calculateWindSpeed(float d1, float d2, long t1, long t2) {
// Wind speed formula:
// (d1*1e6/t1 - d2*1e6/t2) / 2
return (d1 * 1e6 / t1 - d2 * 1e6 / t2) / 2;
}
// Function to classify wind speed based on the Beaufort scale
String beaufortScale(float windSpeed) {
// Treat negative and positive values equally (abs)
if (abs(windSpeed) < 0.3) return "Calm";
if (abs(windSpeed) < 1.6) return "Very Light Breeze";
if (abs(windSpeed) < 3.4) return "Light Breeze";
if (abs(windSpeed) < 5.5) return "Gentle Breeze";
if (abs(windSpeed) < 7.9) return "Moderate Breeze";
if (abs(windSpeed) < 10.7) return "Strong Breeze";
if (abs(windSpeed) < 13.8) return "Fresh Wind";
if (abs(windSpeed) < 17.1) return "Gale";
if (abs(windSpeed) < 20.7) return "Strong Gale";
if (abs(windSpeed) < 24.4) return "Storm";
if (abs(windSpeed) < 28.4) return "Violent Storm";
return "Hurricane";
}
// Initialize variables in the IoT Cloud
void initProperties() {
ArduinoCloud.addProperty(temperature, READ, 1 * SECONDS, NULL);
ArduinoCloud.addProperty(humidity, READ, 1 * SECONDS, NULL);
ArduinoCloud.addProperty(pressure, READ, 1 * SECONDS, NULL);
ArduinoCloud.addProperty(windSpeed, READ, 1 * SECONDS, NULL);
ArduinoCloud.addProperty(beaufortCategory, READ, 1 * SECONDS, NULL);
}
// Configure the connection handler
WiFiConnectionHandler ArduinoIoTPreferredConnection(WIFI_SSID, WIFI_PASSWORD);
void setup() {
// Initialize serial communication
Serial.begin(9600);
while (!Serial);
// Configure ultrasonic sensor pins
pinMode(TriggerPin, OUTPUT);
pinMode(EchoPin1, INPUT);
pinMode(EchoPin2, INPUT);
// Initialize the BME280 sensor
if (!bme.begin(BME280_ADDRESS)) {
Serial.println("Failed to initialize the BME280 sensor. Check the connections.");
while (1); // Error case
}
// Initialize the IoT Cloud
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
Serial.println("Setup complete!");
}
void loop() {
// Update the IoT Cloud
ArduinoCloud.update();
// First activation: measure the time to travel from sensor 1 to sensor 2
digitalWrite(TriggerPin, LOW);
delayMicroseconds(2);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
Duration1 = pulseIn(EchoPin2, HIGH); // Capture time at sensor 2
// Wait before reactivating
delay(50);
// Second activation: measure the time to travel from sensor 2 to sensor 1
digitalWrite(TriggerPin, LOW);
delayMicroseconds(2);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
Duration2 = pulseIn(EchoPin1, HIGH); // Capture time at sensor 1
// Use fixed distance between sensors (0.3 meters / 30 cm)
float Distance1_cm = DistanceBetweenSensors * 100.0; // 0.3 meters to cm
float Distance2_cm = DistanceBetweenSensors * 100.0; // 0.3 meters to cm
// Readings from the BME280 sensor
temperature = bme.readTemperature();
humidity = bme.readHumidity();
pressure = bme.readPressure() / 100.0F;
// Calculate the speed of sound using the thermodynamic formula
float soundSpeedThermodynamic = calculateThermodynamicSoundSpeed(temperature);
// Calculate the wind speed using the calibrated distances
windSpeed = calculateWindSpeed(CalibratedDist1, CalibratedDist2, Duration1, Duration2);
// Adjust to ignore sensor fluctuations
if (windSpeed > -0.196 && windSpeed < 1.297) {
windSpeed = 0; // Natural fluctuation, treat as 0
} else if (windSpeed <= -0.196) {
windSpeed += 0.196; // Compensate for the lower limit
} else if (windSpeed >= 1.297) {
windSpeed -= 1.297; // Compensate for the upper limit
}
// Classify the wind speed on the Beaufort scale
beaufortCategory = beaufortScale(windSpeed);
// Display the results as in the original code
Serial.print("Sensor 1 Distance = ");
Serial.print(Distance1_cm, 3);
Serial.println(" cm");
Serial.print("Sensor 2 Distance = ");
Serial.print(Distance2_cm, 3);
Serial.println(" cm");
// Calculate and display the time difference between the sensors
long TimeDifference = Duration1 - Duration2;
Serial.print("Time Difference = ");
Serial.print(TimeDifference);
Serial.println(" microseconds");
// Display BME280 sensor readings
Serial.print("Temp: ");
Serial.print(temperature);
Serial.print(" °C | Hum: ");
Serial.print(humidity);
Serial.print(" % | Press: ");
Serial.print(pressure);
Serial.println(" hPa");
// Display sound speed
Serial.print("Sound Speed (Thermodynamic): ");
Serial.print(soundSpeedThermodynamic);
Serial.println(" m/s");
// Display wind speed
Serial.print("Wind Speed: ");
Serial.print(windSpeed);
Serial.print(" m/s (");
Serial.print(beaufortCategory);
Serial.println(")");
Serial.println("---------------------------");
delay(3000);
}