├── .github └── FUNDING.yml ├── LICENSE.TXT ├── README.md ├── ds18b20.h └── ds18b20.c /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | 4 | github: [nimaltd] 5 | patreon: # Replace with a single Patreon username 6 | open_collective: # Replace with a single Open Collective username 7 | ko_fi: nimaltd 8 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 9 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 10 | otechie: # Replace with a single Otechie username 11 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 12 | -------------------------------------------------------------------------------- /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | # Software License Terms 2 | 3 | This software is dual-licensed under the **GNU General Public License v2 (GPLv2)** and a **Commercial License**. 4 | 5 | --- 6 | 7 | ## 1. GNU General Public License v2 (GPLv2) 8 | This software is licensed under the GNU General Public License version 2 (GPLv2) **only**, as published by the Free Software Foundation. 9 | 10 | - You may redistribute and/or modify this software under the terms of GPLv2. 11 | - This license is provided **without any warranty**, including but not limited to implied warranties of **MERCHANTABILITY** or **FITNESS FOR A PARTICULAR PURPOSE**. 12 | - See for details. 13 | 14 | --- 15 | 16 | ## 2. Commercial License 17 | 18 | A commercial license is available for entities who wish to use this software **without the restrictions of GPLv2** (e.g., in closed-source or proprietary products). 19 | 20 | ### 2.1 Grant of License 21 | - A valid commercial license removes GPLv2 restrictions and grants the right to use, modify, and distribute the software in proprietary or closed-source products. 22 | - Commercial use of this software **requires obtaining a valid license agreement** from the copyright holder. 23 | 24 | ### 2.2 License Models 25 | - **Single-Product License** – Permits usage in **one specific product**. 26 | - **Company-Wide License** – Permits usage across **all products of the company**. 27 | 28 | ### 2.3 Maintenance & Updates 29 | - The licensor *may*, at its sole discretion, provide updates, bug fixes, or new releases. 30 | - The licensor has **no obligation** to release updates or support on a specific schedule. 31 | 32 | --- 33 | 34 | ## 3. Disclaimer of Warranty 35 | 36 | THIS SOFTWARE IS PROVIDED **"AS IS"** AND WITHOUT ANY WARRANTIES OF ANY KIND, WHETHER EXPRESS, IMPLIED, OR STATUTORY. 37 | THIS INCLUDES, BUT IS NOT LIMITED TO, THE IMPLIED WARRANTIES OF **MERCHANTABILITY**, **FITNESS FOR A PARTICULAR PURPOSE**, AND **NON-INFRINGEMENT**. 38 | 39 | --- 40 | 41 | ## 4. Limitation of Liability 42 | 43 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES. 44 | THIS INCLUDES, BUT IS NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, LOSS OF DATA, BUSINESS INTERRUPTION, OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO THE USE OF THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 45 | 46 | --- 47 | 48 | ## 5. Reservation of Rights 49 | 50 | All rights not expressly granted under this license are **reserved by the copyright holder**. 51 | 52 | --- 53 | 54 | 📌 For commercial licensing inquiries, please contact: 55 | **Nima Askari** 56 | ✉️ Email: **nima.askari@gmail.com** 57 | 58 | --- 59 | 60 | © 2025 Nima Askari. All rights reserved. 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🌡️ DS18B20 Temperature Sensor Library for STM32 2 | 3 | A lightweight and **non-blocking DS18B20 driver** written in C for STM32 (HAL-based). 4 | 5 | Built on top of the **non-blocking 1-Wire library**, it allows reading temperature from one or multiple DS18B20 devices **without blocking the CPU**. 6 | 7 | It supports: 8 | 9 | - 🌡️ **DS18B20** – 9–12 bit temperature sensor (Celsius & Fahrenheit) 10 | 11 | The library is designed for: 12 | 13 | - Applications requiring **non-blocking temperature acquisition** 14 | - Multi-device support on a single 1-Wire bus 15 | - STM32 projects across All families 16 | 17 | --- 18 | 19 | ## ✨ Features 20 | 21 | - 🔹 Non-blocking operation using timer callbacks 22 | - 🔹 Supports multiple DS18B20 devices (`OW_MAX_DEVICE`) 23 | - 🔹 Configurable resolution (9–12 bit) 24 | - 🔹 Temperature read in Celsius and Fahrenheit 25 | - 🔹 Alarm threshold configuration 26 | - 🔹 Works with any GPIO pins 27 | - 🔹 Built on top of HAL-compatible **1-Wire library** 28 | 29 | --- 30 | 31 | ## ⚙️ Installation 32 | 33 | ### 1. Copy files directly 34 | Add these files to your STM32 project: 35 | 36 | - `ds18b20.h` 37 | - `ds18b20.c` 38 | - Ensure One-Wire Library added, https://github.com/nimaltd/ow 39 | 40 | ### 2. STM32Cube Pack Installer (Recommended) 41 | Not yet available; include files manually for now. 42 | 43 | --- 44 | 45 | ## 🔧 Configuration (`ds18b20_config_t`) 46 | 47 | Set conversion resolution and alarm thresholds (Not yet available): 48 | 49 | ```c 50 | ds18b20_config_t ds18_conf = { 51 | .alarm_high = 50, // High temperature alarm 52 | .alarm_low = -50, // Low temperature alarm 53 | .cnv_bit = DS18B20_CNV_BIT_12 // Resolution (9–12 bit) 54 | }; 55 | ``` 56 | 57 | --- 58 | 59 | ## 🛠 CubeMX Setup 60 | 61 | Read in One-Wire Reopository 62 | 63 | ## 🚀 Quick Start 64 | 65 | ### Include header 66 | ```c 67 | #include "ds18b20.h" 68 | ``` 69 | 70 | ### Define a handle 71 | ```c 72 | ds18b20_t ds18; 73 | ``` 74 | 75 | ### Timer callback 76 | ```c 77 | void ds18_tim_cb(TIM_HandleTypeDef *htim) 78 | { 79 | ow_callback(&ds18.ow); 80 | } 81 | ``` 82 | 83 | ### Optional done callback 84 | ```c 85 | void ds18_done_cb(ow_err_t error) 86 | { 87 | } 88 | ``` 89 | 90 | ### Initialize DS18B20 in `main.c` 91 | ```c 92 | ow_init_t ow_init_struct; 93 | ow_init_struct.tim_handle = &htim1; 94 | ow_init_struct.gpio = GPIOC; 95 | ow_init_struct.pin = GPIO_PIN_8; 96 | ow_init_struct.tim_cb = ds18_tim_cb; 97 | ow_init_struct.done_cb = NULL; // Optional 98 | ow_init_struct.rom_id_filter = DS18B20_ID; 99 | 100 | ds18b20_init(&ds18, &ow_init_struct); 101 | 102 | // Update ROM IDs for all devices 103 | ds18b20_update_rom_id(&ds18); 104 | while(ds18b20_is_busy(&ds18)); 105 | 106 | // Configure alarm thresholds and resolution 107 | ds18b20_config_t ds18_conf = { 108 | .alarm_high = 50, 109 | .alarm_low = -50, 110 | .cnv_bit = DS18B20_CNV_BIT_12 111 | }; 112 | ds18b20_conf(&ds18, &ds18_conf); 113 | while(ds18b20_is_busy(&ds18)); 114 | ``` 115 | 116 | ### Read temperatures 117 | ```c 118 | int16_t temp_c[2]; 119 | 120 | while(1) { 121 | ds18b20_cnv(&ds18); 122 | while(ds18b20_is_busy(&ds18)); 123 | while(!ds18b20_is_cnv_done(&ds18)); 124 | 125 | ds18b20_req_read(&ds18, 0); 126 | while(ds18b20_is_busy(&ds18)); 127 | temp_c[0] = ds18b20_read_c(&ds18); 128 | 129 | ds18b20_req_read(&ds18, 1); 130 | while(ds18b20_is_busy(&ds18)); 131 | temp_c[1] = ds18b20_read_c(&ds18); 132 | } 133 | ``` 134 | 135 | --- 136 | 137 | ## 🧰 API Overview 138 | 139 | | Function | Description | 140 | |----------|-------------| 141 | | `ds18b20_init()` | Initialize DS18B20 driver handle | 142 | | `ds18b20_is_busy()` | Check if bus is busy | 143 | | `ds18b20_last_error()` | Get last error | 144 | | `ds18b20_update_rom_id()` | Update connected ROM IDs | 145 | | `ds18b20_cnv()` | Start temperature conversion | 146 | | `ds18b20_conf()` | Set configuration (alarm/resolution) | 147 | | `ds18b20_is_cnv_done()` | Check if conversion is done | 148 | | `ds18b20_req_read()` | Request temperature read | 149 | | `ds18b20_read_c()` | Read temperature in Celsius | 150 | | `ds18b20_read_f()` | Convert Celsius to Fahrenheit | 151 | 152 | --- 153 | 154 | ## 💖 Support 155 | 156 | If you find this project useful, please **⭐ star** the repo and support! 157 | 158 | - [![GitHub](https://img.shields.io/badge/GitHub-Follow-black?style=for-the-badge&logo=github)](https://github.com/NimaLTD) 159 | - [![YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?style=for-the-badge&logo=youtube)](https://www.youtube.com/@nimaltd) 160 | - [![Instagram](https://img.shields.io/badge/Instagram-Follow-blue?style=for-the-badge&logo=instagram)](https://instagram.com/github.nimaltd) 161 | - [![LinkedIn](https://img.shields.io/badge/LinkedIn-Connect-blue?style=for-the-badge&logo=linkedin)](https://linkedin.com/in/nimaltd) 162 | - [![Email](https://img.shields.io/badge/Email-Contact-red?style=for-the-badge&logo=gmail)](mailto:nima.askari@gmail.com) 163 | - [![Ko-fi](https://img.shields.io/badge/Ko--fi-Support-orange?style=for-the-badge&logo=ko-fi)](https://ko-fi.com/nimaltd) 164 | 165 | --- 166 | 167 | ## 📜 License 168 | 169 | Licensed under the terms in the [LICENSE](./LICENSE.TXT). 170 | 171 | --- 172 | -------------------------------------------------------------------------------- /ds18b20.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @file ds18b20.h 4 | * @brief ds18b20 driver 5 | * @author Nima Askari 6 | * @version 2.0.0 7 | * @license See the LICENSE file in the root folder. 8 | * 9 | * @note All my libraries are dual-licensed. 10 | * Please review the licensing terms before using them. 11 | * For any inquiries, feel free to contact me. 12 | * 13 | * @github https://www.github.com/nimaltd 14 | * @linkedin https://www.linkedin.com/in/nimaltd 15 | * @youtube https://www.youtube.com/@nimaltd 16 | * @instagram https://instagram.com/github.nimaltd 17 | * 18 | * Copyright (C) 2025 Nima Askari - NimaLTD. All rights reserved. 19 | */ 20 | 21 | #ifndef _DS18B20_H_ 22 | #define _DS18B20_H_ 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /*************************************************************************************************/ 29 | /** Includes **/ 30 | /*************************************************************************************************/ 31 | 32 | #include 33 | #include "main.h" 34 | #include "ow.h" 35 | 36 | /*************************************************************************************************/ 37 | /** Definitions **/ 38 | /*************************************************************************************************/ 39 | 40 | #define DS18B20_ID 0x28 41 | #define DS18B20_ERROR -10000 42 | 43 | /*************************************************************************************************/ 44 | /** Typedef/Struct/Enum **/ 45 | /*************************************************************************************************/ 46 | 47 | /*************************************************************************************************/ 48 | /* DS18B20 Command Codes */ 49 | typedef enum 50 | { 51 | DS18B20_CMD_CONV = 0x44, /* Start temperature conversion */ 52 | DS18B20_CMD_CONF = 0x4E, /* Write to configuration register */ 53 | DS18B20_CMD_READ = 0xBE, /* Read scratchpad */ 54 | DS18B20_CMD_RECALL = 0xB8, /* Recall EEPROM */ 55 | DS18B20_CMD_POWER = 0xB4 /* Check power supply (parasite power mode) */ 56 | 57 | } ds18b20_cmd_t; 58 | 59 | /*************************************************************************************************/ 60 | /* DS18B20 Resolution (conversion bits) */ 61 | typedef enum 62 | { 63 | DS18B20_CNV_BIT_9 = 9, 64 | DS18B20_CNV_BIT_10 = 10, 65 | DS18B20_CNV_BIT_11 = 11, 66 | DS18B20_CNV_BIT_12 = 12 67 | 68 | } ds18b20_cnv_bit_t; 69 | 70 | /*************************************************************************************************/ 71 | /* DS18B20 Conversion Times (in milliseconds) for each resolution */ 72 | typedef enum 73 | { 74 | DS18B20_CNV_TIM_9 = 100UL, 75 | DS18B20_CNV_TIM_10 = 200UL, 76 | DS18B20_CNV_TIM_11 = 400UL, 77 | DS18B20_CNV_TIM_12 = 800UL 78 | 79 | } ds18b20_cnv_tim_t; 80 | 81 | /*************************************************************************************************/ 82 | /* DS18B20 Configuration Structure */ 83 | typedef struct 84 | { 85 | int8_t alarm_low; /* Low temperature alarm threshold */ 86 | int8_t alarm_high; /* High temperature alarm threshold */ 87 | ds18b20_cnv_bit_t cnv_bit; /* Temperature resolution (9–12 bit) */ 88 | 89 | } ds18b20_config_t; 90 | 91 | /*************************************************************************************************/ 92 | /* DS18B20 Driver Handle */ 93 | typedef struct 94 | { 95 | ow_t ow; /* One-Wire interface handle */ 96 | uint32_t time; /* Start conversion timestamp */ 97 | ds18b20_cnv_tim_t cnv_time; /* Conversion time based on resolution */ 98 | ds18b20_cnv_bit_t cnv_bit_last; /* Store Last conversation bit length */ 99 | 100 | } ds18b20_t; 101 | 102 | /*************************************************************************************************/ 103 | /** API Functions **/ 104 | /*************************************************************************************************/ 105 | 106 | /* Initialize ds18b20 driver */ 107 | void ds18b20_init(ds18b20_t *handle, ow_init_t *init); 108 | 109 | /* Check if ds18b20 bus is busy */ 110 | bool ds18b20_is_busy(ds18b20_t *handle); 111 | 112 | /* Check if ds18b20 bus is busy */ 113 | ow_err_t ds18b20_last_error(ds18b20_t *handle); 114 | 115 | /* Start search to update all ROM IDs on the 1-Wire bus */ 116 | ow_err_t ds18b20_update_rom_id(ds18b20_t *handle); 117 | 118 | /* Send Start Conversation to All Devices */ 119 | ow_err_t ds18b20_cnv(ds18b20_t *handle); 120 | 121 | /* Set new configuration */ 122 | ow_err_t ds18b20_conf(ds18b20_t *handle, ds18b20_config_t *config); 123 | 124 | /* Check if ds18b20 conversation is done */ 125 | bool ds18b20_is_cnv_done(ds18b20_t *handle); 126 | 127 | #if (OW_MAX_DEVICE == 1) 128 | /* Send read temperature request */ 129 | ow_err_t ds18b20_req_read(ds18b20_t *handle); 130 | #else 131 | /* Send read temperature request */ 132 | ow_err_t ds18b20_req_read(ds18b20_t *handle, uint8_t rom_id); 133 | #endif 134 | 135 | /* Read temperature in Celsius */ 136 | int16_t ds18b20_read_c(ds18b20_t *handle); 137 | 138 | /* Convert temperature from Celsius to Fahrenheit */ 139 | int16_t ds18b20_cnv_to_f(int16_t temp_c); 140 | 141 | /* Read Last conversation bit */ 142 | ds18b20_cnv_bit_t 143 | ds18b20_read_last_cnv_bit(ds18b20_t *handle); 144 | 145 | /*************************************************************************************************/ 146 | /** End of File **/ 147 | /*************************************************************************************************/ 148 | 149 | #ifdef __cplusplus 150 | } 151 | #endif 152 | #endif /* _DS18B20_H_ */ 153 | -------------------------------------------------------------------------------- /ds18b20.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * @file ds18b20.c 4 | * @brief OneWire communication driver 5 | * @author Nima Askari 6 | * @version 2.0.0 7 | * @license See the LICENSE file in the root folder. 8 | * 9 | * @note All my libraries are dual-licensed. 10 | * Please review the licensing terms before using them. 11 | * For any inquiries, feel free to contact me. 12 | * 13 | * @github https://www.github.com/nimaltd 14 | * @linkedin https://www.linkedin.com/in/nimaltd 15 | * @youtube https://www.youtube.com/@nimaltd 16 | * @instagram https://instagram.com/github.nimaltd 17 | * 18 | * Copyright (C) 2025 Nima Askari - NimaLTD. All rights reserved. 19 | */ 20 | 21 | /*************************************************************************************************/ 22 | /** Includes **/ 23 | /*************************************************************************************************/ 24 | 25 | #include "ds18b20.h" 26 | 27 | /*************************************************************************************************/ 28 | /** Function Implementations **/ 29 | /*************************************************************************************************/ 30 | 31 | /*************************************************************************************************/ 32 | /** 33 | * @brief Initialize ds18b20 handle with one-wire configuration. 34 | * @param[in] handle: Pointer to the ds18b20 handle to initialize. 35 | * @param[in] init: Pointer to initialization data (GPIO, pin, timer, callback). 36 | * @retval None 37 | */ 38 | void ds18b20_init(ds18b20_t *handle, ow_init_t *init) 39 | { 40 | assert_param(handle != NULL); 41 | assert_param(init != NULL); 42 | 43 | /* Set Default value after power-up */ 44 | handle->cnv_time = DS18B20_CNV_TIM_12; 45 | 46 | /* Initialize one-wire */ 47 | ow_init(&handle->ow, init); 48 | } 49 | 50 | /*************************************************************************************************/ 51 | /** 52 | * @brief Check if ds18b20 bus is busy. 53 | * @param[in] handle: Pointer to the ds18b20 handle. 54 | * @retval true if busy, false if idle 55 | */ 56 | __INLINE bool ds18b20_is_busy(ds18b20_t *handle) 57 | { 58 | assert_param(handle != NULL); 59 | return ow_is_busy(&handle->ow); 60 | } 61 | 62 | /*************************************************************************************************/ 63 | /** 64 | * @brief Get the last ds18b20 error. 65 | * @param[in] handle: Pointer to the ds18b20 handle. 66 | * @retval Last error code (ow_err_t) 67 | */ 68 | __INLINE ow_err_t ds18b20_last_error(ds18b20_t *handle) 69 | { 70 | assert_param(handle != NULL); 71 | return ow_last_error(&handle->ow); 72 | } 73 | 74 | /*************************************************************************************************/ 75 | /** 76 | * @brief Start search to update all ROM IDs on the 1-Wire bus. 77 | * @param[in] handle: Pointer to the ds18b20 handle. 78 | * @retval Last error code (ow_err_t) 79 | */ 80 | __INLINE ow_err_t ds18b20_update_rom_id(ds18b20_t *handle) 81 | { 82 | assert_param(handle != NULL); 83 | return ow_update_rom_id(&handle->ow); 84 | } 85 | 86 | /*************************************************************************************************/ 87 | /** 88 | * @brief Send Start Conversation to All Devices. 89 | * @param[in] handle: Pointer to the ds18b20 handle. 90 | * @retval Last error code (ow_err_t) 91 | */ 92 | ow_err_t ds18b20_cnv(ds18b20_t *handle) 93 | { 94 | assert_param(handle != NULL); 95 | 96 | /* Save Start time */ 97 | handle->time = HAL_GetTick(); 98 | 99 | /* Send Command */ 100 | return ow_xfer(&handle->ow, DS18B20_CMD_CONV, NULL, 0, 0); 101 | } 102 | 103 | /*************************************************************************************************/ 104 | /** 105 | * @brief Set new configuration. 106 | * @param[in] handle: Pointer to the ds18b20 handle. 107 | * @param[in] config: Pointer to New configuration. 108 | * @retval Last error code (ow_err_t) 109 | */ 110 | ow_err_t ds18b20_conf(ds18b20_t *handle, ds18b20_config_t *config) 111 | { 112 | uint8_t w_data[3]; 113 | /* base config for 12-bit */ 114 | uint8_t conf_reg = 0x7F; 115 | 116 | assert_param(handle != NULL); 117 | assert_param(config != NULL); 118 | 119 | switch (config->cnv_bit) 120 | { 121 | case DS18B20_CNV_BIT_9: 122 | conf_reg = 0x1F; 123 | handle->cnv_time = DS18B20_CNV_TIM_9; 124 | break; 125 | case DS18B20_CNV_BIT_10: 126 | conf_reg = 0x3F; 127 | handle->cnv_time = DS18B20_CNV_TIM_10; 128 | break; 129 | case DS18B20_CNV_BIT_11: 130 | conf_reg = 0x5F; 131 | handle->cnv_time = DS18B20_CNV_TIM_11; 132 | break; 133 | default: 134 | conf_reg = 0x7F; 135 | handle->cnv_time = DS18B20_CNV_TIM_12; 136 | break; 137 | } 138 | 139 | /* Write data: TH, TL, config register */ 140 | if (config->alarm_high > 125) 141 | { 142 | config->alarm_high = 125; 143 | } 144 | if (config->alarm_high < -55) 145 | { 146 | config->alarm_high = -55; 147 | } 148 | if (config->alarm_low > 125) 149 | { 150 | config->alarm_low = 125; 151 | } 152 | if (config->alarm_low < -55) 153 | { 154 | config->alarm_low = -55; 155 | } 156 | w_data[0] = config->alarm_high; 157 | w_data[1] = config->alarm_low; 158 | w_data[2] = conf_reg; 159 | 160 | /* Send command over 1-Wire: Skip ROM + Write Scratchpad */ 161 | return ow_xfer(&handle->ow, DS18B20_CMD_CONF, w_data, 3, 0); 162 | } 163 | 164 | /*************************************************************************************************/ 165 | /** 166 | * @brief Check if ds18b20 conversation is done. 167 | * @param[in] handle: Pointer to the ds18b20 handle. 168 | * @retval True if Ready, otherwise false. 169 | */ 170 | bool ds18b20_is_cnv_done(ds18b20_t *handle) 171 | { 172 | assert_param(handle != NULL); 173 | 174 | return ((HAL_GetTick() - handle->time >= handle->cnv_time) ? true : false); 175 | } 176 | 177 | #if (OW_MAX_DEVICE == 1) 178 | /*************************************************************************************************/ 179 | /** 180 | * @brief Send read temperature request. 181 | * @param[in] handle: Pointer to the ds18b20 handle. 182 | * @retval Last error code (ow_err_t) 183 | */ 184 | ow_err_t ds18b20_req_read(ds18b20_t *handle) 185 | { 186 | assert_param(handle != NULL); 187 | 188 | /* Send Read Command */ 189 | return ow_xfer(&handle->ow, DS18B20_CMD_READ, NULL, 0, 9); 190 | } 191 | #else 192 | /*************************************************************************************************/ 193 | /** 194 | * @brief Send read temperature request. 195 | * @param[in] handle: Pointer to the ds18b20 handle. 196 | * @param[in] rom_id: Selected ROM ID index. 197 | * @retval Last error code (ow_err_t) 198 | */ 199 | ow_err_t ds18b20_req_read(ds18b20_t *handle, uint8_t rom_id) 200 | { 201 | assert_param(handle != NULL); 202 | 203 | /* Send Read Command */ 204 | return ow_xfer_by_id(&handle->ow, rom_id, DS18B20_CMD_READ, NULL, 0, 9); 205 | } 206 | #endif 207 | 208 | /*************************************************************************************************/ 209 | /** 210 | * @brief Read temperature from buffer. 211 | * @param[in] handle: Pointer to the ds18b20 handle. 212 | * @retval retval Temperature in Celsius * 100 (e.g. 1025 = 10.25°C), return DS18B20_ERROR if error 213 | */ 214 | int16_t ds18b20_read_c(ds18b20_t *handle) 215 | { 216 | uint8_t r_data[9]; 217 | uint16_t raw; 218 | int32_t temp_x100 = DS18B20_ERROR; // use 32-bit for intermediate math 219 | int8_t sign = 1; 220 | uint8_t resolution; 221 | 222 | assert_param(handle != NULL); 223 | 224 | do 225 | { 226 | /* Check received data length */ 227 | if (ow_read_resp(&handle->ow, r_data, sizeof(r_data)) != sizeof(r_data)) 228 | { 229 | break; 230 | } 231 | 232 | /* Check CRC */ 233 | if (ow_crc(r_data, 8) != r_data[8]) 234 | { 235 | break; 236 | } 237 | 238 | /* Read Raw data */ 239 | raw = (uint16_t) (r_data[0] | (r_data[1] << 8)); 240 | 241 | /* Check Sign */ 242 | if (raw & 0x8000) 243 | { 244 | raw = (~raw + 1); 245 | sign = -1; 246 | } 247 | 248 | /* Determine resolution (9–12 bits) */ 249 | resolution = ((r_data[4] & 0x60) >> 5) + 9; 250 | switch (resolution) 251 | { 252 | case DS18B20_CNV_BIT_9: 253 | /* 0.5°C per bit → 50 per bit in x100 units */ 254 | temp_x100 = (raw >> 3) * 50; 255 | handle->cnv_bit_last = DS18B20_CNV_BIT_9; 256 | break; 257 | case DS18B20_CNV_BIT_10: 258 | /* 0.25°C per bit → 25 per bit in x100 units */ 259 | temp_x100 = (raw >> 2) * 25; 260 | handle->cnv_bit_last = DS18B20_CNV_BIT_10; 261 | break; 262 | case DS18B20_CNV_BIT_11: 263 | /* 0.125°C per bit → 12.5 per bit in x100 units ≈ 125 / 10 */ 264 | temp_x100 = (raw >> 1) * 125 / 10; 265 | handle->cnv_bit_last = DS18B20_CNV_BIT_11; 266 | break; 267 | case DS18B20_CNV_BIT_12: 268 | /* 0.0625°C per bit → 6.25 per bit in x100 units = 625 / 100 */ 269 | temp_x100 = raw * 625 / 100; 270 | handle->cnv_bit_last = DS18B20_CNV_BIT_12; 271 | break; 272 | default: 273 | sign = 1; 274 | break; 275 | } 276 | 277 | temp_x100 *= sign; 278 | 279 | } 280 | while (0); 281 | 282 | return (int16_t) temp_x100; 283 | } 284 | 285 | /*************************************************************************************************/ 286 | /** 287 | * @brief Convert temperature from Celsius to Fahrenheit. 288 | * @param[in] temp_c: Temperature in Celsius * 100 (e.g., 1025 = 10.25°C) 289 | * @retval Temperature in Fahrenheit * 100 (e.g., 7234 = 72.34°F), 290 | * returns DS18B20_ERROR if error 291 | */ 292 | int16_t ds18b20_cnv_to_f(int16_t temp_c) 293 | { 294 | /* Check for error */ 295 | if (temp_c == DS18B20_ERROR) 296 | { 297 | return DS18B20_ERROR; 298 | } 299 | 300 | /* Convert to Fahrenheit: F = C * 1.8 + 32 */ 301 | /* Multiply everything by 100 to keep hundredths */ 302 | /* F_x100 = (C_x100 * 9 / 5) + 3200 */ 303 | return (int16_t)((int32_t) temp_c * 9) / 5 + 3200; 304 | } 305 | 306 | /*************************************************************************************************/ 307 | /** 308 | * @brief Read last conversation bit. 309 | * @param[in] handle: Pointer to the ds18b20 handle. 310 | * @retval ds18b20_cnv_bit_t conversation bit length 311 | */ 312 | ds18b20_cnv_bit_t ds18b20_read_last_cnv_bit(ds18b20_t *handle) 313 | { 314 | assert_param(handle != NULL); 315 | 316 | return handle->cnv_bit_last; 317 | } 318 | 319 | /*************************************************************************************************/ 320 | /** End of File **/ 321 | /*************************************************************************************************/ 322 | --------------------------------------------------------------------------------