Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add temperature compensation to ultrasonic distance measurements #619

Merged
merged 1 commit into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions components/ultrasonic/ultrasonic.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define PING_TIMEOUT 6000
#define ROUNDTRIP_M 5800.0f
#define ROUNDTRIP_CM 58
#define SPEED_OF_SOUND_AT_0C_M_S 331.4 // Speed of sound in m/s at 0 degrees Celsius

#if HELPER_TARGET_IS_ESP32
static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
Expand Down Expand Up @@ -141,3 +142,35 @@ esp_err_t ultrasonic_measure_cm(const ultrasonic_sensor_t *dev, uint32_t max_dis

return ESP_OK;
}

esp_err_t ultrasonic_measure_temp_compensated(const ultrasonic_sensor_t *dev, float max_distance, float *distance, float temperature_c)
{
CHECK_ARG(dev && distance);

// Calculate the speed of sound in m/us based on temperature
float speed_of_sound = (SPEED_OF_SOUND_AT_0C_M_S + 0.6 * temperature_c) / 1000000; // Convert m/s to m/us

uint32_t time_us;
// Adjust max_time_us based on the recalculated speed of sound
CHECK(ultrasonic_measure_raw(dev, max_distance / speed_of_sound, &time_us));
// Calculate distance using the temperature-compensated speed of sound
*distance = time_us * speed_of_sound;

return ESP_OK;
}

esp_err_t ultrasonic_measure_cm_temp_compensated(const ultrasonic_sensor_t *dev, uint32_t max_distance, uint32_t *distance, float temperature_c)
{
CHECK_ARG(dev && distance);

// Calculate the speed of sound in cm/us based on temperature
float speed_of_sound_cm_us = ((SPEED_OF_SOUND_AT_0C_M_S + 0.6 * temperature_c) * 100) / 1000000; // Convert m/s to cm/us

uint32_t time_us;
// Adjust max_time_us based on the recalculated speed of sound in cm
CHECK(ultrasonic_measure_raw(dev, max_distance * 100 / speed_of_sound_cm_us, &time_us));
// Calculate distance using the temperature-compensated speed of sound, converting result to cm
*distance = time_us * speed_of_sound_cm_us;

return ESP_OK;
}
35 changes: 35 additions & 0 deletions components/ultrasonic/ultrasonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,41 @@ esp_err_t ultrasonic_measure(const ultrasonic_sensor_t *dev, float max_distance,
*/
esp_err_t ultrasonic_measure_cm(const ultrasonic_sensor_t *dev, uint32_t max_distance, uint32_t *distance);

/**
* @brief Measure distance in meters with temperature compensation
*
* This function measures the distance by taking into account the temperature of the air,
* which affects the speed of sound. This method improves the accuracy of measurements
* in various environmental conditions.
*
* @param dev Pointer to the device descriptor
* @param max_distance Maximal distance to measure, meters
* @param[out] distance Distance in meters
* @param temperature_c Current air temperature in degrees Celsius
* @return `ESP_OK` on success, otherwise:
* - ::ESP_ERR_ULTRASONIC_PING - Invalid state (previous ping is not ended)
* - ::ESP_ERR_ULTRASONIC_PING_TIMEOUT - Device is not responding
* - ::ESP_ERR_ULTRASONIC_ECHO_TIMEOUT - Distance is too big or wave is scattered
*/
esp_err_t ultrasonic_measure_temp_compensated(const ultrasonic_sensor_t *dev, float max_distance, float *distance, float temperature_c);

/**
* @brief Measure distance in centimeters with temperature compensation
*
* Similar to ultrasonic_measure_temp_compensated but provides the distance in centimeters.
* It factors in the temperature of the air for more accurate measurements across a range of environmental conditions.
*
* @param dev Pointer to the device descriptor
* @param max_distance Maximal distance to measure, centimeters
* @param[out] distance Distance in centimeters
* @param temperature_c Current air temperature in degrees Celsius
* @return `ESP_OK` on success, otherwise:
* - ::ESP_ERR_ULTRASONIC_PING - Invalid state (previous ping is not ended)
* - ::ESP_ERR_ULTRASONIC_PING_TIMEOUT - Device is not responding
* - ::ESP_ERR_ULTRASONIC_ECHO_TIMEOUT - Distance is too big or wave is scattered
*/
esp_err_t ultrasonic_measure_cm_temp_compensated(const ultrasonic_sensor_t *dev, uint32_t max_distance, uint32_t *distance, float temperature_c);

#ifdef __cplusplus
}
#endif
Expand Down
Loading