esp32-warm-water
esp32 based project for the control of a heating element based on temperature
ds18b20.c
Go to the documentation of this file.
1 /*
2  * MIT License
3  *
4  * Copyright (c) 2017-2019 David Antliff
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
34 #include <stddef.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include <stdint.h>
39 #include <math.h>
40 
41 #include "freertos/FreeRTOS.h"
42 #include "freertos/task.h"
43 #include "driver/gpio.h"
44 #include "esp_system.h"
45 #include "esp_log.h"
46 
47 #include "ds18b20.h"
48 #include "owb.h"
49 
50 static const char *TAG = CONFIG_TEMP_TAG;
51 static const int T_CONV = 750;
52 
53 // Function commands
54 #define DS18B20_FUNCTION_TEMP_CONVERT 0x44
55 #define DS18B20_FUNCTION_SCRATCHPAD_WRITE 0x4E
56 #define DS18B20_FUNCTION_SCRATCHPAD_READ 0xBE
57 #define DS18B20_FUNCTION_SCRATCHPAD_COPY 0x48
58 #define DS18B20_FUNCTION_EEPROM_RECALL 0xB8
59 #define DS18B20_FUNCTION_POWER_SUPPLY_READ 0xB4
60 
62 typedef struct
63 {
64  uint8_t temperature[2]; // [0] is LSB, [1] is MSB
65  uint8_t trigger_high;
66  uint8_t trigger_low;
67  uint8_t configuration;
68  uint8_t reserved[3];
69  uint8_t crc;
70 } __attribute__((packed)) Scratchpad;
72 
73 static void _init(DS18B20_Info *ds18b20_info, const OneWireBus *bus)
74 {
75  if (ds18b20_info != NULL)
76  {
77  ds18b20_info->bus = bus;
78  memset(&ds18b20_info->rom_code, 0, sizeof(ds18b20_info->rom_code));
79  ds18b20_info->use_crc = false;
80  ds18b20_info->resolution = DS18B20_RESOLUTION_INVALID;
81  ds18b20_info->solo = false; // assume multiple devices unless told otherwise
82  ds18b20_info->init = true;
83  }
84  else
85  {
86  ESP_LOGE(TAG, "ds18b20_info is NULL");
87  }
88 }
89 
90 static bool _is_init(const DS18B20_Info *ds18b20_info)
91 {
92  bool ok = false;
93  if (ds18b20_info != NULL)
94  {
95  if (ds18b20_info->init)
96  {
97  // OK
98  ok = true;
99  }
100  else
101  {
102  ESP_LOGE(TAG, "ds18b20_info is not initialised");
103  }
104  }
105  else
106  {
107  ESP_LOGE(TAG, "ds18b20_info is NULL");
108  }
109  return ok;
110 }
111 
112 static bool _address_device(const DS18B20_Info *ds18b20_info)
113 {
114  bool present = false;
115  if (_is_init(ds18b20_info))
116  {
117  owb_reset(ds18b20_info->bus, &present);
118  if (present)
119  {
120  if (ds18b20_info->solo)
121  {
122  // if there's only one device on the bus, we can skip
123  // sending the ROM code and instruct it directly
124  owb_write_byte(ds18b20_info->bus, OWB_ROM_SKIP);
125  }
126  else
127  {
128  // if there are multiple devices on the bus, a Match ROM command
129  // must be issued to address a specific slave
130  owb_write_byte(ds18b20_info->bus, OWB_ROM_MATCH);
131  owb_write_rom_code(ds18b20_info->bus, ds18b20_info->rom_code);
132  }
133  }
134  else
135  {
136  ESP_LOGE(TAG, "ds18b20 device not responding");
137  }
138  }
139  return present;
140 }
141 
142 static bool _check_resolution(DS18B20_RESOLUTION resolution)
143 {
144  return (resolution >= DS18B20_RESOLUTION_9_BIT) && (resolution <= DS18B20_RESOLUTION_12_BIT);
145 }
146 
147 static float _wait_for_duration(DS18B20_RESOLUTION resolution)
148 {
149  int64_t start_time = esp_timer_get_time();
150  if (_check_resolution(resolution))
151  {
152  int divisor = 1 << (DS18B20_RESOLUTION_12_BIT - resolution);
153  ESP_LOGD(TAG, "divisor %d", divisor);
154  float max_conversion_time = (float)T_CONV / (float)divisor;
155  int ticks = ceil(max_conversion_time / portTICK_PERIOD_MS);
156  ESP_LOGD(TAG, "wait for conversion: %.3f ms, %d ticks", max_conversion_time, ticks);
157 
158  // wait at least this maximum conversion time
159  vTaskDelay(ticks);
160  }
161  int64_t end_time = esp_timer_get_time();
162  return (float)(end_time - start_time) / 1000000.0f;
163 }
164 
165 static float _wait_for_device_signal(const DS18B20_Info *ds18b20_info)
166 {
167  float elapsed_time = 0.0f;
168  if (_check_resolution(ds18b20_info->resolution))
169  {
170  int divisor = 1 << (DS18B20_RESOLUTION_12_BIT - ds18b20_info->resolution);
171 
172  // allow for 10% overtime
173  float max_conversion_time = (float)T_CONV / (float)divisor * 1.1;
174  int max_conversion_ticks = ceil(max_conversion_time / portTICK_PERIOD_MS);
175  ESP_LOGD(TAG, "wait for conversion: max %.0f ms, %d ticks", max_conversion_time, max_conversion_ticks);
176 
177  // wait for conversion to complete - all devices will pull bus low once complete
178  TickType_t start_ticks = xTaskGetTickCount();
179  TickType_t duration_ticks = 0;
180  uint8_t status = 0;
181  do
182  {
183  vTaskDelay(1);
184  owb_read_bit(ds18b20_info->bus, &status);
185  duration_ticks = xTaskGetTickCount() - start_ticks;
186  } while (status == 0 && duration_ticks < max_conversion_ticks);
187 
188  elapsed_time = duration_ticks * portTICK_PERIOD_MS;
189  if (duration_ticks >= max_conversion_ticks)
190  {
191  ESP_LOGW(TAG, "conversion timed out");
192  }
193  else
194  {
195  ESP_LOGD(TAG, "conversion took at most %.0f ms", elapsed_time);
196  }
197  }
198  return elapsed_time;
199 }
200 
201 static float _decode_temp(uint8_t lsb, uint8_t msb, DS18B20_RESOLUTION resolution)
202 {
203  float result = 0.0f;
204  if (_check_resolution(resolution))
205  {
206  // masks to remove undefined bits from result
207  static const uint8_t lsb_mask[4] = {~0x07, ~0x03, ~0x01, ~0x00};
208  uint8_t lsb_masked = lsb_mask[resolution - DS18B20_RESOLUTION_9_BIT] & lsb;
209  int16_t raw = (msb << 8) | lsb_masked;
210  result = raw / 16.0f;
211  }
212  else
213  {
214  ESP_LOGE(TAG, "Unsupported resolution %d", resolution);
215  }
216  return result;
217 }
218 
219 static size_t _min(size_t x, size_t y)
220 {
221  return x > y ? y : x;
222 }
223 
224 static DS18B20_ERROR _read_scratchpad(const DS18B20_Info *ds18b20_info, Scratchpad *scratchpad, size_t count)
225 {
226  // If CRC is enabled, regardless of count, read the entire scratchpad and verify the CRC,
227  // otherwise read up to the scratchpad size, or count, whichever is smaller.
228 
229  if (!scratchpad)
230  {
231  return DS18B20_ERROR_NULL;
232  }
233 
235 
236  if (ds18b20_info->use_crc)
237  {
238  count = sizeof(Scratchpad);
239  }
240  count = _min(sizeof(Scratchpad), count); // avoid reading past end of scratchpad
241 
242  ESP_LOGD(TAG, "scratchpad read: CRC %d, count %d", ds18b20_info->use_crc, count);
243  if (_address_device(ds18b20_info))
244  {
245  // read scratchpad
247  {
248  if (owb_read_bytes(ds18b20_info->bus, (uint8_t *)scratchpad, count) == OWB_STATUS_OK)
249  {
250  ESP_LOG_BUFFER_HEX_LEVEL(TAG, scratchpad, count, ESP_LOG_DEBUG);
251 
252  err = DS18B20_OK;
253  if (!ds18b20_info->use_crc)
254  {
255  // Without CRC, or partial read:
256  ESP_LOGD(TAG, "No CRC check");
257  bool is_present = false;
258  owb_reset(ds18b20_info->bus, &is_present); // terminate early
259  }
260  else
261  {
262  // With CRC:
263  if (owb_crc8_bytes(0, (uint8_t *)scratchpad, sizeof(*scratchpad)) != 0)
264  {
265  ESP_LOGE(TAG, "CRC failed");
266  err = DS18B20_ERROR_CRC;
267  }
268  else
269  {
270  ESP_LOGD(TAG, "CRC ok");
271  }
272  }
273  }
274  else
275  {
276  ESP_LOGE(TAG, "owb_read_bytes failed");
277  err = DS18B20_ERROR_OWB;
278  }
279  }
280  else
281  {
282  ESP_LOGE(TAG, "owb_write_byte failed");
283  err = DS18B20_ERROR_OWB;
284  }
285  }
286  else
287  {
288  err = DS18B20_ERROR_DEVICE;
289  }
290  return err;
291 }
292 
293 static bool _write_scratchpad(const DS18B20_Info *ds18b20_info, const Scratchpad *scratchpad, bool verify)
294 {
295  bool result = false;
296  // Only bytes 2, 3 and 4 (trigger and configuration) can be written.
297  // All three bytes MUST be written before the next reset to avoid corruption.
298  if (_is_init(ds18b20_info))
299  {
300  if (_address_device(ds18b20_info))
301  {
302  ESP_LOGD(TAG, "scratchpad write 3 bytes:");
303  ESP_LOG_BUFFER_HEX_LEVEL(TAG, &scratchpad->trigger_high, 3, ESP_LOG_DEBUG);
305  owb_write_bytes(ds18b20_info->bus, (uint8_t *)&scratchpad->trigger_high, 3);
306  result = true;
307 
308  if (verify)
309  {
310  Scratchpad read = {0};
311  if (_read_scratchpad(ds18b20_info, &read, offsetof(Scratchpad, configuration) + 1) == DS18B20_OK)
312  {
313  if (memcmp(&scratchpad->trigger_high, &read.trigger_high, 3) != 0)
314  {
315  ESP_LOGE(TAG, "scratchpad verify failed: "
316  "wrote {0x%02x, 0x%02x, 0x%02x}, "
317  "read {0x%02x, 0x%02x, 0x%02x}",
318  scratchpad->trigger_high, scratchpad->trigger_low, scratchpad->configuration,
319  read.trigger_high, read.trigger_low, read.configuration);
320  result = false;
321  }
322  }
323  else
324  {
325  ESP_LOGE(TAG, "read scratchpad failed");
326  result = false;
327  }
328  }
329  }
330  }
331  return result;
332 }
333 
334 // Public API
335 
337 {
338  DS18B20_Info *ds18b20_info = malloc(sizeof(*ds18b20_info));
339  if (ds18b20_info != NULL)
340  {
341  memset(ds18b20_info, 0, sizeof(*ds18b20_info));
342  ESP_LOGD(TAG, "malloc %p", ds18b20_info);
343  }
344  else
345  {
346  ESP_LOGE(TAG, "malloc failed");
347  }
348 
349  return ds18b20_info;
350 }
351 
352 void ds18b20_free(DS18B20_Info **ds18b20_info)
353 {
354  if (ds18b20_info != NULL && (*ds18b20_info != NULL))
355  {
356  ESP_LOGD(TAG, "free %p", *ds18b20_info);
357  free(*ds18b20_info);
358  *ds18b20_info = NULL;
359  }
360 }
361 
362 void ds18b20_init(DS18B20_Info *ds18b20_info, const OneWireBus *bus, OneWireBus_ROMCode rom_code)
363 {
364  if (ds18b20_info != NULL)
365  {
366  _init(ds18b20_info, bus);
367  ds18b20_info->rom_code = rom_code;
368 
369  // read current resolution from device as it may not be power-on or factory default
370  ds18b20_info->resolution = ds18b20_read_resolution(ds18b20_info);
371  }
372  else
373  {
374  ESP_LOGE(TAG, "ds18b20_info is NULL");
375  }
376 }
377 
378 void ds18b20_init_solo(DS18B20_Info *ds18b20_info, const OneWireBus *bus)
379 {
380  if (ds18b20_info != NULL)
381  {
382  _init(ds18b20_info, bus);
383  ds18b20_info->solo = true;
384  // ROM code not required
385 
386  // read current resolution from device as it may not be power-on or factory default
387  ds18b20_info->resolution = ds18b20_read_resolution(ds18b20_info);
388  }
389  else
390  {
391  ESP_LOGE(TAG, "ds18b20_info is NULL");
392  }
393 }
394 
395 void ds18b20_use_crc(DS18B20_Info *ds18b20_info, bool use_crc)
396 {
397  if (_is_init(ds18b20_info))
398  {
399  ds18b20_info->use_crc = use_crc;
400  ESP_LOGD(TAG, "use_crc %d", ds18b20_info->use_crc);
401  }
402 }
403 
405 {
406  bool result = false;
407  if (_is_init(ds18b20_info))
408  {
409  if (_check_resolution(ds18b20_info->resolution))
410  {
411  // read scratchpad up to and including configuration register
412  Scratchpad scratchpad = {0};
413  _read_scratchpad(ds18b20_info, &scratchpad,
414  offsetof(Scratchpad, configuration) - offsetof(Scratchpad, temperature) + 1);
415 
416  // modify configuration register to set resolution
417  uint8_t value = (((resolution - 1) & 0x03) << 5) | 0x1f;
418  scratchpad.configuration = value;
419  ESP_LOGD(TAG, "configuration value 0x%02x", value);
420 
421  // write bytes 2, 3 and 4 of scratchpad
422  result = _write_scratchpad(ds18b20_info, &scratchpad, /* verify */ true);
423  if (result)
424  {
425  ds18b20_info->resolution = resolution;
426  ESP_LOGD(TAG, "Resolution set to %d bits", (int)resolution);
427  }
428  else
429  {
430  // Resolution change failed - update the info resolution with the value read from configuration
431  ds18b20_info->resolution = ds18b20_read_resolution(ds18b20_info);
432  ESP_LOGW(TAG, "Resolution consistency lost - refreshed from device: %d", ds18b20_info->resolution);
433  }
434  }
435  else
436  {
437  ESP_LOGE(TAG, "Unsupported resolution %d", resolution);
438  }
439  }
440  return result;
441 }
442 
444 {
446  if (_is_init(ds18b20_info))
447  {
448  // read scratchpad up to and including configuration register
449  Scratchpad scratchpad = {0};
450  _read_scratchpad(ds18b20_info, &scratchpad,
451  offsetof(Scratchpad, configuration) - offsetof(Scratchpad, temperature) + 1);
452 
453  resolution = ((scratchpad.configuration >> 5) & 0x03) + DS18B20_RESOLUTION_9_BIT;
454  if (!_check_resolution(resolution))
455  {
456  ESP_LOGE(TAG, "invalid resolution read from device: 0x%02x", scratchpad.configuration);
457  resolution = DS18B20_RESOLUTION_INVALID;
458  }
459  else
460  {
461  ESP_LOGD(TAG, "Resolution read as %d", resolution);
462  }
463  }
464  return resolution;
465 }
466 
467 bool ds18b20_convert(const DS18B20_Info *ds18b20_info)
468 {
469  bool result = false;
470  if (_is_init(ds18b20_info))
471  {
472  const OneWireBus *bus = ds18b20_info->bus;
473  if (_address_device(ds18b20_info))
474  {
475  // initiate a temperature measurement
477  result = true;
478  }
479  else
480  {
481  ESP_LOGE(TAG, "ds18b20 device not responding");
482  }
483  }
484  return result;
485 }
486 
488 {
489  if (bus)
490  {
491  bool is_present = false;
492  owb_reset(bus, &is_present);
495  owb_set_strong_pullup(bus, true);
496  }
497  else
498  {
499  ESP_LOGE(TAG, "bus is NULL");
500  }
501 }
502 
503 float ds18b20_wait_for_conversion(const DS18B20_Info *ds18b20_info)
504 {
505  float elapsed_time = 0.0f;
506  if (_is_init(ds18b20_info))
507  {
508  if (ds18b20_info->bus->use_parasitic_power)
509  {
510  // in parasitic mode, devices cannot signal when they are complete,
511  // so use the datasheet values to wait for a duration.
512  elapsed_time = _wait_for_duration(ds18b20_info->resolution);
513  }
514  else
515  {
516  // wait for the device(s) to indicate the conversion is complete
517  elapsed_time = _wait_for_device_signal(ds18b20_info);
518  }
519  }
520  return elapsed_time;
521 }
522 
523 DS18B20_ERROR ds18b20_read_temp(const DS18B20_Info *ds18b20_info, float *value)
524 {
526  if (_is_init(ds18b20_info))
527  {
528  uint8_t temp_LSB = 0x00;
529  uint8_t temp_MSB = 0x80;
530  Scratchpad scratchpad = {0};
531  if ((err = _read_scratchpad(ds18b20_info, &scratchpad, 2)) == DS18B20_OK)
532  {
533  temp_LSB = scratchpad.temperature[0];
534  temp_MSB = scratchpad.temperature[1];
535  }
536 
537  // https://github.com/cpetrich/counterfeit_DS18B20#solution-to-the-85-c-problem
538  if (scratchpad.reserved[1] == 0x0c && temp_MSB == 0x05 && temp_LSB == 0x50)
539  {
540  ESP_LOGE(TAG, "Read power-on value (85.0)");
541  err = DS18B20_ERROR_DEVICE;
542  }
543 
544  float temp = _decode_temp(temp_LSB, temp_MSB, ds18b20_info->resolution);
545  ESP_LOGD(TAG, "temp_LSB 0x%02x, temp_MSB 0x%02x, temp %f", temp_LSB, temp_MSB, temp);
546 
547  if (value)
548  {
549  *value = temp;
550  }
551  }
552  return err;
553 }
554 
555 DS18B20_ERROR ds18b20_convert_and_read_temp(const DS18B20_Info *ds18b20_info, float *value)
556 {
558  if (_is_init(ds18b20_info))
559  {
560  if (ds18b20_convert(ds18b20_info))
561  {
562  // wait at least maximum conversion time
563  ds18b20_wait_for_conversion(ds18b20_info);
564 
565  if (value)
566  {
567  *value = 0.0f;
568  err = ds18b20_read_temp(ds18b20_info, value);
569  }
570  else
571  {
572  err = DS18B20_ERROR_NULL;
573  }
574  }
575  }
576  return err;
577 }
578 
580 {
582  ESP_LOGD(TAG, "ds18b20_check_for_parasite_power");
583  if (bus)
584  {
585  bool reset_present;
586  if ((err = owb_reset(bus, &reset_present)) == DS18B20_OK)
587  {
588  ESP_LOGD(TAG, "owb_reset OK");
589  if ((err = owb_write_byte(bus, OWB_ROM_SKIP)) == DS18B20_OK)
590  {
591  ESP_LOGD(TAG, "owb_write_byte(ROM_SKIP) OK");
593  {
594  // Parasitic-powered devices will pull the bus low during read time slot
595  ESP_LOGD(TAG, "owb_write_byte(POWER_SUPPLY_READ) OK");
596  uint8_t value = 0;
597  if ((err = owb_read_bit(bus, &value)) == DS18B20_OK)
598  {
599  ESP_LOGD(TAG, "owb_read_bit OK: 0x%02x", value);
600  if (present)
601  {
602  *present = !(bool)(value & 0x01u);
603  }
604  }
605  }
606  }
607  }
608  }
609  else
610  {
611  ESP_LOGE(TAG, "bus is NULL");
612  err = DS18B20_ERROR_NULL;
613  }
614  return err;
615 }
#define DS18B20_FUNCTION_TEMP_CONVERT
Initiate a single temperature conversion.
Definition: ds18b20.c:54
void ds18b20_init_solo(DS18B20_Info *ds18b20_info, const OneWireBus *bus)
Initialise a device info instance as a solo device on the bus.
Definition: ds18b20.c:378
bool ds18b20_set_resolution(DS18B20_Info *ds18b20_info, DS18B20_RESOLUTION resolution)
Set temperature measurement resolution.
Definition: ds18b20.c:404
void ds18b20_init(DS18B20_Info *ds18b20_info, const OneWireBus *bus, OneWireBus_ROMCode rom_code)
Initialise a device info instance with the specified GPIO.
Definition: ds18b20.c:362
void ds18b20_free(DS18B20_Info **ds18b20_info)
Delete an existing device info instance.
Definition: ds18b20.c:352
DS18B20_RESOLUTION ds18b20_read_resolution(DS18B20_Info *ds18b20_info)
Update and return the current temperature measurement resolution from the device.
Definition: ds18b20.c:443
#define DS18B20_FUNCTION_SCRATCHPAD_READ
Read 9 bytes of data (including CRC) from the device scratchpad.
Definition: ds18b20.c:56
#define DS18B20_FUNCTION_SCRATCHPAD_WRITE
Write 3 bytes of data to the device scratchpad at positions 2, 3 and 4.
Definition: ds18b20.c:55
float ds18b20_wait_for_conversion(const DS18B20_Info *ds18b20_info)
Wait for the maximum conversion time according to the current resolution of the device....
Definition: ds18b20.c:503
DS18B20_ERROR ds18b20_read_temp(const DS18B20_Info *ds18b20_info, float *value)
Read last temperature measurement from device.
Definition: ds18b20.c:523
#define DS18B20_FUNCTION_POWER_SUPPLY_READ
Determine if a device is using parasitic power.
Definition: ds18b20.c:59
DS18B20_ERROR ds18b20_check_for_parasite_power(const OneWireBus *bus, bool *present)
Check OneWire bus for presence of parasitic-powered devices.
Definition: ds18b20.c:579
void ds18b20_convert_all(const OneWireBus *bus)
Start temperature conversion on all connected devices.
Definition: ds18b20.c:487
void ds18b20_use_crc(DS18B20_Info *ds18b20_info, bool use_crc)
Enable or disable use of CRC checks on device communications.
Definition: ds18b20.c:395
DS18B20_ERROR ds18b20_convert_and_read_temp(const DS18B20_Info *ds18b20_info, float *value)
Convert, wait and read current temperature from device.
Definition: ds18b20.c:555
bool ds18b20_convert(const DS18B20_Info *ds18b20_info)
Start a temperature measurement conversion on a single device.
Definition: ds18b20.c:467
DS18B20_Info * ds18b20_malloc(void)
Construct a new device info instance. New instance should be initialised before calling other functio...
Definition: ds18b20.c:336
Interface definitions for the Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermom...
DS18B20_RESOLUTION
Symbols for the supported temperature resolution of the device.
Definition: ds18b20.h:61
@ DS18B20_RESOLUTION_12_BIT
12-bit resolution (default)
Definition: ds18b20.h:66
@ DS18B20_RESOLUTION_9_BIT
9-bit resolution, LSB bits 2,1,0 undefined
Definition: ds18b20.h:63
@ DS18B20_RESOLUTION_INVALID
Invalid resolution.
Definition: ds18b20.h:62
DS18B20_ERROR
Success and error codes.
Definition: ds18b20.h:48
@ DS18B20_OK
Success.
Definition: ds18b20.h:50
@ DS18B20_ERROR_UNKNOWN
An unknown error occurred, or the value was not set.
Definition: ds18b20.h:49
@ DS18B20_ERROR_NULL
A parameter or value is NULL.
Definition: ds18b20.h:54
@ DS18B20_ERROR_DEVICE
A device error occurred.
Definition: ds18b20.h:51
@ DS18B20_ERROR_CRC
A CRC error occurred.
Definition: ds18b20.h:52
@ DS18B20_ERROR_OWB
A One Wire Bus error occurred.
Definition: ds18b20.h:53
Interface definitions for the 1-Wire bus component.
owb_status owb_set_strong_pullup(const OneWireBus *bus, bool enable)
Enable or disable the strong-pullup GPIO, if configured.
Definition: owb.c:719
#define OWB_ROM_SKIP
Address all devices on the bus simultaneously.
Definition: owb.h:54
uint8_t owb_crc8_bytes(uint8_t crc, const uint8_t *data, size_t len)
1-Wire 8-bit CRC lookup with accumulation over a block of bytes.
Definition: owb.c:652
owb_status owb_write_rom_code(const OneWireBus *bus, OneWireBus_ROMCode rom_code)
Write a ROM code to the 1-Wire bus ensuring LSB is sent first.
Definition: owb.c:626
owb_status owb_write_bytes(const OneWireBus *bus, const uint8_t *buffer, size_t len)
Write a number of bytes to the 1-Wire bus.
Definition: owb.c:598
owb_status owb_read_bytes(const OneWireBus *bus, uint8_t *buffer, unsigned int len)
Read a number of bytes from the 1-Wire bus.
Definition: owb.c:524
@ OWB_STATUS_OK
Operation succeeded.
Definition: owb.h:116
owb_status owb_read_bit(const OneWireBus *bus, uint8_t *out)
Read a single bit from the 1-Wire bus.
Definition: owb.c:480
#define OWB_ROM_MATCH
Address a specific device on the bus by ROM.
Definition: owb.h:53
owb_status owb_write_byte(const OneWireBus *bus, uint8_t data)
Write a single byte to the 1-Wire bus.
Definition: owb.c:576
owb_status owb_reset(const OneWireBus *bus, bool *is_present)
Reset the 1-Wire bus.
Definition: owb.c:460
Structure containing information related to a single DS18B20 device connected via a 1-Wire bus.
Definition: ds18b20.h:74
DS18B20_RESOLUTION resolution
Temperature measurement resolution per reading.
Definition: ds18b20.h:80
bool init
True if struct has been initialised, otherwise false.
Definition: ds18b20.h:75
const OneWireBus * bus
Pointer to 1-Wire bus information relevant to this device.
Definition: ds18b20.h:78
OneWireBus_ROMCode rom_code
The ROM code used to address this device on the bus.
Definition: ds18b20.h:79
bool use_crc
True if CRC checks are to be used when retrieving information from a device on the bus.
Definition: ds18b20.h:77
bool solo
True if device is intended to be the only one connected to the bus, otherwise false.
Definition: ds18b20.h:76
Structure containing 1-Wire bus information relevant to a single instance.
Definition: owb.h:69
bool use_parasitic_power
True if parasitic-powered devices are expected on the bus.
Definition: owb.h:72
Represents a 1-Wire ROM Code. This is a sequence of eight bytes, where the first byte is the family n...
Definition: owb.h:83
volatile float temp
current temp
Definition: main.c:72
const char * TAG
Definition: wifi_sta.c:42