Browse Source

Support separate conversion start and temperature retrieval to allow for multiple devices to be used simultaneously.

main
David Antliff 8 years ago
parent
commit
dd5455f594
  1. 3
      README.md
  2. 57
      main/ds18b20.c
  3. 33
      main/ds18b20.h
  4. 52
      main/ds18b20_main.c
  5. 31
      main/owb.h

3
README.md

@ -21,6 +21,7 @@ This library includes:
* CRC checks on ROM code and temperature data.
* Programmable temperature measurement resolution (9, 10, 11 or 12-bit resolution).
* Temperature conversion and retrieval.
* Separation of conversion and temperature retrieval to allow for simultaneous conversion across multiple devices.
## Documentation
@ -51,7 +52,7 @@ Parts of this code are based on references provided to the public domain by Maxi
The following features are anticipated but not yet implemented:
* Simultaneous temperature conversion from multiple devices on the same bus - concurrency.
* Concurrency support (multiple tasks accessing devices on the same bus).
* Alarm support.
* EEPROM support.
* Parasitic power support.

57
main/ds18b20.c

@ -360,9 +360,9 @@ DS18B20_RESOLUTION ds18b20_read_resolution(DS18B20_Info * ds18b20_info)
return resolution;
}
float ds18b20_get_temp(const DS18B20_Info * ds18b20_info)
bool ds18b20_convert(const DS18B20_Info * ds18b20_info)
{
float temp = 0.0f;
bool result = false;
if (_is_init(ds18b20_info))
{
OneWireBus * bus = ds18b20_info->bus;
@ -370,10 +370,42 @@ float ds18b20_get_temp(const DS18B20_Info * ds18b20_info)
{
// initiate a temperature measurement
owb_write_byte(bus, DS18B20_FUNCTION_TEMP_CONVERT);
result = true;
}
else
{
ESP_LOGE(TAG, "ds18b20 device not responding");
}
}
return result;
}
// wait at least maximum conversion time
_wait_for_conversion(ds18b20_info->resolution);
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)
{
if (_is_init(ds18b20_info))
{
_wait_for_conversion(ds18b20_info->resolution);
}
}
float ds18b20_read_temp(const DS18B20_Info * ds18b20_info)
{
float temp = 0.0f;
if (_is_init(ds18b20_info))
{
OneWireBus * bus = ds18b20_info->bus;
if (_address_device(ds18b20_info))
{
// read measurement
_address_device(ds18b20_info);
owb_write_byte(bus, DS18B20_FUNCTION_SCRATCHPAD_READ);
@ -411,6 +443,23 @@ float ds18b20_get_temp(const DS18B20_Info * ds18b20_info)
ESP_LOGE(TAG, "ds18b20 device not responding");
}
}
return temp;
}
float ds18b20_convert_and_read_temp(const DS18B20_Info * ds18b20_info)
{
float temp = 0.0f;
if (_is_init(ds18b20_info))
{
if (ds18b20_convert(ds18b20_info))
{
// wait at least maximum conversion time
_wait_for_conversion(ds18b20_info->resolution);
temp = ds18b20_read_temp(ds18b20_info);
}
}
return temp;
}

33
main/ds18b20.h

@ -136,12 +136,39 @@ DS18B20_RESOLUTION ds18b20_read_resolution(DS18B20_Info * ds18b20_info);
OneWireBus_ROMCode ds18b20_read_rom(DS18B20_Info * ds18b20_info);
/**
* @brief Get current temperature from device.
* @brief Start a temperature measurement conversion on a single device.
* @param[in] ds18b20_info Pointer to device info instance.
*/
bool ds18b20_convert(const DS18B20_Info * ds18b20_info);
/**
* @brief Start temperature conversion on all connected devices.
* @param[in] bus Pointer to initialised bus instance.
*/
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.
*/
void ds18b20_wait_for_conversion(const DS18B20_Info * ds18b20_info);
/**
* @brief Read last temperature measurement from device.
*
* This is typically called after ds18b20_start_mass_conversion(), provided enough time
* has elapsed to ensure that all devices have completed their conversions.
* @param[in] ds18b20_info Pointer to device info instance. Must be initialised first.
* @return The current temperature returned by the device, in degrees Celsius.
* @return The measurement value returned by the device, in degrees Celsius.
*/
float ds18b20_get_temp(const DS18B20_Info * ds18b20_info);
float ds18b20_read_temp(const DS18B20_Info * ds18b20_info);
/**
* @brief Convert, wait and read current temperature from device.
* @param[in] ds18b20_info Pointer to device info instance. Must be initialised first.
* @return The measurement value returned by the device, in degrees Celsius.
*/
float ds18b20_convert_and_read_temp(const DS18B20_Info * ds18b20_info);
#ifdef __cplusplus
}

