From 1c58f41b091805772b8aa4f30170b6860a058765 Mon Sep 17 00:00:00 2001 From: David Antliff Date: Sun, 6 Aug 2017 11:50:34 +1200 Subject: [PATCH] Sample temperature from multiple devices approximately once per second. --- main/ds18b20.c | 16 ++++++++++------ main/ds18b20.h | 6 +++++- main/ds18b20_main.c | 23 ++++++++++++++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/main/ds18b20.c b/main/ds18b20.c index f05fe04..b84a0ad 100644 --- a/main/ds18b20.c +++ b/main/ds18b20.c @@ -144,8 +144,9 @@ static bool _check_resolution(DS18B20_RESOLUTION resolution) return (resolution >= DS18B20_RESOLUTION_9_BIT) && (resolution <= DS18B20_RESOLUTION_12_BIT); } -static void _wait_for_conversion(DS18B20_RESOLUTION resolution) +static float _wait_for_conversion(DS18B20_RESOLUTION resolution) { + float elapsed_time = 0.0f; if (_check_resolution(resolution)) { int divisor = 1 << (DS18B20_RESOLUTION_12_BIT - resolution); @@ -156,7 +157,11 @@ static void _wait_for_conversion(DS18B20_RESOLUTION resolution) // wait at least this maximum conversion time vTaskDelay(ticks); + + // TODO: measure elapsed time more accurately + elapsed_time = ticks * portTICK_PERIOD_MS; } + return elapsed_time; } static float _decode_temp(uint8_t lsb, uint8_t msb, DS18B20_RESOLUTION resolution) @@ -385,17 +390,16 @@ void ds18b20_convert_all(const OneWireBus * bus) owb_reset(bus); owb_write_byte(bus, OWB_ROM_SKIP); owb_write_byte(bus, DS18B20_FUNCTION_TEMP_CONVERT); - - // wait the maximum conversion duration - _wait_for_conversion(DS18B20_RESOLUTION_12_BIT); } -void ds18b20_wait_for_conversion(const DS18B20_Info * ds18b20_info) +float ds18b20_wait_for_conversion(const DS18B20_Info * ds18b20_info) { + float elapsed_time = 0.0f; if (_is_init(ds18b20_info)) { - _wait_for_conversion(ds18b20_info->resolution); + elapsed_time = _wait_for_conversion(ds18b20_info->resolution); } + return elapsed_time; } float ds18b20_read_temp(const DS18B20_Info * ds18b20_info) diff --git a/main/ds18b20.h b/main/ds18b20.h index 76dd47a..e6f0163 100644 --- a/main/ds18b20.h +++ b/main/ds18b20.h @@ -143,6 +143,9 @@ bool ds18b20_convert(const DS18B20_Info * ds18b20_info); /** * @brief Start temperature conversion on all connected devices. + * + * This should be followed by a sufficient delay to ensure all devices complete + * their conversion before the measurements are read. * @param[in] bus Pointer to initialised bus instance. */ void ds18b20_convert_all(const OneWireBus * bus); @@ -150,8 +153,9 @@ void ds18b20_convert_all(const OneWireBus * bus); /** * @brief Wait for the maximum conversion time according to the current resolution of the device. * @param[in] bus Pointer to initialised bus instance. + * @return An estimate of the time elapsed, in milliseconds. Actual elapsed time may be greater. */ -void ds18b20_wait_for_conversion(const DS18B20_Info * ds18b20_info); +float ds18b20_wait_for_conversion(const DS18B20_Info * ds18b20_info); /** * @brief Read last temperature measurement from device. diff --git a/main/ds18b20_main.c b/main/ds18b20_main.c index e8615e2..892e5ef 100644 --- a/main/ds18b20_main.c +++ b/main/ds18b20_main.c @@ -137,18 +137,31 @@ void app_main() { while (1) { - printf("\nTemperature readings (degrees C):\n"); + TickType_t start_ticks = xTaskGetTickCount(); + ds18b20_convert_all(owb); - // we know all devices use the same resolution, so use the first device to determine the delay + // in this application all devices use the same resolution, + // so use the first device to determine the delay ds18b20_wait_for_conversion(devices[0]); + // read the results immediately after conversion otherwise it may fail + // (using printf before reading may take too long) + float temps[MAX_DEVICES] = { 0 }; + for (int i = 0; i < num_devices; ++i) + { + temps[i] = ds18b20_read_temp(devices[i]); + } + + // print results in a separate loop, after all have been read + printf("\nTemperature readings (degrees C):\n"); for (int i = 0; i < num_devices; ++i) { - float temp = ds18b20_read_temp(devices[i]); - printf(" %d: %.3f\n", i, temp); + printf(" %d: %.3f\n", i, temps[i]); } - vTaskDelay(1000 / portTICK_PERIOD_MS); + + // make up delay to approximately 1 second per measurement + vTaskDelay(1000 / portTICK_PERIOD_MS - (xTaskGetTickCount() - start_ticks)); } }