52
main/ds18b20_main.c

@ -72,6 +72,11 @@ void app_main()
found = owb_search_next(owb, &search_state);
}
//uint64_t rom_code = 0x0001162e87ccee28; // pink
//uint64_t rom_code = 0xf402162c6149ee28; // green
//uint64_t rom_code = 0x1502162ca5b2ee28; // orange
//uint64_t rom_code = owb_read_rom(owb);
// known ROM codes (LSB first):
OneWireBus_ROMCode known_device = {
.fields.family = { 0x28 },
@ -82,15 +87,8 @@ void app_main()
owb_string_from_rom_code(known_device, rom_code_s, sizeof(rom_code_s));
printf("Device %s is %s\n", rom_code_s, owb_verify_rom(owb, known_device) ? "present" : "not present");
//uint64_t rom_code = 0x0001162e87ccee28; // pink
//uint64_t rom_code = 0xf402162c6149ee28; // green
//uint64_t rom_code = 0x1502162ca5b2ee28; // orange
//uint64_t rom_code = owb_read_rom(owb);
// Create a DS18B20 device on the 1-Wire bus
#ifdef USE_STATIC
DS18B20_Info ds18b20_info_static; // static allocation
DS18B20_Info * ds18b20_info = &ds18b20_info_static;
DS18B20_Info devices_static[MAX_DEVICES] = {0};
DS18B20_Info * devices[MAX_DEVICES] = {0};
for (int i = 0; i < MAX_DEVICES; ++i)
@ -98,7 +96,6 @@ void app_main()
devices[i] = &(devices_static[i]);
}
#else
DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
DS18B20_Info * devices[MAX_DEVICES] = {0};
#endif
@ -123,21 +120,44 @@ void app_main()
ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION);
}
// read temperatures from all sensors sequentially
while (1)
// // read temperatures from all sensors sequentially
// while (1)
// {
// printf("\nTemperature readings (degrees C):\n");
// for (int i = 0; i < num_devices; ++i)
// {
// float temp = ds18b20_get_temp(devices[i]);
// printf(" %d: %.3f\n", i, temp);
// }
// vTaskDelay(1000 / portTICK_PERIOD_MS);
// }
// read temperatures more efficiently by starting conversions on all devices at the same time
if (num_devices > 0)
{
printf("\nTemperature readings (degrees C):\n");
for (int i = 0; i < num_devices; ++i)
while (1)
{
float temp = ds18b20_get_temp(devices[i]);
printf(" %d: %.3f\n", i, temp);
printf("\nTemperature readings (degrees C):\n");
ds18b20_convert_all(owb);
// we know all devices use the same resolution, so use the first device to determine the delay
ds18b20_wait_for_conversion(devices[0]);
for (int i = 0; i < num_devices; ++i)
{
float temp = ds18b20_read_temp(devices[i]);
printf(" %d: %.3f\n", i, temp);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
#ifndef USE_STATIC
// clean up dynamically allocated data
ds18b20_free(&ds18b20_info);
for (int i = 0; i < num_devices; ++i)
{
ds18b20_free(&devices[i]);
}
owb_free(&owb);
#endif

31
main/owb.h

@ -80,6 +80,20 @@ typedef union
} OneWireBus_ROMCode;
/**
* @brief Represents the state of a device search on the 1-Wire bus.
*
* Pass a pointer to this structure to owb_search_first() and
* owb_search_next() to iterate through detected devices on the bus.
*/
typedef struct
{
OneWireBus_ROMCode rom_code;
int last_discrepancy;
int last_family_discrepancy;
int last_device_flag;
} OneWireBus_SearchState;
/**
* @brief Construct a new 1-Wire bus instance.
* New instance should be initialised before calling other functions.
@ -188,23 +202,6 @@ uint8_t owb_crc8_byte(uint8_t crc, uint8_t data);
*/
uint8_t owb_crc8_bytes(uint8_t crc, const uint8_t * data, size_t len);
// Search API
/**
* @brief Represents the state of a device search on the 1-Wire bus.
*
* Pass a pointer to this structure to owb_search_first() and
* owb_search_next() to iterate through detected devices on the bus.
*/
typedef struct
{
OneWireBus_ROMCode rom_code;
int last_discrepancy;
int last_family_discrepancy;
int last_device_flag;
} OneWireBus_SearchState;
/**
* @brief Locates the first device on the 1-Wire bus, if present.
* @param[in] bus Pointer to initialised bus instance.

Loading…
Cancel
Save