├── .arduino-ci.yml ├── .arduino_ci ├── .arduino-ci.cpp └── util │ └── crc16.h ├── .devcontainer ├── Dockerfile ├── arduino-cli.yaml ├── devcontainer.json └── update-libraries.sh ├── .gitattributes ├── .github └── workflows │ ├── README.md │ ├── arduino-ci.yml │ ├── arduino-lint.yml │ └── jsoncheck.yml ├── .gitignore ├── CMakeLists.txt ├── DallasTemperature.cpp ├── DallasTemperature.h ├── Gemfile ├── LICENSE ├── README.md ├── arduino-cli.yaml ├── build.sh ├── examples ├── Alarm │ └── Alarm.ino ├── AlarmHandler │ └── AlarmHandler.ino ├── ESP-WebServer │ ├── ESP-WebServer.ino │ └── README.md ├── ExternalPullup │ └── ExternalPullup.ino ├── Multibus_simple │ └── Multibus_simple.ino ├── Multiple │ └── Multiple.ino ├── SaveRecallScratchPad │ └── SaveRecallScratchPad.ino ├── SetUserData │ └── SetUserData.ino ├── Simple │ └── Simple.ino ├── Single │ └── Single.ino ├── Tester │ └── Tester.ino ├── Timing │ └── Timing.ino ├── TwoPin_DS18B20 │ └── TwoPin_DS18B20.ino ├── UserDataDemo │ └── UserDataDemo.ino ├── UserDataWriteBatch │ └── UserDataWriteBatch.ino ├── WaitForConversion │ └── WaitForConversion.ino ├── WaitForConversion2 │ └── WaitForConversion2.ino ├── oneWireSearch │ └── oneWireSearch.ino └── readPowerSupply │ └── readPowerSupply.ino ├── keywords.txt ├── library.json ├── library.properties └── test ├── TestDallasTemperature.cpp └── unit_test_001.cpp /.arduino-ci.yml: -------------------------------------------------------------------------------- 1 | # .arduino-ci.yml 2 | 3 | # Compilation settings 4 | compile: 5 | platforms: 6 | - uno 7 | libraries: 8 | - "OneWire" 9 | 10 | # Unit testing settings 11 | unittest: 12 | platforms: 13 | - uno 14 | libraries: 15 | - "OneWire" -------------------------------------------------------------------------------- /.arduino_ci/.arduino-ci.cpp: -------------------------------------------------------------------------------- 1 | #define ARDUINO_CI 1 2 | 3 | // Mock OneWire GPIO functions 4 | uint8_t digitalPinToBitMask(uint8_t pin) { return 1 << (pin % 8); } 5 | void* digitalPinToPort(uint8_t pin) { static uint8_t dummy; return &dummy; } 6 | void* portModeRegister(void* port) { return port; } -------------------------------------------------------------------------------- /.arduino_ci/util/crc16.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC16_H 2 | #define CRC16_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | // Pure C implementation to replace the ASM version 9 | static inline uint16_t _crc16_update(uint16_t crc, uint8_t data) { 10 | unsigned int i; 11 | crc ^= data; 12 | for (i = 0; i < 8; ++i) { 13 | if (crc & 1) 14 | crc = (crc >> 1) ^ 0xA001; 15 | else 16 | crc = (crc >> 1); 17 | } 18 | return crc; 19 | } 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/vscode/devcontainers/cpp:debian 2 | 3 | # Install required packages 4 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 5 | && apt-get -y install --no-install-recommends \ 6 | python3 \ 7 | python3-pip \ 8 | git \ 9 | curl \ 10 | fish \ 11 | && apt-get clean \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | RUN mkdir -p /home/vscode/.local/share/CMakeTools \ 15 | && chown -R vscode:vscode /home/vscode/.local/share/CMakeTools 16 | 17 | RUN mkdir -p /home/vscode/.ssh \ 18 | && chown vscode:vscode /home/vscode/.ssh \ 19 | && chmod 700 /home/vscode/.ssh 20 | 21 | # Install arduino-cli 22 | RUN curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh 23 | 24 | # Set up arduino-cli config 25 | RUN arduino-cli config init 26 | 27 | # Add arduino-cli to PATH 28 | ENV PATH="/usr/local/bin:${PATH}" 29 | 30 | # Create workspace directory 31 | WORKDIR /workspace 32 | 33 | # Copy arduino-cli configuration (customise to your actual path) 34 | COPY arduino-cli.yaml /root/.arduino15/arduino-cli.yaml 35 | 36 | # Install build essentials 37 | RUN apt-get update && apt-get install -y build-essential && rm -rf /var/lib/apt/lists/* 38 | 39 | # (Optional) Install Arduino cores for ESP8266 and ESP32 if needed 40 | RUN arduino-cli core install esp8266:esp8266 esp32:esp32 41 | 42 | # Install only required dependencies for DallasTemperature library and others 43 | RUN arduino-cli lib install \ 44 | "OneWire" \ 45 | "ArduinoUnit" # For testing 46 | 47 | # Verify library installation 48 | RUN arduino-cli lib list 49 | 50 | # Copy update script 51 | COPY update-libraries.sh /usr/local/bin/ 52 | RUN chmod +x /usr/local/bin/update-libraries.sh 53 | 54 | # Add aliases for build operations (for Bash) 55 | RUN echo 'alias arduino-build="./build.sh build"' >> /home/vscode/.bashrc && \ 56 | echo 'alias arduino-test="./build.sh test"' >> /home/vscode/.bashrc && \ 57 | echo 'alias arduino-build-test="./build.sh all"' >> /home/vscode/.bashrc 58 | 59 | # Add a welcome message to .bashrc 60 | RUN echo '\n# Welcome to the dev container! Here are some useful aliases:' >> /home/vscode/.bashrc && \ 61 | echo 'echo " - arduino-build: Build the project"' >> /home/vscode/.bashrc && \ 62 | echo 'echo " - arduino-test: Run tests for the project"' >> /home/vscode/.bashrc && \ 63 | echo 'echo " - arduino-build-test: Build and test the project"' >> /home/vscode/.bashrc 64 | 65 | # (Optional) Add fish-specific configuration if desired 66 | # For example, you might add an alias file or welcome message for fish: 67 | RUN mkdir -p /home/vscode/.config/fish && \ 68 | echo 'set -gx PATH /usr/local/bin $PATH' >> /home/vscode/.config/fish/config.fish && \ 69 | echo '# Welcome to the Fish shell inside the dev container!' >> /home/vscode/.config/fish/config.fish 70 | 71 | # Generate SSH keys and set proper ownership and permissions 72 | RUN if [ ! -f /home/vscode/.ssh/id_rsa ]; then \ 73 | ssh-keygen -t rsa -b 4096 -N "" -C "devcontainer@local" -f /home/vscode/.ssh/id_rsa && \ 74 | chmod 600 /home/vscode/.ssh/id_rsa && \ 75 | chmod 644 /home/vscode/.ssh/id_rsa.pub && \ 76 | chown vscode:vscode /home/vscode/.ssh/id_rsa /home/vscode/.ssh/id_rsa.pub ; \ 77 | fi 78 | -------------------------------------------------------------------------------- /.devcontainer/arduino-cli.yaml: -------------------------------------------------------------------------------- 1 | compile: 2 | # Choosing to run compilation tests on 2 different Arduino platforms 3 | platforms: 4 | - uno 5 | - due 6 | # - zero # SAMD covered by M4 7 | # - leonardo # AVR covered by UNO 8 | - m4 9 | # - esp32 # errors on OneWire => util/crc16.h vs rom/crc.h 10 | # - esp8266 11 | # - mega2560 # AVR covered by UNO 12 | unittest: 13 | # These dependent libraries will be installed 14 | libraries: 15 | - "OneWire" 16 | board_manager: 17 | additional_urls: 18 | - https://arduino.esp8266.com/stable/package_esp8266com_index.json 19 | - https://dl.espressif.com/dl/package_esp32_index.json -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Arduino Library Development", 3 | "dockerFile": "Dockerfile", 4 | "mounts": [ 5 | "source=devcontainer_ssh,target=/home/vscode/.ssh,type=volume", 6 | "source=devcontainer_bash_history,target=/home/vscode/.bash_history,type=volume", 7 | "source=devcontainer_fish_history,target=/home/vscode/.local/share/fish/fish_history,type=volume" 8 | ], 9 | "customizations": { 10 | "vscode": { 11 | "extensions": [ 12 | "vsciot-vscode.vscode-arduino", 13 | "ms-vscode.cpptools", 14 | "ms-azuretools.vscode-docker", 15 | "yzhang.markdown-all-in-one" 16 | ] 17 | } 18 | }, 19 | "postCreateCommand": "arduino-cli core install arduino:avr && arduino-cli lib install ArduinoUnit && /usr/local/bin/update-libraries.sh", 20 | "updateContentCommand": "/usr/local/bin/update-libraries.sh", 21 | "remoteUser": "vscode" 22 | } 23 | -------------------------------------------------------------------------------- /.devcontainer/update-libraries.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Updating arduino-cli core and index..." 4 | arduino-cli core update-index 5 | arduino-cli update 6 | 7 | echo "Updating installed libraries..." 8 | arduino-cli lib update-index 9 | arduino-cli lib upgrade 10 | 11 | # Update Arduino cores 12 | echo "Updating ESP8266 and ESP32 cores..." 13 | arduino-cli core install esp8266:esp8266 14 | arduino-cli core install esp32:esp32 15 | 16 | # List of libraries to ensure are installed/updated 17 | LIBRARIES=( 18 | "OneWire" 19 | "ArduinoUnit" 20 | ) 21 | 22 | echo "Checking and installing libraries..." 23 | for lib in "${LIBRARIES[@]}"; do 24 | echo "Processing library: $lib" 25 | if ! arduino-cli lib list | grep -q "$lib"; then 26 | echo "Installing $lib..." 27 | arduino-cli lib install "$lib" 28 | else 29 | echo "$lib is already installed" 30 | fi 31 | done 32 | 33 | echo "Verifying all libraries are up to date..." 34 | arduino-cli lib list 35 | 36 | echo "Library update complete!" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/workflows/README.md: -------------------------------------------------------------------------------- 1 | # 📂 GitHub Workflows for Arduino Temperature Control Library 2 | 3 | Automate testing, compilation, and validation of the Arduino Temperature Control Library across multiple platforms using GitHub Actions. 4 | 5 | ## 🛠️ Workflows Overview 6 | 7 | ### 1. 📦 Arduino CI Workflow 8 | 9 | **Purpose:** 10 | Compiles the library and its examples for both AVR and ESP8266 platforms. 11 | 12 | **Trigger:** 13 | Runs on every `push` and `pull_request`. 14 | 15 | **Key Features:** 16 | - **AVR Compilation:** Compiles all examples for the AVR platform (e.g., Arduino Uno). 17 | - **ESP8266 Compilation:** Compiles all examples for the ESP8266 platform (e.g., NodeMCU v2). 18 | - **Selective Compilation:** Skips ESP-specific examples (e.g., ESP-WebServer) when compiling for AVR. 19 | - **Unit Testing:** Executes unit tests using the `arduino_ci` framework. 20 | 21 | ### 2. 🔄 Why Separate AVR and ESP Platforms? 22 | 23 | The library supports both AVR-based boards (e.g., Arduino Uno) and ESP8266-based boards (e.g., NodeMCU). Some examples utilize ESP-specific libraries like `ESP8266WiFi.h`, which are incompatible with AVR platforms. Separating the compilation ensures: 24 | 25 | - **AVR Compatibility:** Skips ESP-specific examples to prevent compilation errors. 26 | - **ESP Compatibility:** Compiles all examples, including ESP-specific ones, for the ESP8266 platform. 27 | 28 | ### 3. ⚙️ Workflow Steps 29 | 30 | The workflow follows these steps: 31 | 32 | 1. **Setup Environment:** 33 | - Installs dependencies (e.g., `gcc-avr`, `avr-libc`). 34 | - Configures the Arduino CLI and installs required cores (`arduino:avr` and `esp8266:esp8266`). 35 | 36 | 2. **Install Libraries:** 37 | - Installs the OneWire library. 38 | - Applies a custom CRC implementation. 39 | 40 | 3. **Run Unit Tests:** 41 | - Executes unit tests using the `arduino_ci` framework for the AVR platform. 42 | 43 | 4. **Compile Examples for AVR:** 44 | - Compiles all examples (excluding ESP-specific ones) for the AVR platform. 45 | 46 | 5. **Compile Examples for ESP8266:** 47 | - Compiles all examples (including ESP-specific ones) for the ESP8266 platform. 48 | 49 | ### 4. 📁 File Structure 50 | 51 | Understanding the project’s file structure is crucial for effective navigation and contribution. Below is an overview of the key files and directories: 52 | 53 | - **`Gemfile`** 54 | - **Description:** 55 | Manages Ruby dependencies required for the project. It ensures that the correct versions of gems (like `arduino_ci`) are used. 56 | - **Usage:** 57 | Run `bundle install` to install the necessary gems. 58 | 59 | - **`.arduino-ci.yml`** 60 | - **Description:** 61 | Configuration file for the `arduino_ci` tool. It defines how the Arduino CI should run tests and compile sketches. 62 | - **Key Configurations:** 63 | - Specifies which boards to target. 64 | - Defines libraries and dependencies needed for testing. 65 | - Sets up compilation and testing parameters. 66 | 67 | - **`.arduino_ci/`** 68 | - **Description:** 69 | Contains supporting files and configurations for the `arduino_ci.rb` tool. 70 | - **Contents:** 71 | - **`config.rb`:** 72 | Custom configuration settings for the Arduino CI. 73 | - **`helpers.rb`:** 74 | Helper methods and utilities used by the CI scripts. 75 | - **Other supporting scripts and assets.** 76 | 77 | - **`arduino-ci.yml`** 78 | - **Description:** 79 | GitHub Actions workflow file that defines the CI pipeline for the project. 80 | - **Key Sections:** 81 | - **Jobs:** 82 | Defines the sequence of steps for setting up the environment, installing dependencies, running tests, and compiling examples. 83 | - **Triggers:** 84 | Specifies when the workflow should run (e.g., on push or pull request). 85 | 86 | - **`examples/`** 87 | - **Description:** 88 | Contains example sketches demonstrating how to use the Arduino Temperature Control Library. 89 | - **Structure:** 90 | - **`ESP-WebServer/`** 91 | ESP-specific examples that utilize libraries like `ESP8266WiFi.h`. 92 | 93 | - **`LICENSE`** 94 | - **Description:** 95 | Contains the MIT License under which the project is released. 96 | 97 | - **Other Files and Directories:** 98 | - **`.github/`** 99 | - Contains GitHub-specific configurations, issues templates, and additional workflows. 100 | - **`src/`** 101 | - Contains the source code of the Arduino Temperature Control Library. 102 | 103 | ### 5. 🔧 Workflow Configuration 104 | 105 | The workflow is defined in the `arduino-ci.yml` file. Key configurations include: 106 | 107 | - **Cores Installed:** 108 | ```yaml 109 | arduino-cli core install arduino:avr 110 | arduino-cli core install esp8266:esp8266 111 | ``` 112 | 113 | - **Skipping ESP-Specific Examples:** 114 | ```yaml 115 | export ARDUINO_CI_SKIP_EXAMPLES="ESP-WebServer" 116 | ``` 117 | 118 | - **Compiling for AVR and ESP Platforms:** 119 | ```yaml 120 | arduino-cli compile --fqbn arduino:avr:uno "$sketch" 121 | arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 "$sketch" 122 | ``` 123 | 124 | ### 6. 🤝 Contributing 125 | 126 | If you’re contributing to the workflows, please ensure that: 127 | 128 | - **Compatibility:** New examples are compatible with both AVR and ESP platforms (if applicable). 129 | - **Organization:** ESP-specific examples are placed in a clearly labeled directory (e.g., `examples/ESP-WebServer`). 130 | - **Testing:** Unit tests are added or updated as needed. 131 | 132 | ### 7. 🐞 Troubleshooting 133 | 134 | If the workflow fails: 135 | 136 | 1. **Check Logs:** Navigate to the Actions tab in GitHub for detailed logs. 137 | 2. **Local Replication:** Try to replicate the issue locally using the dev container. 138 | 3. **Dependencies:** Ensure all dependencies are installed correctly. 139 | 140 | ## 📄 License 141 | 142 | This workflow configuration and scripts are released under the [MIT License](LICENSE). 143 | -------------------------------------------------------------------------------- /.github/workflows/arduino-ci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino-Temperature-Control-Library Github Workflow 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | 11 | - name: Install AVR dependencies 12 | run: | 13 | sudo apt-get update 14 | sudo apt-get install -y gcc-avr avr-libc 15 | 16 | - name: Create required directories 17 | run: | 18 | mkdir -p $GITHUB_WORKSPACE/libraries 19 | mkdir -p $GITHUB_WORKSPACE/.arduino15 20 | mkdir -p $GITHUB_WORKSPACE/Arduino 21 | 22 | - name: Setup Arduino CLI 23 | uses: arduino/setup-arduino-cli@v1 24 | 25 | - name: Configure Arduino CLI and install cores 26 | run: | 27 | arduino-cli config init 28 | arduino-cli config set library.enable_unsafe_install true 29 | arduino-cli config add board_manager.additional_urls https://arduino.esp8266.com/stable/package_esp8266com_index.json 30 | arduino-cli core update-index 31 | arduino-cli core install arduino:avr 32 | arduino-cli core install esp8266:esp8266 33 | 34 | - name: Install OneWire library 35 | run: | 36 | arduino-cli lib install OneWire 37 | # Replace the CRC implementation directly in the OneWire library 38 | cat > /home/runner/Arduino/libraries/OneWire/util/crc16.h << 'EOF' 39 | #ifndef CRC16_H 40 | #define CRC16_H 41 | #include 42 | 43 | static inline uint16_t _crc16_update(uint16_t crc, uint8_t a) 44 | { 45 | crc ^= a; 46 | for (uint8_t i = 0; i < 8; ++i) { 47 | if (crc & 1) 48 | crc = (crc >> 1) ^ 0xA001; 49 | else 50 | crc = (crc >> 1); 51 | } 52 | return crc; 53 | } 54 | 55 | #endif 56 | EOF 57 | 58 | - name: Set up Ruby 59 | uses: ruby/setup-ruby@v1 60 | with: 61 | ruby-version: '3.2.0' 62 | 63 | - name: Install bundler 64 | run: | 65 | gem install bundler 66 | 67 | - name: Install dependencies 68 | run: | 69 | bundle install 70 | 71 | - name: List repository contents (for debugging) 72 | run: | 73 | ls -R 74 | 75 | - name: Run tests (skip example compilation) 76 | run: | 77 | # Run arduino_ci for unit tests only (skip example compilation) 78 | export ARDUINO_CI_SELECTED_BOARD="arduino:avr:uno" 79 | bundle exec arduino_ci.rb --skip-examples-compilation 80 | 81 | - name: Compile all sketches for AVR platform 82 | run: | 83 | # Compile all sketches for AVR platform (Arduino Uno), excluding ESP-WebServer 84 | for sketch in $(find examples -name "*.ino" ! -path "*/ESP-WebServer/*"); do 85 | arduino-cli compile --fqbn arduino:avr:uno $sketch 86 | done 87 | 88 | - name: Compile all sketches for ESP8266 platform 89 | run: | 90 | # Compile all sketches for ESP8266 platform (NodeMCU v2) 91 | for sketch in $(find examples -name "*.ino"); do 92 | arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 $sketch 93 | done -------------------------------------------------------------------------------- /.github/workflows/arduino-lint.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Arduino-lint 3 | 4 | on: [push, pull_request] 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: arduino/arduino-lint-action@v1 11 | with: 12 | library-manager: update 13 | # compliance: strict 14 | -------------------------------------------------------------------------------- /.github/workflows/jsoncheck.yml: -------------------------------------------------------------------------------- 1 | name: JSON check 2 | 3 | on: 4 | push: 5 | paths: 6 | - '**.json' 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - name: json-syntax-check 15 | uses: limitusus/json-syntax-check@v1 16 | with: 17 | pattern: "\\.json$" 18 | 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | classes 3 | target 4 | out 5 | build 6 | *.iml 7 | *.ipr 8 | *.iws 9 | *.log 10 | *.war 11 | .idea 12 | .project 13 | .classpath 14 | .settings 15 | .gradle 16 | .vscode 17 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Author: diplfranzhoepfinger 2 | # reference: https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html 3 | # URL: https://github.com/milesburton/Arduino-Temperature-Control-Library 4 | # DATE: 15.02.2023 5 | 6 | idf_component_register( 7 | SRCS "DallasTemperature.cpp" 8 | INCLUDE_DIRS "." 9 | PRIV_REQUIRES OneWire arduino 10 | ) 11 | -------------------------------------------------------------------------------- /DallasTemperature.cpp: -------------------------------------------------------------------------------- 1 | #include "DallasTemperature.h" 2 | 3 | #if ARDUINO >= 100 4 | #include "Arduino.h" 5 | #else 6 | extern "C" { 7 | #include "WConstants.h" 8 | } 9 | #endif 10 | 11 | // OneWire commands 12 | #define STARTCONVO 0x44 // Tells device to take a temperature reading 13 | #define COPYSCRATCH 0x48 // Copy scratchpad to EEPROM 14 | #define READSCRATCH 0xBE // Read from scratchpad 15 | #define WRITESCRATCH 0x4E // Write to scratchpad 16 | #define RECALLSCRATCH 0xB8 // Recall from EEPROM to scratchpad 17 | #define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power 18 | #define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition 19 | 20 | // Scratchpad locations 21 | #define TEMP_LSB 0 22 | #define TEMP_MSB 1 23 | #define HIGH_ALARM_TEMP 2 24 | #define LOW_ALARM_TEMP 3 25 | #define CONFIGURATION 4 26 | #define INTERNAL_BYTE 5 27 | #define COUNT_REMAIN 6 28 | #define COUNT_PER_C 7 29 | #define SCRATCHPAD_CRC 8 30 | 31 | // Device resolution 32 | #define TEMP_9_BIT 0x1F 33 | #define TEMP_10_BIT 0x3F 34 | #define TEMP_11_BIT 0x5F 35 | #define TEMP_12_BIT 0x7F 36 | 37 | #define NO_ALARM_HANDLER ((AlarmHandler *)0) 38 | 39 | // DSROM FIELDS 40 | #define DSROM_FAMILY 0 41 | #define DSROM_CRC 7 42 | 43 | DallasTemperature::DallasTemperature() { 44 | _wire = nullptr; 45 | devices = 0; 46 | ds18Count = 0; 47 | parasite = false; 48 | bitResolution = 9; 49 | waitForConversion = true; 50 | checkForConversion = true; 51 | autoSaveScratchPad = true; 52 | useExternalPullup = false; 53 | #if REQUIRESALARMS 54 | setAlarmHandler(NO_ALARM_HANDLER); 55 | alarmSearchJunction = -1; 56 | alarmSearchExhausted = 0; 57 | #endif 58 | } 59 | 60 | DallasTemperature::DallasTemperature(OneWire* _oneWire) : DallasTemperature() { 61 | setOneWire(_oneWire); 62 | } 63 | 64 | DallasTemperature::DallasTemperature(OneWire* _oneWire, uint8_t _pullupPin) : DallasTemperature(_oneWire) { 65 | setPullupPin(_pullupPin); 66 | } 67 | 68 | void DallasTemperature::setOneWire(OneWire* _oneWire) { 69 | _wire = _oneWire; 70 | devices = 0; 71 | ds18Count = 0; 72 | parasite = false; 73 | bitResolution = 9; 74 | waitForConversion = true; 75 | checkForConversion = true; 76 | autoSaveScratchPad = true; 77 | } 78 | 79 | void DallasTemperature::setPullupPin(uint8_t _pullupPin) { 80 | useExternalPullup = true; 81 | pullupPin = _pullupPin; 82 | pinMode(pullupPin, OUTPUT); 83 | deactivateExternalPullup(); 84 | } 85 | 86 | void DallasTemperature::begin(void) { 87 | DeviceAddress deviceAddress; 88 | 89 | for (uint8_t retry = 0; retry < MAX_INITIALIZATION_RETRIES; retry++) { 90 | _wire->reset_search(); 91 | devices = 0; 92 | ds18Count = 0; 93 | 94 | delay(INITIALIZATION_DELAY_MS); 95 | 96 | while (_wire->search(deviceAddress)) { 97 | if (validAddress(deviceAddress)) { 98 | devices++; 99 | 100 | if (validFamily(deviceAddress)) { 101 | ds18Count++; 102 | 103 | if (!parasite && readPowerSupply(deviceAddress)) { 104 | parasite = true; 105 | } 106 | 107 | uint8_t b = getResolution(deviceAddress); 108 | if (b > bitResolution) { 109 | bitResolution = b; 110 | } 111 | } 112 | } 113 | } 114 | 115 | if (devices > 0) break; 116 | } 117 | } 118 | 119 | void DallasTemperature::activateExternalPullup() { 120 | if (useExternalPullup) digitalWrite(pullupPin, LOW); 121 | } 122 | 123 | void DallasTemperature::deactivateExternalPullup() { 124 | if (useExternalPullup) digitalWrite(pullupPin, HIGH); 125 | } 126 | 127 | bool DallasTemperature::validFamily(const uint8_t* deviceAddress) { 128 | switch (deviceAddress[0]) { 129 | case DS18S20MODEL: 130 | case DS18B20MODEL: 131 | case DS1822MODEL: 132 | case DS1825MODEL: 133 | case DS28EA00MODEL: 134 | return true; 135 | default: 136 | return false; 137 | } 138 | } 139 | 140 | bool DallasTemperature::validAddress(const uint8_t* deviceAddress) { 141 | return (_wire->crc8(const_cast(deviceAddress), 7) == deviceAddress[7]); 142 | } 143 | 144 | bool DallasTemperature::getAddress(uint8_t* deviceAddress, uint8_t index) { 145 | if (index < devices) { 146 | uint8_t depth = 0; 147 | 148 | _wire->reset_search(); 149 | 150 | while (depth <= index && _wire->search(deviceAddress)) { 151 | if (depth == index && validAddress(deviceAddress)) { 152 | return true; 153 | } 154 | depth++; 155 | } 156 | } 157 | return false; 158 | } 159 | 160 | uint8_t DallasTemperature::getDeviceCount(void) { 161 | return devices; 162 | } 163 | 164 | uint8_t DallasTemperature::getDS18Count(void) { 165 | return ds18Count; 166 | } 167 | 168 | bool DallasTemperature::isConnected(const uint8_t* deviceAddress) { 169 | ScratchPad scratchPad; 170 | return isConnected(deviceAddress, scratchPad); 171 | } 172 | 173 | bool DallasTemperature::isConnected(const uint8_t* deviceAddress, uint8_t* scratchPad) { 174 | bool b = readScratchPad(deviceAddress, scratchPad); 175 | return b && !isAllZeros(scratchPad) && (_wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC]); 176 | } 177 | 178 | bool DallasTemperature::readPowerSupply(const uint8_t* deviceAddress) { 179 | bool parasiteMode = false; 180 | _wire->reset(); 181 | if (deviceAddress == nullptr) { 182 | _wire->skip(); 183 | } else { 184 | _wire->select(deviceAddress); 185 | } 186 | 187 | _wire->write(READPOWERSUPPLY); 188 | if (_wire->read_bit() == 0) { 189 | parasiteMode = true; 190 | } 191 | _wire->reset(); 192 | return parasiteMode; 193 | } 194 | 195 | bool DallasTemperature::isParasitePowerMode(void) { 196 | return parasite; 197 | } 198 | 199 | bool DallasTemperature::isAllZeros(const uint8_t* const scratchPad, const size_t length) { 200 | for (size_t i = 0; i < length; i++) { 201 | if (scratchPad[i] != 0) return false; 202 | } 203 | return true; 204 | } 205 | 206 | bool DallasTemperature::readScratchPad(const uint8_t* deviceAddress, uint8_t* scratchPad) { 207 | int b = _wire->reset(); 208 | if (b == 0) return false; 209 | 210 | _wire->select(deviceAddress); 211 | _wire->write(READSCRATCH); 212 | 213 | for (uint8_t i = 0; i < 9; i++) { 214 | scratchPad[i] = _wire->read(); 215 | } 216 | 217 | b = _wire->reset(); 218 | return (b == 1); 219 | } 220 | 221 | void DallasTemperature::writeScratchPad(const uint8_t* deviceAddress, const uint8_t* scratchPad) { 222 | _wire->reset(); 223 | _wire->select(deviceAddress); 224 | _wire->write(WRITESCRATCH); 225 | _wire->write(scratchPad[HIGH_ALARM_TEMP]); // high alarm temp 226 | _wire->write(scratchPad[LOW_ALARM_TEMP]); // low alarm temp 227 | 228 | // DS1820 and DS18S20 have no configuration register 229 | if (deviceAddress[0] != DS18S20MODEL) { 230 | _wire->write(scratchPad[CONFIGURATION]); 231 | } 232 | 233 | if (autoSaveScratchPad) { 234 | saveScratchPad(deviceAddress); 235 | } else { 236 | _wire->reset(); 237 | } 238 | } 239 | 240 | bool DallasTemperature::saveScratchPad(const uint8_t* deviceAddress) { 241 | if (_wire->reset() == 0) return false; 242 | 243 | if (deviceAddress == nullptr) 244 | _wire->skip(); 245 | else 246 | _wire->select(deviceAddress); 247 | 248 | _wire->write(COPYSCRATCH, parasite); 249 | 250 | // Specification: NV Write Cycle Time is typically 2ms, max 10ms 251 | // Waiting 20ms to allow for sensors that take longer in practice 252 | if (!parasite) { 253 | delay(20); 254 | } else { 255 | activateExternalPullup(); 256 | delay(20); 257 | deactivateExternalPullup(); 258 | } 259 | 260 | return (_wire->reset() == 1); 261 | } 262 | 263 | bool DallasTemperature::recallScratchPad(const uint8_t* deviceAddress) { 264 | if (_wire->reset() == 0) return false; 265 | 266 | if (deviceAddress == nullptr) 267 | _wire->skip(); 268 | else 269 | _wire->select(deviceAddress); 270 | 271 | _wire->write(RECALLSCRATCH, parasite); 272 | 273 | // Specification: Strong pullup only needed when writing to EEPROM 274 | unsigned long start = millis(); 275 | while (_wire->read_bit() == 0) { 276 | if (millis() - start > 20) return false; 277 | yield(); 278 | } 279 | 280 | return (_wire->reset() == 1); 281 | } 282 | 283 | int32_t DallasTemperature::getTemp(const uint8_t* deviceAddress, byte retryCount) { 284 | ScratchPad scratchPad; 285 | byte retries = 0; 286 | 287 | while (retries++ <= retryCount) { 288 | if (isConnected(deviceAddress, scratchPad)) { 289 | return calculateTemperature(deviceAddress, scratchPad); 290 | } 291 | } 292 | 293 | return DEVICE_DISCONNECTED_RAW; 294 | } 295 | 296 | float DallasTemperature::getTempC(const uint8_t* deviceAddress, byte retryCount) { 297 | return rawToCelsius(getTemp(deviceAddress, retryCount)); 298 | } 299 | 300 | float DallasTemperature::getTempF(const uint8_t* deviceAddress) { 301 | return rawToFahrenheit(getTemp(deviceAddress)); 302 | } 303 | 304 | float DallasTemperature::getTempCByIndex(uint8_t index) { 305 | DeviceAddress deviceAddress; 306 | if (!getAddress(deviceAddress, index)) { 307 | return DEVICE_DISCONNECTED_C; 308 | } 309 | return getTempC((uint8_t*)deviceAddress); 310 | } 311 | 312 | float DallasTemperature::getTempFByIndex(uint8_t index) { 313 | DeviceAddress deviceAddress; 314 | if (!getAddress(deviceAddress, index)) { 315 | return DEVICE_DISCONNECTED_F; 316 | } 317 | return getTempF((uint8_t*)deviceAddress); 318 | } 319 | 320 | void DallasTemperature::setResolution(uint8_t newResolution) { 321 | bitResolution = constrain(newResolution, 9, 12); 322 | DeviceAddress deviceAddress; 323 | _wire->reset_search(); 324 | for (uint8_t i = 0; i < devices; i++) { 325 | if (_wire->search(deviceAddress) && validAddress(deviceAddress)) { 326 | setResolution(deviceAddress, bitResolution, true); 327 | } 328 | } 329 | } 330 | 331 | bool DallasTemperature::setResolution(const uint8_t* deviceAddress, uint8_t newResolution, bool skipGlobalBitResolutionCalculation) { 332 | bool success = false; 333 | 334 | if (deviceAddress[0] == DS18S20MODEL) { 335 | success = true; 336 | } else { 337 | newResolution = constrain(newResolution, 9, 12); 338 | uint8_t newValue = 0; 339 | ScratchPad scratchPad; 340 | 341 | if (isConnected(deviceAddress, scratchPad)) { 342 | switch (newResolution) { 343 | case 12: newValue = TEMP_12_BIT; break; 344 | case 11: newValue = TEMP_11_BIT; break; 345 | case 10: newValue = TEMP_10_BIT; break; 346 | case 9: 347 | default: newValue = TEMP_9_BIT; break; 348 | } 349 | 350 | if (scratchPad[CONFIGURATION] != newValue) { 351 | scratchPad[CONFIGURATION] = newValue; 352 | writeScratchPad(deviceAddress, scratchPad); 353 | } 354 | success = true; 355 | } 356 | } 357 | 358 | if (!skipGlobalBitResolutionCalculation && success) { 359 | bitResolution = newResolution; 360 | if (devices > 1) { 361 | DeviceAddress deviceAddr; 362 | _wire->reset_search(); 363 | for (uint8_t i = 0; i < devices; i++) { 364 | if (bitResolution == 12) break; 365 | if (_wire->search(deviceAddr) && validAddress(deviceAddr)) { 366 | uint8_t b = getResolution(deviceAddr); 367 | if (b > bitResolution) bitResolution = b; 368 | } 369 | } 370 | } 371 | } 372 | return success; 373 | } 374 | 375 | uint8_t DallasTemperature::getResolution() { 376 | return bitResolution; 377 | } 378 | 379 | uint8_t DallasTemperature::getResolution(const uint8_t* deviceAddress) { 380 | if (deviceAddress[0] == DS18S20MODEL) return 12; 381 | 382 | ScratchPad scratchPad; 383 | if (isConnected(deviceAddress, scratchPad)) { 384 | if (deviceAddress[0] == DS1825MODEL && scratchPad[CONFIGURATION] & 0x80) { 385 | return 12; 386 | } 387 | 388 | switch (scratchPad[CONFIGURATION]) { 389 | case TEMP_12_BIT: return 12; 390 | case TEMP_11_BIT: return 11; 391 | case TEMP_10_BIT: return 10; 392 | case TEMP_9_BIT: return 9; 393 | } 394 | } 395 | return 0; 396 | } 397 | 398 | float DallasTemperature::toFahrenheit(float celsius) { 399 | return (celsius * 1.8f) + 32.0f; 400 | } 401 | 402 | float DallasTemperature::toCelsius(float fahrenheit) { 403 | return (fahrenheit - 32.0f) * 0.555555556f; 404 | } 405 | 406 | float DallasTemperature::rawToCelsius(int32_t raw) { 407 | if (raw <= DEVICE_DISCONNECTED_RAW) 408 | return DEVICE_DISCONNECTED_C; 409 | return (float)raw * 0.0078125f; // 1/128 410 | } 411 | 412 | float DallasTemperature::rawToFahrenheit(int32_t raw) { 413 | if (raw <= DEVICE_DISCONNECTED_RAW) 414 | return DEVICE_DISCONNECTED_F; 415 | return rawToCelsius(raw) * 1.8f + 32.0f; 416 | } 417 | 418 | int16_t DallasTemperature::celsiusToRaw(float celsius) { 419 | return static_cast(celsius * 128.0f); 420 | } 421 | 422 | uint16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) { 423 | switch (bitResolution) { 424 | case 9: return 94; 425 | case 10: return 188; 426 | case 11: return 375; 427 | default: return 750; 428 | } 429 | } 430 | 431 | uint16_t DallasTemperature::millisToWaitForConversion() { 432 | return millisToWaitForConversion(bitResolution); 433 | } 434 | 435 | void DallasTemperature::setWaitForConversion(bool flag) { 436 | waitForConversion = flag; 437 | } 438 | 439 | bool DallasTemperature::getWaitForConversion() { 440 | return waitForConversion; 441 | } 442 | 443 | void DallasTemperature::setCheckForConversion(bool flag) { 444 | checkForConversion = flag; 445 | } 446 | 447 | bool DallasTemperature::getCheckForConversion() { 448 | return checkForConversion; 449 | } 450 | 451 | bool DallasTemperature::isConversionComplete() { 452 | uint8_t b = _wire->read_bit(); 453 | return (b == 1); 454 | } 455 | 456 | void DallasTemperature::setAutoSaveScratchPad(bool flag) { 457 | autoSaveScratchPad = flag; 458 | } 459 | 460 | bool DallasTemperature::getAutoSaveScratchPad() { 461 | return autoSaveScratchPad; 462 | } 463 | 464 | DallasTemperature::request_t DallasTemperature::requestTemperatures() { 465 | request_t req = {}; 466 | req.result = true; 467 | 468 | _wire->reset(); 469 | _wire->skip(); 470 | _wire->write(STARTCONVO, parasite); 471 | 472 | req.timestamp = millis(); 473 | if (!waitForConversion) return req; 474 | 475 | blockTillConversionComplete(bitResolution, req.timestamp); 476 | return req; 477 | } 478 | 479 | DallasTemperature::request_t DallasTemperature::requestTemperaturesByAddress(const uint8_t* deviceAddress) { 480 | request_t req = {}; 481 | uint8_t deviceBitResolution = getResolution(deviceAddress); 482 | if (deviceBitResolution == 0) { 483 | req.result = false; 484 | return req; 485 | } 486 | 487 | _wire->reset(); 488 | _wire->select(deviceAddress); 489 | _wire->write(STARTCONVO, parasite); 490 | 491 | req.timestamp = millis(); 492 | req.result = true; 493 | 494 | if (!waitForConversion) return req; 495 | 496 | blockTillConversionComplete(deviceBitResolution, req.timestamp); 497 | return req; 498 | } 499 | 500 | DallasTemperature::request_t DallasTemperature::requestTemperaturesByIndex(uint8_t index) { 501 | DeviceAddress deviceAddress; 502 | getAddress(deviceAddress, index); 503 | return requestTemperaturesByAddress(deviceAddress); 504 | } 505 | 506 | void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution) { 507 | unsigned long start = millis(); 508 | blockTillConversionComplete(bitResolution, start); 509 | } 510 | 511 | void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution, unsigned long start) { 512 | if (checkForConversion && !parasite) { 513 | while (!isConversionComplete() && ((unsigned long)(millis() - start) < (unsigned long)MAX_CONVERSION_TIMEOUT)) { 514 | yield(); 515 | } 516 | } else { 517 | unsigned long delayInMillis = millisToWaitForConversion(bitResolution); 518 | activateExternalPullup(); 519 | delay(delayInMillis); 520 | deactivateExternalPullup(); 521 | } 522 | } 523 | 524 | void DallasTemperature::blockTillConversionComplete(uint8_t bitResolution, request_t req) { 525 | if (req.result) { 526 | blockTillConversionComplete(bitResolution, req.timestamp); 527 | } 528 | } 529 | 530 | int32_t DallasTemperature::calculateTemperature(const uint8_t* deviceAddress, uint8_t* scratchPad) { 531 | int32_t fpTemperature = 0; 532 | 533 | // looking thru the spec sheets of all supported devices, bit 15 is always the signing bit 534 | int32_t neg = 0x0; 535 | if (scratchPad[TEMP_MSB] & 0x80) 536 | neg = 0xFFF80000; 537 | 538 | // detect MAX31850 539 | if (deviceAddress[0] == DS1825MODEL && scratchPad[CONFIGURATION] & 0x80) { 540 | if (scratchPad[TEMP_LSB] & 1) { // Fault Detected 541 | if (scratchPad[HIGH_ALARM_TEMP] & 1) { 542 | return DEVICE_FAULT_OPEN_RAW; 543 | } else if (scratchPad[HIGH_ALARM_TEMP] >> 1 & 1) { 544 | return DEVICE_FAULT_SHORTGND_RAW; 545 | } else if (scratchPad[HIGH_ALARM_TEMP] >> 2 & 1) { 546 | return DEVICE_FAULT_SHORTVDD_RAW; 547 | } else { 548 | return DEVICE_DISCONNECTED_RAW; 549 | } 550 | } 551 | // We must mask out bit 1 (reserved) and 0 (fault) on TEMP_LSB 552 | fpTemperature = (((int32_t)scratchPad[TEMP_MSB]) << 11) 553 | | (((int32_t)scratchPad[TEMP_LSB] & 0xFC) << 3) 554 | | neg; 555 | } else { 556 | fpTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 11) 557 | | (((int16_t)scratchPad[TEMP_LSB]) << 3) 558 | | neg; 559 | } 560 | 561 | /* 562 | DS1820 and DS18S20 have a 9-bit temperature register. 563 | 564 | Resolutions greater than 9-bit can be calculated using the data from 565 | the temperature, and COUNT REMAIN and COUNT PER °C registers in the 566 | scratchpad. The resolution of the calculation depends on the model. 567 | 568 | While the COUNT PER °C register is hard-wired to 16 (10h) in a 569 | DS18S20, it changes with temperature in DS1820. 570 | 571 | After reading the scratchpad, the TEMP_READ value is obtained by 572 | truncating the 0.5°C bit (bit 0) from the temperature data. The 573 | extended resolution temperature can then be calculated using the 574 | following equation: 575 | 576 | COUNT_PER_C - COUNT_REMAIN 577 | TEMPERATURE = TEMP_READ - 0.25 + -------------------------- 578 | COUNT_PER_C 579 | 580 | Hagai Shatz simplified this to integer arithmetic for a 12 bits 581 | value for a DS18S20, and James Cameron added legacy DS1820 support. 582 | 583 | See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html 584 | */ 585 | 586 | if ((deviceAddress[DSROM_FAMILY] == DS18S20MODEL) && (scratchPad[COUNT_PER_C] != 0)) { 587 | fpTemperature = (((fpTemperature & 0xfff0) << 3) - 32 588 | + (((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 7) 589 | / scratchPad[COUNT_PER_C])) | neg; 590 | } 591 | 592 | return fpTemperature; 593 | } 594 | 595 | #if REQUIRESALARMS 596 | 597 | void DallasTemperature::setAlarmHandler(const AlarmHandler* handler) { 598 | _AlarmHandler = handler; 599 | } 600 | 601 | void DallasTemperature::setHighAlarmTemp(const uint8_t* deviceAddress, int8_t celsius) { 602 | // make sure the alarm temperature is within the device's range 603 | if (celsius > 125) celsius = 125; 604 | else if (celsius < -55) celsius = -55; 605 | 606 | ScratchPad scratchPad; 607 | if (isConnected(deviceAddress, scratchPad)) { 608 | scratchPad[HIGH_ALARM_TEMP] = (uint8_t)celsius; 609 | writeScratchPad(deviceAddress, scratchPad); 610 | } 611 | } 612 | 613 | void DallasTemperature::setLowAlarmTemp(const uint8_t* deviceAddress, int8_t celsius) { 614 | // make sure the alarm temperature is within the device's range 615 | if (celsius > 125) celsius = 125; 616 | else if (celsius < -55) celsius = -55; 617 | 618 | ScratchPad scratchPad; 619 | if (isConnected(deviceAddress, scratchPad)) { 620 | scratchPad[LOW_ALARM_TEMP] = (uint8_t)celsius; 621 | writeScratchPad(deviceAddress, scratchPad); 622 | } 623 | } 624 | 625 | int8_t DallasTemperature::getHighAlarmTemp(const uint8_t* deviceAddress) { 626 | ScratchPad scratchPad; 627 | if (isConnected(deviceAddress, scratchPad)) 628 | return (int8_t)scratchPad[HIGH_ALARM_TEMP]; 629 | return DEVICE_DISCONNECTED_C; 630 | } 631 | 632 | int8_t DallasTemperature::getLowAlarmTemp(const uint8_t* deviceAddress) { 633 | ScratchPad scratchPad; 634 | if (isConnected(deviceAddress, scratchPad)) 635 | return (int8_t)scratchPad[LOW_ALARM_TEMP]; 636 | return DEVICE_DISCONNECTED_C; 637 | } 638 | 639 | void DallasTemperature::resetAlarmSearch() { 640 | alarmSearchJunction = -1; 641 | alarmSearchExhausted = 0; 642 | for (uint8_t i = 0; i < 7; i++) { 643 | alarmSearchAddress[i] = 0; 644 | } 645 | } 646 | 647 | bool DallasTemperature::alarmSearch(uint8_t* newAddr) { 648 | uint8_t i; 649 | int8_t lastJunction = -1; 650 | uint8_t done = 1; 651 | 652 | if (alarmSearchExhausted) 653 | return false; 654 | 655 | if (!_wire->reset()) 656 | return false; 657 | 658 | _wire->write(ALARMSEARCH); 659 | 660 | for (i = 0; i < 64; i++) { 661 | uint8_t a = _wire->read_bit(); 662 | uint8_t nota = _wire->read_bit(); 663 | uint8_t ibyte = i / 8; 664 | uint8_t ibit = 1 << (i & 7); 665 | 666 | if (a && nota) 667 | return false; 668 | 669 | if (!a && !nota) { 670 | if (i == alarmSearchJunction) { 671 | a = 1; 672 | alarmSearchJunction = lastJunction; 673 | } else if (i < alarmSearchJunction) { 674 | if (alarmSearchAddress[ibyte] & ibit) { 675 | a = 1; 676 | } else { 677 | a = 0; 678 | done = 0; 679 | lastJunction = i; 680 | } 681 | } else { 682 | a = 0; 683 | alarmSearchJunction = i; 684 | done = 0; 685 | } 686 | } 687 | 688 | if (a) 689 | alarmSearchAddress[ibyte] |= ibit; 690 | else 691 | alarmSearchAddress[ibyte] &= ~ibit; 692 | 693 | _wire->write_bit(a); 694 | } 695 | 696 | if (done) 697 | alarmSearchExhausted = 1; 698 | for (i = 0; i < 8; i++) 699 | newAddr[i] = alarmSearchAddress[i]; 700 | return true; 701 | } 702 | 703 | bool DallasTemperature::hasAlarm(const uint8_t* deviceAddress) { 704 | ScratchPad scratchPad; 705 | if (isConnected(deviceAddress, scratchPad)) { 706 | int8_t temp = calculateTemperature(deviceAddress, scratchPad) >> 7; 707 | return (temp <= (int8_t)scratchPad[LOW_ALARM_TEMP] || 708 | temp >= (int8_t)scratchPad[HIGH_ALARM_TEMP]); 709 | } 710 | return false; 711 | } 712 | 713 | bool DallasTemperature::hasAlarm(void) { 714 | DeviceAddress deviceAddress; 715 | resetAlarmSearch(); 716 | return alarmSearch(deviceAddress); 717 | } 718 | 719 | void DallasTemperature::processAlarms(void) { 720 | if (!hasAlarmHandler()) 721 | return; 722 | 723 | resetAlarmSearch(); 724 | DeviceAddress alarmAddr; 725 | 726 | while (alarmSearch(alarmAddr)) { 727 | if (validAddress(alarmAddr)) { 728 | _AlarmHandler(alarmAddr); 729 | } 730 | } 731 | } 732 | 733 | bool DallasTemperature::hasAlarmHandler() { 734 | return (_AlarmHandler != NO_ALARM_HANDLER); 735 | } 736 | 737 | #endif 738 | 739 | #if REQUIRESNEW 740 | 741 | void* DallasTemperature::operator new(unsigned int size) { 742 | void* p = malloc(size); 743 | memset(p, 0, size); 744 | return p; 745 | } 746 | 747 | void DallasTemperature::operator delete(void* p) { 748 | free(p); 749 | } 750 | 751 | #endif 752 | 753 | bool DallasTemperature::verifyDeviceCount(void) { 754 | uint8_t actualCount = 0; 755 | float temp; 756 | 757 | requestTemperatures(); 758 | 759 | do { 760 | temp = getTempCByIndex(actualCount); 761 | if (temp > DEVICE_DISCONNECTED_C) { 762 | actualCount++; 763 | } 764 | } while (temp > DEVICE_DISCONNECTED_C && actualCount < 255); 765 | 766 | if (actualCount > devices) { 767 | devices = actualCount; 768 | begin(); 769 | return true; 770 | } 771 | 772 | return false; 773 | } 774 | 775 | void DallasTemperature::setUserData(const uint8_t* deviceAddress, int16_t data) { 776 | // return when stored value == new value 777 | if (getUserData(deviceAddress) == data) 778 | return; 779 | 780 | ScratchPad scratchPad; 781 | if (isConnected(deviceAddress, scratchPad)) { 782 | scratchPad[HIGH_ALARM_TEMP] = data >> 8; 783 | scratchPad[LOW_ALARM_TEMP] = data & 255; 784 | writeScratchPad(deviceAddress, scratchPad); 785 | } 786 | } 787 | 788 | void DallasTemperature::setUserDataByIndex(uint8_t deviceIndex, int16_t data) { 789 | DeviceAddress deviceAddress; 790 | if (getAddress(deviceAddress, deviceIndex)) { 791 | setUserData((uint8_t*)deviceAddress, data); 792 | } 793 | } 794 | 795 | int16_t DallasTemperature::getUserData(const uint8_t* deviceAddress) { 796 | int16_t data = 0; 797 | ScratchPad scratchPad; 798 | if (isConnected(deviceAddress, scratchPad)) { 799 | data = scratchPad[HIGH_ALARM_TEMP] << 8; 800 | data += scratchPad[LOW_ALARM_TEMP]; 801 | } 802 | return data; 803 | } 804 | 805 | int16_t DallasTemperature::getUserDataByIndex(uint8_t deviceIndex) { 806 | DeviceAddress deviceAddress; 807 | getAddress(deviceAddress, deviceIndex); 808 | return getUserData((uint8_t*)deviceAddress); 809 | } -------------------------------------------------------------------------------- /DallasTemperature.h: -------------------------------------------------------------------------------- 1 | #ifndef DallasTemperature_h 2 | #define DallasTemperature_h 3 | 4 | #define DALLASTEMPLIBVERSION "4.0.4" 5 | 6 | // Configuration 7 | #ifndef REQUIRESNEW 8 | #define REQUIRESNEW false 9 | #endif 10 | 11 | #ifndef REQUIRESALARMS 12 | #define REQUIRESALARMS true 13 | #endif 14 | 15 | // Includes 16 | #include 17 | #include 18 | 19 | #ifdef __STM32F1__ 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | // Constants for device models 26 | #define DS18S20MODEL 0x10 // also DS1820 27 | #define DS18B20MODEL 0x28 // also MAX31820 28 | #define DS1822MODEL 0x22 29 | #define DS1825MODEL 0x3B // also MAX31850 30 | #define DS28EA00MODEL 0x42 31 | 32 | // Error Codes 33 | #define DEVICE_DISCONNECTED_C -127 34 | #define DEVICE_DISCONNECTED_F -196.6 35 | #define DEVICE_DISCONNECTED_RAW -7040 36 | 37 | #define DEVICE_FAULT_OPEN_C -254 38 | #define DEVICE_FAULT_OPEN_F -425.199982 39 | #define DEVICE_FAULT_OPEN_RAW -32512 40 | 41 | #define DEVICE_FAULT_SHORTGND_C -253 42 | #define DEVICE_FAULT_SHORTGND_F -423.399994 43 | #define DEVICE_FAULT_SHORTGND_RAW -32384 44 | 45 | #define DEVICE_FAULT_SHORTVDD_C -252 46 | #define DEVICE_FAULT_SHORTVDD_F -421.599976 47 | #define DEVICE_FAULT_SHORTVDD_RAW -32256 48 | 49 | // Configuration Constants 50 | #define MAX_CONVERSION_TIMEOUT 750 51 | #define MAX_INITIALIZATION_RETRIES 3 52 | #define INITIALIZATION_DELAY_MS 50 53 | 54 | typedef uint8_t DeviceAddress[8]; 55 | 56 | class DallasTemperature { 57 | public: 58 | struct request_t { 59 | bool result; 60 | unsigned long timestamp; 61 | operator bool() { return result; } 62 | }; 63 | 64 | // Constructors 65 | DallasTemperature(); 66 | DallasTemperature(OneWire*); 67 | DallasTemperature(OneWire*, uint8_t); 68 | 69 | // Setup & Configuration 70 | void setOneWire(OneWire*); 71 | void setPullupPin(uint8_t); 72 | void begin(void); 73 | bool verifyDeviceCount(void); 74 | 75 | // Device Information 76 | uint8_t getDeviceCount(void); 77 | uint8_t getDS18Count(void); 78 | bool validAddress(const uint8_t*); 79 | bool validFamily(const uint8_t* deviceAddress); 80 | bool getAddress(uint8_t*, uint8_t); 81 | bool isConnected(const uint8_t*); 82 | bool isConnected(const uint8_t*, uint8_t*); 83 | 84 | // Scratchpad Operations 85 | bool readScratchPad(const uint8_t*, uint8_t*); 86 | void writeScratchPad(const uint8_t*, const uint8_t*); 87 | bool readPowerSupply(const uint8_t* deviceAddress = nullptr); 88 | 89 | // Resolution Control 90 | uint8_t getResolution(); 91 | void setResolution(uint8_t); 92 | uint8_t getResolution(const uint8_t*); 93 | bool setResolution(const uint8_t*, uint8_t, bool skipGlobalBitResolutionCalculation = false); 94 | 95 | // Conversion Configuration 96 | void setWaitForConversion(bool); 97 | bool getWaitForConversion(void); 98 | void setCheckForConversion(bool); 99 | bool getCheckForConversion(void); 100 | 101 | // Temperature Operations 102 | request_t requestTemperatures(void); 103 | request_t requestTemperaturesByAddress(const uint8_t*); 104 | request_t requestTemperaturesByIndex(uint8_t); 105 | int32_t getTemp(const uint8_t*, byte retryCount = 0); 106 | float getTempC(const uint8_t*, byte retryCount = 0); 107 | float getTempF(const uint8_t*); 108 | float getTempCByIndex(uint8_t); 109 | float getTempFByIndex(uint8_t); 110 | 111 | // Conversion Status 112 | bool isParasitePowerMode(void); 113 | bool isConversionComplete(void); 114 | static uint16_t millisToWaitForConversion(uint8_t); 115 | uint16_t millisToWaitForConversion(); 116 | 117 | // EEPROM Operations 118 | bool saveScratchPadByIndex(uint8_t); 119 | bool saveScratchPad(const uint8_t* = nullptr); 120 | bool recallScratchPadByIndex(uint8_t); 121 | bool recallScratchPad(const uint8_t* = nullptr); 122 | void setAutoSaveScratchPad(bool); 123 | bool getAutoSaveScratchPad(void); 124 | 125 | #if REQUIRESALARMS 126 | typedef void AlarmHandler(const uint8_t*); 127 | void setHighAlarmTemp(const uint8_t*, int8_t); 128 | void setLowAlarmTemp(const uint8_t*, int8_t); 129 | int8_t getHighAlarmTemp(const uint8_t*); 130 | int8_t getLowAlarmTemp(const uint8_t*); 131 | void resetAlarmSearch(void); 132 | bool alarmSearch(uint8_t*); 133 | bool hasAlarm(const uint8_t*); 134 | bool hasAlarm(void); 135 | void processAlarms(void); 136 | void setAlarmHandler(const AlarmHandler*); 137 | bool hasAlarmHandler(); 138 | #endif 139 | 140 | // User Data Operations 141 | void setUserData(const uint8_t*, int16_t); 142 | void setUserDataByIndex(uint8_t, int16_t); 143 | int16_t getUserData(const uint8_t*); 144 | int16_t getUserDataByIndex(uint8_t); 145 | 146 | // Temperature Conversion Utilities 147 | static float toFahrenheit(float); 148 | static float toCelsius(float); 149 | static float rawToCelsius(int32_t); 150 | static int16_t celsiusToRaw(float); 151 | static float rawToFahrenheit(int32_t); 152 | 153 | #if REQUIRESNEW 154 | void* operator new(unsigned int); 155 | void operator delete(void*); 156 | #endif 157 | 158 | // Conversion Completion Methods 159 | void blockTillConversionComplete(uint8_t); 160 | void blockTillConversionComplete(uint8_t, unsigned long); 161 | void blockTillConversionComplete(uint8_t, request_t); 162 | 163 | private: 164 | typedef uint8_t ScratchPad[9]; 165 | 166 | // Internal State 167 | bool parasite; 168 | bool useExternalPullup; 169 | uint8_t pullupPin; 170 | uint8_t bitResolution; 171 | bool waitForConversion; 172 | bool checkForConversion; 173 | bool autoSaveScratchPad; 174 | uint8_t devices; 175 | uint8_t ds18Count; 176 | OneWire* _wire; 177 | 178 | // Internal Methods 179 | int32_t calculateTemperature(const uint8_t*, uint8_t*); 180 | bool isAllZeros(const uint8_t* const scratchPad, const size_t length = 9); 181 | void activateExternalPullup(void); 182 | void deactivateExternalPullup(void); 183 | 184 | #if REQUIRESALARMS 185 | uint8_t alarmSearchAddress[8]; 186 | int8_t alarmSearchJunction; 187 | uint8_t alarmSearchExhausted; 188 | AlarmHandler* _AlarmHandler; 189 | #endif 190 | }; 191 | 192 | #endif // DallasTemperature_h -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "arduino_ci", "~> 1.6.2" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Miles Burton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 🌡️ Arduino Temperature Control Library 3 | 4 | [![Arduino CI](https://github.com/milesburton/Arduino-Temperature-Control-Library/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) 5 | [![Arduino-lint](https://github.com/milesburton/Arduino-Temperature-Control-Library/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AS5600/actions/workflows/arduino-lint.yml) 6 | [![JSON check](https://github.com/milesburton/Arduino-Temperature-Control-Library/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AS5600/actions/workflows/jsoncheck.yml) 7 | [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/master/LICENSE) 8 | [![GitHub release](https://img.shields.io/github/release/milesburton/Arduino-Temperature-Control-Library.svg?maxAge=3600)](https://github.com/milesburton/Arduino-Temperature-Control-Library/releases) 9 | 10 | A robust and feature-complete Arduino library for Maxim Temperature Integrated Circuits. 11 | 12 | ## 📌 Supported Devices 13 | 14 | - DS18B20 15 | - DS18S20 (⚠️ Known issues with this series) 16 | - DS1822 17 | - DS1820 18 | - MAX31820 19 | - MAX31850 20 | 21 | ## 🚀 Installation 22 | 23 | ### Using Arduino IDE Library Manager (Recommended) 24 | 1. Open Arduino IDE 25 | 2. Go to Tools > Manage Libraries... 26 | 3. Search for "DallasTemperature" 27 | 4. Click Install 28 | 5. Also install the required "OneWire" library by Paul Stoffregen using the same method 29 | 30 | ### Manual Installation 31 | 1. Download the latest release from [GitHub releases](https://github.com/milesburton/Arduino-Temperature-Control-Library/releases) 32 | 2. In Arduino IDE, go to Sketch > Include Library > Add .ZIP Library... 33 | 3. Select the downloaded ZIP file 34 | 4. Repeat steps 1-3 for the required "OneWire" library 35 | 36 | ## 📝 Basic Usage 37 | 38 | 1. **Hardware Setup** 39 | - Connect a 4k7 kΩ pull-up resistor between the 1-Wire data line and 5V power. Note this applies to the Arduino platform, for ESP32 and 8266 you'll need to adjust the resistor value accordingly. 40 | - For DS18B20: Ground pins 1 and 3 (the centre pin is the data line) 41 | - For reliable readings, see pull-up requirements in the [DS18B20 datasheet](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) (page 7) 42 | 43 | 2. **Code Example** 44 | ```cpp 45 | #include 46 | #include 47 | 48 | // Data wire is connected to GPIO 4 49 | #define ONE_WIRE_BUS 4 50 | 51 | OneWire oneWire(ONE_WIRE_BUS); 52 | DallasTemperature sensors(&oneWire); 53 | 54 | void setup(void) { 55 | Serial.begin(9600); 56 | sensors.begin(); 57 | } 58 | 59 | void loop(void) { 60 | sensors.requestTemperatures(); 61 | 62 | delay(750); 63 | 64 | float tempC = sensors.getTempCByIndex(0); 65 | Serial.print("Temperature: "); 66 | Serial.print(tempC); 67 | Serial.println("°C"); 68 | delay(1000); 69 | } 70 | ``` 71 | 72 | ## 🛠️ Advanced Features 73 | 74 | - Multiple sensors on the same bus 75 | - Temperature conversion by address (`getTempC(address)` and `getTempF(address)`) 76 | - Asynchronous mode (added in v3.7.0) 77 | - Configurable resolution 78 | 79 | ### Configuration Options 80 | 81 | You can slim down the code by defining the following at the top of DallasTemperature.h: 82 | 83 | ```cpp 84 | #define REQUIRESNEW // Use if you want to minimise code size 85 | #define REQUIRESALARMS // Use if you need alarm functionality 86 | ``` 87 | 88 | ## 📚 Additional Documentation 89 | 90 | Visit our [Wiki](https://www.milesburton.com/w/index.php/Dallas_Temperature_Control_Library) for detailed documentation. 91 | 92 | ## 🔧 Library Development 93 | 94 | If you want to contribute to the library development: 95 | 96 | ### Using Dev Container 97 | The project includes a development container configuration for VS Code that provides a consistent development environment. 98 | 99 | 1. **Prerequisites** 100 | - Visual Studio Code 101 | - Docker 102 | - VS Code Remote - Containers extension 103 | 104 | 2. **Development Commands** 105 | Within the dev container, use: 106 | - `arduino-build` - Compile the library and examples 107 | - `arduino-test` - Run the test suite 108 | - `arduino-build-test` - Complete build and test process 109 | 110 | > Note: Currently compiling against arduino:avr:uno environment 111 | 112 | ## ✨ Credits 113 | 114 | - Original development by Miles Burton 115 | - Multiple sensor support by Tim Newsome 116 | - Address-based temperature reading by Guil Barros [gfbarros@bappos.com] 117 | - Async mode by Rob Tillaart [rob.tillaart@gmail.com] 118 | 119 | ## 📄 License 120 | 121 | MIT License | Copyright (c) 2025 Miles Burton 122 | 123 | Full license text available in [LICENSE](LICENSE) file. 124 | -------------------------------------------------------------------------------- /arduino-cli.yaml: -------------------------------------------------------------------------------- 1 | board_manager: 2 | additional_urls: [] 3 | daemon: 4 | port: "50051" 5 | directories: 6 | data: $GITHUB_WORKSPACE/.arduino15 7 | downloads: $GITHUB_WORKSPACE/.arduino15/staging 8 | user: $GITHUB_WORKSPACE/libraries 9 | library: 10 | enable_unsafe_install: true 11 | logging: 12 | file: "" 13 | format: text 14 | level: info 15 | metrics: 16 | addr: :9090 17 | enabled: true 18 | sketch: 19 | always_export_binaries: false -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set error handling 4 | set -e 5 | 6 | # Function to display usage 7 | show_usage() { 8 | echo "Usage: ./build.sh [option]" 9 | echo "Options:" 10 | echo " build - Only compile library and examples" 11 | echo " test - Only compile and run tests" 12 | echo " all - Build everything and run tests (default)" 13 | } 14 | 15 | # Function to compile for a specific board 16 | compile_for_board() { 17 | local fqbn=$1 18 | local sketch=$2 19 | echo "📦 Compiling $sketch for $fqbn..." 20 | arduino-cli compile --fqbn $fqbn "$sketch" --library . 21 | } 22 | 23 | # Function to build library and examples 24 | build() { 25 | echo "🔨 Building library and examples..." 26 | 27 | # Compile all examples 28 | echo "🔍 Compiling examples..." 29 | for example in examples/*/*.ino; do 30 | if [ -f "$example" ]; then 31 | echo "Building example: $example" 32 | compile_for_board "arduino:avr:uno" "$example" 33 | fi 34 | done 35 | } 36 | 37 | # Function to run tests 38 | run_tests() { 39 | echo "🧪 Running tests..." 40 | for test in test/*/*.ino; do 41 | if [ -f "$test" ]; then 42 | echo "Running test: $test" 43 | compile_for_board "arduino:avr:uno" "$test" 44 | fi 45 | done 46 | } 47 | 48 | # Main execution 49 | case "${1:-all}" in 50 | "build") 51 | build 52 | ;; 53 | "test") 54 | run_tests 55 | ;; 56 | "all") 57 | build 58 | run_tests 59 | ;; 60 | *) 61 | show_usage 62 | exit 1 63 | ;; 64 | esac 65 | 66 | echo "✅ Process completed!" -------------------------------------------------------------------------------- /examples/Alarm/Alarm.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Data wire is plugged into port 2 on the Arduino 5 | #define ONE_WIRE_BUS 2 6 | 7 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 8 | OneWire oneWire(ONE_WIRE_BUS); 9 | 10 | // Pass our oneWire reference to Dallas Temperature. 11 | DallasTemperature sensors(&oneWire); 12 | 13 | // arrays to hold device addresses 14 | DeviceAddress insideThermometer, outsideThermometer; 15 | 16 | void setup(void) 17 | { 18 | // start serial port 19 | Serial.begin(9600); 20 | Serial.println("Dallas Temperature IC Control Library Demo"); 21 | 22 | // Start up the library 23 | sensors.begin(); 24 | 25 | // locate devices on the bus 26 | Serial.print("Found "); 27 | Serial.print(sensors.getDeviceCount(), DEC); 28 | Serial.println(" devices."); 29 | 30 | // search for devices on the bus and assign based on an index. 31 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 32 | if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 33 | 34 | // show the addresses we found on the bus 35 | Serial.print("Device 0 Address: "); 36 | printAddress(insideThermometer); 37 | Serial.println(); 38 | 39 | Serial.print("Device 0 Alarms: "); 40 | printAlarms(insideThermometer); 41 | Serial.println(); 42 | 43 | Serial.print("Device 1 Address: "); 44 | printAddress(outsideThermometer); 45 | Serial.println(); 46 | 47 | Serial.print("Device 1 Alarms: "); 48 | printAlarms(outsideThermometer); 49 | Serial.println(); 50 | 51 | Serial.println("Setting alarm temps..."); 52 | 53 | // alarm when temp is higher than 30C 54 | sensors.setHighAlarmTemp(insideThermometer, 30); 55 | 56 | // alarm when temp is lower than -10C 57 | sensors.setLowAlarmTemp(insideThermometer, -10); 58 | 59 | // alarm when temp is higher than 31C 60 | sensors.setHighAlarmTemp(outsideThermometer, 31); 61 | 62 | // alarn when temp is lower than 27C 63 | sensors.setLowAlarmTemp(outsideThermometer, 27); 64 | 65 | Serial.print("New Device 0 Alarms: "); 66 | printAlarms(insideThermometer); 67 | Serial.println(); 68 | 69 | Serial.print("New Device 1 Alarms: "); 70 | printAlarms(outsideThermometer); 71 | Serial.println(); 72 | } 73 | 74 | // function to print a device address 75 | void printAddress(DeviceAddress deviceAddress) 76 | { 77 | for (uint8_t i = 0; i < 8; i++) 78 | { 79 | if (deviceAddress[i] < 16) Serial.print("0"); 80 | Serial.print(deviceAddress[i], HEX); 81 | } 82 | } 83 | 84 | // function to print the temperature for a device 85 | void printTemperature(DeviceAddress deviceAddress) 86 | { 87 | float tempC = sensors.getTempC(deviceAddress); 88 | Serial.print("Temp C: "); 89 | Serial.print(tempC); 90 | Serial.print(" Temp F: "); 91 | Serial.print(DallasTemperature::toFahrenheit(tempC)); 92 | } 93 | 94 | void printAlarms(uint8_t deviceAddress[]) 95 | { 96 | char temp; 97 | temp = sensors.getHighAlarmTemp(deviceAddress); 98 | Serial.print("High Alarm: "); 99 | Serial.print(temp, DEC); 100 | Serial.print("C/"); 101 | Serial.print(DallasTemperature::toFahrenheit(temp)); 102 | Serial.print("F | Low Alarm: "); 103 | temp = sensors.getLowAlarmTemp(deviceAddress); 104 | Serial.print(temp, DEC); 105 | Serial.print("C/"); 106 | Serial.print(DallasTemperature::toFahrenheit(temp)); 107 | Serial.print("F"); 108 | } 109 | 110 | // main function to print information about a device 111 | void printData(DeviceAddress deviceAddress) 112 | { 113 | Serial.print("Device Address: "); 114 | printAddress(deviceAddress); 115 | Serial.print(" "); 116 | printTemperature(deviceAddress); 117 | Serial.println(); 118 | } 119 | 120 | void checkAlarm(DeviceAddress deviceAddress) 121 | { 122 | if (sensors.hasAlarm(deviceAddress)) 123 | { 124 | Serial.print("ALARM: "); 125 | printData(deviceAddress); 126 | } 127 | } 128 | 129 | void loop(void) 130 | { 131 | // call sensors.requestTemperatures() to issue a global temperature 132 | // request to all devices on the bus 133 | Serial.print("Requesting temperatures..."); 134 | sensors.requestTemperatures(); 135 | Serial.println("DONE"); 136 | 137 | // Method 1: 138 | // check each address individually for an alarm condition 139 | checkAlarm(insideThermometer); 140 | checkAlarm(outsideThermometer); 141 | /* 142 | // Alternate method: 143 | // Search the bus and iterate through addresses of devices with alarms 144 | 145 | // space for the alarm device's address 146 | DeviceAddress alarmAddr; 147 | 148 | Serial.println("Searching for alarms..."); 149 | 150 | // resetAlarmSearch() must be called before calling alarmSearch() 151 | sensors.resetAlarmSearch(); 152 | 153 | // alarmSearch() returns 0 when there are no devices with alarms 154 | while (sensors.alarmSearch(alarmAddr)) 155 | { 156 | Serial.print("ALARM: "); 157 | printData(alarmAddr); 158 | } 159 | */ 160 | 161 | } 162 | -------------------------------------------------------------------------------- /examples/AlarmHandler/AlarmHandler.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Data wire is plugged into port 2 on the Arduino 5 | #define ONE_WIRE_BUS 2 6 | 7 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 8 | OneWire oneWire(ONE_WIRE_BUS); 9 | 10 | // Pass our oneWire reference to Dallas Temperature. 11 | DallasTemperature sensors(&oneWire); 12 | 13 | // arrays to hold device addresses 14 | DeviceAddress insideThermometer, outsideThermometer; 15 | 16 | // function that will be called when an alarm condition exists during DallasTemperatures::processAlarms(); 17 | void newAlarmHandler(const uint8_t* deviceAddress) 18 | { 19 | Serial.println("Alarm Handler Start"); 20 | printAlarmInfo(deviceAddress); 21 | printTemp(deviceAddress); 22 | Serial.println(); 23 | Serial.println("Alarm Handler Finish"); 24 | } 25 | 26 | void printCurrentTemp(DeviceAddress deviceAddress) 27 | { 28 | printAddress(deviceAddress); 29 | printTemp(deviceAddress); 30 | Serial.println(); 31 | } 32 | 33 | void printAddress(const DeviceAddress deviceAddress) 34 | { 35 | Serial.print("Address: "); 36 | for (uint8_t i = 0; i < 8; i++) 37 | { 38 | if (deviceAddress[i] < 16) Serial.print("0"); 39 | Serial.print(deviceAddress[i], HEX); 40 | } 41 | Serial.print(" "); 42 | } 43 | 44 | void printTemp(const DeviceAddress deviceAddress) 45 | { 46 | float tempC = sensors.getTempC(deviceAddress); 47 | if (tempC != DEVICE_DISCONNECTED_C) 48 | { 49 | Serial.print("Current Temp C: "); 50 | Serial.print(tempC); 51 | } 52 | else Serial.print("DEVICE DISCONNECTED"); 53 | Serial.print(" "); 54 | } 55 | 56 | void printAlarmInfo(const DeviceAddress deviceAddress) 57 | { 58 | char temp; 59 | printAddress(deviceAddress); 60 | temp = sensors.getHighAlarmTemp(deviceAddress); 61 | Serial.print("High Alarm: "); 62 | Serial.print(temp, DEC); 63 | Serial.print("C"); 64 | Serial.print(" Low Alarm: "); 65 | temp = sensors.getLowAlarmTemp(deviceAddress); 66 | Serial.print(temp, DEC); 67 | Serial.print("C"); 68 | Serial.print(" "); 69 | } 70 | 71 | void setup(void) 72 | { 73 | // start serial port 74 | Serial.begin(9600); 75 | Serial.println("Dallas Temperature IC Control Library Demo"); 76 | 77 | // Start up the library 78 | sensors.begin(); 79 | 80 | // locate devices on the bus 81 | Serial.print("Found "); 82 | Serial.print(sensors.getDeviceCount(), DEC); 83 | Serial.println(" devices."); 84 | 85 | // search for devices on the bus and assign based on an index 86 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 87 | if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 88 | 89 | Serial.print("Device insideThermometer "); 90 | printAlarmInfo(insideThermometer); 91 | Serial.println(); 92 | 93 | Serial.print("Device outsideThermometer "); 94 | printAlarmInfo(outsideThermometer); 95 | Serial.println(); 96 | 97 | // set alarm ranges 98 | Serial.println("Setting alarm temps..."); 99 | sensors.setHighAlarmTemp(insideThermometer, 26); 100 | sensors.setLowAlarmTemp(insideThermometer, 22); 101 | sensors.setHighAlarmTemp(outsideThermometer, 25); 102 | sensors.setLowAlarmTemp(outsideThermometer, 21); 103 | 104 | Serial.print("New insideThermometer "); 105 | printAlarmInfo(insideThermometer); 106 | Serial.println(); 107 | 108 | Serial.print("New outsideThermometer "); 109 | printAlarmInfo(outsideThermometer); 110 | Serial.println(); 111 | 112 | // attach alarm handler 113 | sensors.setAlarmHandler(&newAlarmHandler); 114 | 115 | } 116 | 117 | void loop(void) 118 | { 119 | // ask the devices to measure the temperature 120 | sensors.requestTemperatures(); 121 | 122 | // if an alarm condition exists as a result of the most recent 123 | // requestTemperatures() request, it exists until the next time 124 | // requestTemperatures() is called AND there isn't an alarm condition 125 | // on the device 126 | if (sensors.hasAlarm()) 127 | { 128 | Serial.println("Oh noes! There is at least one alarm on the bus."); 129 | } 130 | 131 | // call alarm handler function defined by sensors.setAlarmHandler 132 | // for each device reporting an alarm 133 | sensors.processAlarms(); 134 | 135 | if (!sensors.hasAlarm()) 136 | { 137 | // just print out the current temperature 138 | printCurrentTemp(insideThermometer); 139 | printCurrentTemp(outsideThermometer); 140 | } 141 | 142 | delay(1000); 143 | } 144 | -------------------------------------------------------------------------------- /examples/ESP-WebServer/ESP-WebServer.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* 7 | SETUP INSTRUCTIONS 8 | 9 | 1) Change WiFi SSID and Password: 10 | const char* ssid = "YourSSID"; 11 | const char* password = "YourPassword"; 12 | 13 | 2) Polling Interval (milliseconds): 14 | const unsigned long READ_INTERVAL = 10000; // 10 seconds 15 | 16 | 3) Number of Readings (History Length): 17 | const int HISTORY_LENGTH = 360; // 1 hour at 10-second intervals 18 | */ 19 | 20 | const char* ssid = "YourSSID"; 21 | const char* password = "YourPassword"; 22 | 23 | const int oneWireBus = 4; 24 | const int MAX_SENSORS = 8; 25 | const int HISTORY_LENGTH = 360; 26 | const unsigned long READ_INTERVAL = 10000; 27 | 28 | DeviceAddress sensorAddresses[MAX_SENSORS]; 29 | float tempHistory[MAX_SENSORS][HISTORY_LENGTH]; 30 | int historyIndex = 0; 31 | int numberOfDevices = 0; 32 | unsigned long lastReadTime = 0; 33 | 34 | OneWire oneWire(oneWireBus); 35 | DallasTemperature sensors(&oneWire); 36 | ESP8266WebServer server(80); 37 | 38 | String getAddressString(DeviceAddress deviceAddress); 39 | void handleRoot(); 40 | void handleSensorList(); 41 | void handleTemperature(); 42 | void handleHistory(); 43 | void updateHistory(); 44 | 45 | const char MAIN_page[] PROGMEM = R"=====( 46 | 47 | 48 | 49 | 50 | 52 | Arduino Temperature Control Library - Sensor Data Graph 53 | 54 | 56 | 57 | 58 |
59 |

60 | Arduino Temperature Control Library - Sensor Data 61 |

62 | 63 |
64 |
67 | Dashboard 68 |
69 |
72 | API Docs 73 |
74 |
77 | Setup 78 |
79 |
80 | 81 |
82 | 87 |
88 |
Loading sensor data...
89 |
90 |
91 | 92 | 143 | 144 | 153 |
154 | 155 |
156 |

© 2025 Miles Burton. All Rights Reserved.

157 |

158 | Licensed under the 159 | 160 | MIT License 161 | . 162 |

163 |
164 | 165 | 268 | 269 | 270 | )====="; 271 | 272 | void setup() { 273 | Serial.begin(115200); 274 | Serial.println(WiFi.localIP()); 275 | sensors.begin(); 276 | 277 | for (int i = 0; i < MAX_SENSORS; i++) { 278 | for (int j = 0; j < HISTORY_LENGTH; j++) { 279 | tempHistory[i][j] = 0; 280 | } 281 | } 282 | 283 | numberOfDevices = sensors.getDeviceCount(); 284 | if (numberOfDevices > MAX_SENSORS) { 285 | numberOfDevices = MAX_SENSORS; 286 | } 287 | 288 | for (int i = 0; i < numberOfDevices; i++) { 289 | sensors.getAddress(sensorAddresses[i], i); 290 | } 291 | 292 | sensors.setResolution(12); 293 | 294 | WiFi.begin(ssid, password); 295 | while (WiFi.status() != WL_CONNECTED) { 296 | delay(500); 297 | } 298 | 299 | server.on("/", HTTP_GET, handleRoot); 300 | server.on("/temperature", HTTP_GET, handleTemperature); 301 | server.on("/sensors", HTTP_GET, handleSensorList); 302 | server.on("/history", HTTP_GET, handleHistory); 303 | 304 | server.begin(); 305 | } 306 | 307 | void loop() { 308 | server.handleClient(); 309 | unsigned long t = millis(); 310 | if (t - lastReadTime >= READ_INTERVAL) { 311 | updateHistory(); 312 | lastReadTime = t; 313 | } 314 | } 315 | 316 | void updateHistory() { 317 | sensors.requestTemperatures(); 318 | for (int i = 0; i < numberOfDevices; i++) { 319 | float tempC = sensors.getTempC(sensorAddresses[i]); 320 | tempHistory[i][historyIndex] = tempC; 321 | } 322 | historyIndex = (historyIndex + 1) % HISTORY_LENGTH; 323 | } 324 | 325 | void handleRoot() { 326 | server.send(200, "text/html", MAIN_page); 327 | } 328 | 329 | void handleSensorList() { 330 | String json = "{\"sensors\":["; 331 | for (int i = 0; i < numberOfDevices; i++) { 332 | if (i > 0) json += ","; 333 | json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\"}"; 334 | } 335 | json += "]}"; 336 | server.send(200, "application/json", json); 337 | } 338 | 339 | void handleTemperature() { 340 | sensors.requestTemperatures(); 341 | String json = "{\"sensors\":["; 342 | for (int i = 0; i < numberOfDevices; i++) { 343 | if (i > 0) json += ","; 344 | float c = sensors.getTempC(sensorAddresses[i]); 345 | float f = sensors.toFahrenheit(c); 346 | json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\","; 347 | json += "\"celsius\":" + String(c) + ",\"fahrenheit\":" + String(f) + "}"; 348 | } 349 | json += "]}"; 350 | server.send(200, "application/json", json); 351 | } 352 | 353 | void handleHistory() { 354 | String json = "{\"interval_ms\":" + String(READ_INTERVAL) + ",\"sensors\":["; 355 | for (int i = 0; i < numberOfDevices; i++) { 356 | if (i > 0) json += ","; 357 | json += "{\"id\":" + String(i) + ",\"address\":\"" + getAddressString(sensorAddresses[i]) + "\",\"history\":["; 358 | for (int j = 0; j < HISTORY_LENGTH; j++) { 359 | int idx = (historyIndex - j + HISTORY_LENGTH) % HISTORY_LENGTH; 360 | if (j > 0) json += ","; 361 | json += String(tempHistory[i][idx]); 362 | } 363 | json += "]}"; 364 | } 365 | json += "]}"; 366 | server.send(200, "application/json", json); 367 | } 368 | 369 | String getAddressString(DeviceAddress deviceAddress) { 370 | String addr; 371 | for (uint8_t i = 0; i < 8; i++) { 372 | if (deviceAddress[i] < 16) addr += "0"; 373 | addr += String(deviceAddress[i], HEX); 374 | } 375 | return addr; 376 | } 377 | -------------------------------------------------------------------------------- /examples/ESP-WebServer/README.md: -------------------------------------------------------------------------------- 1 | # 🌡️ Arduino Sketch: DS18B20 Sensor via Wi-Fi (REST Endpoints & Dashboard) 2 | 3 | This **example Sketch** demonstrates how to use the [Arduino Temperature Control Library](https://github.com/milesburton/Arduino-Temperature-Control-Library) on an **ESP8266** or **ESP32** to read temperature data from **Maxim (Dallas) DS18B20** sensors. The Sketch publishes the readings via Wi-Fi in two ways: 4 | 5 | 1. **REST Endpoints** - Ideal for Node-RED, Home Assistant, or other automation platforms. 6 | 2. **A Human-Friendly Dashboard** - A simple web interface, powered by [Chart.js](https://www.chartjs.org/) and [Tailwind CSS](https://tailwindcss.com/), displaying current and historical temperatures. 7 | 8 | --- 9 | 10 | ## 🔎 Features 11 | - Reads from one or more **DS18B20** temperature sensors 12 | - Configurable **polling interval** (in milliseconds) and **history length** (number of readings) 13 | - **Lightweight dashboard** that visualises the last N readings 14 | - **REST endpoints** for easy integration: 15 | - `/temperature` - current readings 16 | - `/sensors` - sensor addresses 17 | - `/history` - historical data 18 | 19 | --- 20 | 21 | ## 📚 Potential Use Cases 22 | - **Node-RED** automation flows: Perform regular HTTP GET requests against `/temperature` or `/history` 23 | - **Home Assistant** integrations: Use built-in REST sensors to track temperature over time 24 | - **Extensible to other sensor types** (humidity, light, pressure, etc.) by following the same approach 25 | 26 | --- 27 | 28 | ## 🛠️ Getting Started 29 | 1. **Clone or download** this repository 30 | 2. **Open the Sketch** (the `.ino` file) in the Arduino IDE (or other environment) 31 | 3. **Install dependencies**: 32 | - [Arduino Temperature Control Library](https://github.com/milesburton/Arduino-Temperature-Control-Library) 33 | - ESP8266 or ESP32 core for Arduino 34 | 4. **Set your Wi-Fi credentials** in the code: 35 | ```cpp 36 | const char* ssid = "YourNetwork"; 37 | const char* password = "YourPassword"; 38 | ``` 39 | 5. **Adjust** the interval and history: 40 | ```cpp 41 | // Configuration 42 | const unsigned long READ_INTERVAL = 10000; // e.g. 10 seconds 43 | const int HISTORY_LENGTH = 360; // 1 hour at 10-second intervals 44 | ``` 45 | 6. **Connect** the DS18B20 sensor(s) to the ESP, using OneWire with a pull-up resistor 46 | 7. **Upload** the Sketch to your device 47 | 8. **Check** the serial monitor for the IP 48 | 9. **Navigate** to that IP in your browser to see the chart-based interface 49 | 50 | --- 51 | 52 | ## ❓ Questions & Support 53 | - **Library Matters**: If you have issues with the **Arduino Temperature Control Library** itself, please open a ticket in the [official repository](https://github.com/milesburton/Arduino-Temperature-Control-Library/issues) 54 | - **This Sketch**: For help customising this example, dealing with Wi-Fi issues, or setting up the chart dashboard, and other device-specific tweaks, please visit the [Arduino Forum](https://forum.arduino.cc/). You will find many friendly developers there ready to help. 55 | 56 | --- 57 | 58 | ## 📜 License 59 | This project is distributed under the [MIT License](https://opensource.org/licenses/MIT). 60 | 61 | --- 62 | 63 | We hope you find this Sketch useful for monitoring temperatures - both in a machine-readable (REST) and human-friendly (web dashboard) format. Happy hacking! 🚀 64 | -------------------------------------------------------------------------------- /examples/ExternalPullup/ExternalPullup.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Data wire is plugged into port 2 on the Arduino, while external pullup P-MOSFET gate into port 3 5 | #define ONE_WIRE_BUS 2 6 | #define ONE_WIRE_PULLUP 3 7 | 8 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 9 | OneWire oneWire(ONE_WIRE_BUS); 10 | 11 | // Pass our oneWire reference to Dallas Temperature. 12 | DallasTemperature sensors(&oneWire, ONE_WIRE_PULLUP); 13 | 14 | void setup(void) 15 | { 16 | // start serial port 17 | Serial.begin(9600); 18 | Serial.println("Dallas Temperature IC Control Library Demo"); 19 | 20 | // Start up the library 21 | sensors.begin(); 22 | } 23 | 24 | void loop(void) 25 | { 26 | // call sensors.requestTemperatures() to issue a global temperature 27 | // request to all devices on the bus 28 | Serial.print("Requesting temperatures..."); 29 | sensors.requestTemperatures(); // Send the command to get temperatures 30 | Serial.println("DONE"); 31 | 32 | for (int i = 0; i < sensors.getDeviceCount(); i++) { 33 | Serial.println("Temperature for Device " + String(i) + " is: " + String(sensors.getTempCByIndex(i))); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/Multibus_simple/Multibus_simple.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | OneWire ds18x20[] = { 3, 7 }; 5 | const int oneWireCount = sizeof(ds18x20) / sizeof(OneWire); 6 | DallasTemperature sensor[oneWireCount]; 7 | 8 | void setup(void) { 9 | // start serial port 10 | Serial.begin(9600); 11 | Serial.println("Dallas Temperature Multiple Bus Control Library Simple Demo"); 12 | Serial.print("============Ready with "); 13 | Serial.print(oneWireCount); 14 | Serial.println(" Sensors================"); 15 | 16 | // Start up the library on all defined bus-wires 17 | DeviceAddress deviceAddress; 18 | for (int i = 0; i < oneWireCount; i++) { 19 | sensor[i].setOneWire(&ds18x20[i]); 20 | sensor[i].begin(); 21 | if (sensor[i].getAddress(deviceAddress, 0)) sensor[i].setResolution(deviceAddress, 12); 22 | } 23 | } 24 | 25 | void loop(void) { 26 | // call sensors.requestTemperatures() to issue a global temperature 27 | // request to all devices on the bus 28 | Serial.print("Requesting temperatures..."); 29 | for (int i = 0; i < oneWireCount; i++) { 30 | sensor[i].requestTemperatures(); 31 | } 32 | Serial.println("DONE"); 33 | 34 | delay(1000); 35 | for (int i = 0; i < oneWireCount; i++) { 36 | float temperature = sensor[i].getTempCByIndex(0); 37 | Serial.print("Temperature for the sensor "); 38 | Serial.print(i); 39 | Serial.print(" is "); 40 | Serial.println(temperature); 41 | } 42 | Serial.println(); 43 | } 44 | -------------------------------------------------------------------------------- /examples/Multiple/Multiple.ino: -------------------------------------------------------------------------------- 1 | // Include the libraries we need 2 | #include 3 | #include 4 | 5 | // Data wire is plugged into port 2 on the Arduino 6 | #define ONE_WIRE_BUS 2 7 | #define TEMPERATURE_PRECISION 9 8 | 9 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 10 | OneWire oneWire(ONE_WIRE_BUS); 11 | 12 | // Pass our oneWire reference to Dallas Temperature. 13 | DallasTemperature sensors(&oneWire); 14 | 15 | // arrays to hold device addresses 16 | DeviceAddress insideThermometer, outsideThermometer; 17 | 18 | // Assign address manually. The addresses below will need to be changed 19 | // to valid device addresses on your bus. Device address can be retrieved 20 | // by using either oneWire.search(deviceAddress) or individually via 21 | // sensors.getAddress(deviceAddress, index) 22 | // DeviceAddress insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; 23 | // DeviceAddress outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 }; 24 | 25 | void setup(void) 26 | { 27 | // start serial port 28 | Serial.begin(9600); 29 | Serial.println("Dallas Temperature IC Control Library Demo"); 30 | 31 | // Start up the library 32 | sensors.begin(); 33 | 34 | // locate devices on the bus 35 | Serial.print("Locating devices..."); 36 | Serial.print("Found "); 37 | Serial.print(sensors.getDeviceCount(), DEC); 38 | Serial.println(" devices."); 39 | 40 | // report parasite power requirements 41 | Serial.print("Parasite power is: "); 42 | if (sensors.isParasitePowerMode()) Serial.println("ON"); 43 | else Serial.println("OFF"); 44 | 45 | // Search for devices on the bus and assign based on an index. Ideally, 46 | // you would do this to initially discover addresses on the bus and then 47 | // use those addresses and manually assign them (see above) once you know 48 | // the devices on your bus (and assuming they don't change). 49 | // 50 | // method 1: by index 51 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 52 | if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 53 | 54 | // method 2: search() 55 | // search() looks for the next device. Returns 1 if a new address has been 56 | // returned. A zero might mean that the bus is shorted, there are no devices, 57 | // or you have already retrieved all of them. It might be a good idea to 58 | // check the CRC to make sure you didn't get garbage. The order is 59 | // deterministic. You will always get the same devices in the same order 60 | // 61 | // Must be called before search() 62 | //oneWire.reset_search(); 63 | // assigns the first address found to insideThermometer 64 | //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); 65 | // assigns the seconds address found to outsideThermometer 66 | //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer"); 67 | 68 | // show the addresses we found on the bus 69 | Serial.print("Device 0 Address: "); 70 | printAddress(insideThermometer); 71 | Serial.println(); 72 | 73 | Serial.print("Device 1 Address: "); 74 | printAddress(outsideThermometer); 75 | Serial.println(); 76 | 77 | // set the resolution to 9 bit per device 78 | sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION); 79 | sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION); 80 | 81 | Serial.print("Device 0 Resolution: "); 82 | Serial.print(sensors.getResolution(insideThermometer), DEC); 83 | Serial.println(); 84 | 85 | Serial.print("Device 1 Resolution: "); 86 | Serial.print(sensors.getResolution(outsideThermometer), DEC); 87 | Serial.println(); 88 | } 89 | 90 | // function to print a device address 91 | void printAddress(DeviceAddress deviceAddress) 92 | { 93 | for (uint8_t i = 0; i < 8; i++) 94 | { 95 | // zero pad the address if necessary 96 | if (deviceAddress[i] < 16) Serial.print("0"); 97 | Serial.print(deviceAddress[i], HEX); 98 | } 99 | } 100 | 101 | // function to print the temperature for a device 102 | void printTemperature(DeviceAddress deviceAddress) 103 | { 104 | float tempC = sensors.getTempC(deviceAddress); 105 | if (tempC == DEVICE_DISCONNECTED_C) 106 | { 107 | Serial.println("Error: Could not read temperature data"); 108 | return; 109 | } 110 | Serial.print("Temp C: "); 111 | Serial.print(tempC); 112 | Serial.print(" Temp F: "); 113 | Serial.print(DallasTemperature::toFahrenheit(tempC)); 114 | } 115 | 116 | // function to print a device's resolution 117 | void printResolution(DeviceAddress deviceAddress) 118 | { 119 | Serial.print("Resolution: "); 120 | Serial.print(sensors.getResolution(deviceAddress)); 121 | Serial.println(); 122 | } 123 | 124 | // main function to print information about a device 125 | void printData(DeviceAddress deviceAddress) 126 | { 127 | Serial.print("Device Address: "); 128 | printAddress(deviceAddress); 129 | Serial.print(" "); 130 | printTemperature(deviceAddress); 131 | Serial.println(); 132 | } 133 | 134 | /* 135 | Main function, calls the temperatures in a loop. 136 | */ 137 | void loop(void) 138 | { 139 | // call sensors.requestTemperatures() to issue a global temperature 140 | // request to all devices on the bus 141 | Serial.print("Requesting temperatures..."); 142 | sensors.requestTemperatures(); 143 | Serial.println("DONE"); 144 | 145 | // print the device information 146 | printData(insideThermometer); 147 | printData(outsideThermometer); 148 | } 149 | -------------------------------------------------------------------------------- /examples/SaveRecallScratchPad/SaveRecallScratchPad.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: SaveRecallScratchPad.ino 3 | // AUTHOR: GitKomodo 4 | // VERSION: 0.0.1 5 | // PURPOSE: Show DallasTemperature lib functionality to 6 | // save/recall ScratchPad values to/from EEPROM 7 | // 8 | // HISTORY: 9 | // 0.0.1 = 2020-02-18 initial version 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define ONE_WIRE_BUS 2 16 | 17 | OneWire oneWire(ONE_WIRE_BUS); 18 | DallasTemperature sensors(&oneWire); 19 | DeviceAddress deviceAddress; 20 | 21 | void setup() 22 | { 23 | Serial.begin(9600); 24 | Serial.println(__FILE__); 25 | Serial.println("Dallas Temperature Demo"); 26 | 27 | sensors.begin(); 28 | 29 | // Get ID of first sensor (at index 0) 30 | sensors.getAddress(deviceAddress, 0); 31 | 32 | // By default configuration and alarm/userdata registers are also saved to EEPROM 33 | // when they're changed. Sensors recall these values automatically when powered up. 34 | 35 | // Turn OFF automatic saving of configuration and alarm/userdata registers to EEPROM 36 | sensors.setAutoSaveScratchPad(false); 37 | 38 | // Change configuration and alarm/userdata registers on the scratchpad 39 | int8_t resolution = 12; 40 | sensors.setResolution(deviceAddress, resolution); 41 | int16_t userdata = 24680; 42 | sensors.setUserData(deviceAddress, userdata); 43 | 44 | // Save configuration and alarm/userdata registers to EEPROM 45 | sensors.saveScratchPad(deviceAddress); 46 | 47 | // saveScratchPad can also be used without a parameter to save the configuration 48 | // and alarm/userdata registers of ALL connected sensors to EEPROM: 49 | // 50 | // sensors.saveScratchPad(); 51 | // 52 | // Or the configuration and alarm/userdata registers of a sensor can be saved to 53 | // EEPROM by index: 54 | // 55 | // sensors.saveScratchPadByIndex(0); 56 | 57 | // Print current values on the scratchpad (resolution = 12, userdata = 24680) 58 | printValues(); 59 | 60 | } 61 | 62 | void loop() { 63 | 64 | // Change configuration and alarm/userdata registers on the scratchpad 65 | int8_t resolution = 10; 66 | sensors.setResolution(deviceAddress, resolution); 67 | int16_t userdata = 12345; 68 | sensors.setUserData(deviceAddress, userdata); 69 | 70 | // Print current values on the scratchpad (resolution = 10, userdata = 12345) 71 | printValues(); 72 | 73 | delay(2000); 74 | 75 | // Recall configuration and alarm/userdata registers from EEPROM 76 | sensors.recallScratchPad(deviceAddress); 77 | 78 | // recallScratchPad can also be used without a parameter to recall the configuration 79 | // and alarm/userdata registers of ALL connected sensors from EEPROM: 80 | // 81 | // sensors.recallScratchPad(); 82 | // 83 | // Or the configuration and alarm/userdata registers of a sensor can be recalled 84 | // from EEPROM by index: 85 | // 86 | // sensors.recallScratchPadByIndex(0); 87 | 88 | // Print current values on the scratchpad (resolution = 12, userdata = 24680) 89 | printValues(); 90 | 91 | delay(2000); 92 | 93 | } 94 | 95 | void printValues() { 96 | 97 | Serial.println(); 98 | Serial.println("Current values on the scratchpad:"); 99 | 100 | Serial.print("Resolution:\t"); 101 | Serial.println(sensors.getResolution(deviceAddress)); 102 | 103 | Serial.print("User data:\t"); 104 | Serial.println(sensors.getUserData(deviceAddress)); 105 | 106 | } 107 | -------------------------------------------------------------------------------- /examples/SetUserData/SetUserData.ino: -------------------------------------------------------------------------------- 1 | // 2 | // This sketch does not use the ALARM registers and uses those 2 bytes as a counter 3 | // these 2 bytes can be used for other purposes as well e.g. last temperature or 4 | // a specific ID. 5 | // 6 | 7 | #include 8 | #include 9 | 10 | // Data wire is plugged into port 2 on the Arduino 11 | #define ONE_WIRE_BUS 2 12 | 13 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 14 | OneWire oneWire(ONE_WIRE_BUS); 15 | 16 | // Pass our oneWire reference to Dallas Temperature. 17 | DallasTemperature sensors(&oneWire); 18 | 19 | int count = 0; 20 | 21 | void setup(void) 22 | { 23 | // start serial port 24 | Serial.begin(9600); 25 | Serial.println("Dallas Temperature IC Control Library Demo"); 26 | 27 | // Start up the library 28 | sensors.begin(); 29 | 30 | } 31 | 32 | void loop(void) 33 | { 34 | // call sensors.requestTemperatures() to issue a global temperature 35 | // request to all devices on the bus 36 | Serial.print("Requesting temperatures..."); 37 | sensors.requestTemperatures(); // Send the command to get temperatures 38 | Serial.println("DONE"); 39 | 40 | Serial.print("Temperature for the device 1 (index 0) is: "); 41 | Serial.println(sensors.getTempCByIndex(0)); 42 | 43 | count++; 44 | sensors.setUserDataByIndex(0, count); 45 | int x = sensors.getUserDataByIndex(0); 46 | Serial.println(count); 47 | } 48 | -------------------------------------------------------------------------------- /examples/Simple/Simple.ino: -------------------------------------------------------------------------------- 1 | // Include the libraries we need 2 | #include 3 | #include 4 | 5 | // Data wire is plugged into port 2 on the Arduino 6 | #define ONE_WIRE_BUS 2 7 | 8 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 9 | OneWire oneWire(ONE_WIRE_BUS); 10 | 11 | // Pass our oneWire reference to Dallas Temperature. 12 | DallasTemperature sensors(&oneWire); 13 | 14 | /* 15 | * The setup function. We only start the sensors here 16 | */ 17 | void setup(void) 18 | { 19 | // start serial port 20 | Serial.begin(9600); 21 | Serial.println("Dallas Temperature IC Control Library Demo"); 22 | 23 | // Start up the library 24 | sensors.begin(); 25 | } 26 | 27 | /* 28 | * Main function, get and show the temperature 29 | */ 30 | void loop(void) 31 | { 32 | // call sensors.requestTemperatures() to issue a global temperature 33 | // request to all devices on the bus 34 | Serial.print("Requesting temperatures..."); 35 | sensors.requestTemperatures(); // Send the command to get temperatures 36 | Serial.println("DONE"); 37 | delay(1500); 38 | // After we got the temperatures, we can print them here. 39 | // We use the function ByIndex, and as an example get the temperature from the first sensor only. 40 | float tempC = sensors.getTempCByIndex(0); 41 | 42 | // Check if reading was successful 43 | if (tempC != DEVICE_DISCONNECTED_C) 44 | { 45 | Serial.print("Temperature for the device 1 (index 0) is: "); 46 | Serial.println(tempC); 47 | } 48 | else 49 | { 50 | Serial.println("Error: Could not read temperature data"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /examples/Single/Single.ino: -------------------------------------------------------------------------------- 1 | // Include the libraries we need 2 | #include 3 | #include 4 | 5 | // Data wire is plugged into port 2 on the Arduino 6 | #define ONE_WIRE_BUS 2 7 | 8 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 9 | OneWire oneWire(ONE_WIRE_BUS); 10 | 11 | // Pass our oneWire reference to Dallas Temperature. 12 | DallasTemperature sensors(&oneWire); 13 | 14 | // arrays to hold device address 15 | DeviceAddress insideThermometer; 16 | 17 | /* 18 | * Setup function. Here we do the basics 19 | */ 20 | void setup(void) 21 | { 22 | // start serial port 23 | Serial.begin(9600); 24 | Serial.println("Dallas Temperature IC Control Library Demo"); 25 | 26 | // locate devices on the bus 27 | Serial.print("Locating devices..."); 28 | sensors.begin(); 29 | Serial.print("Found "); 30 | Serial.print(sensors.getDeviceCount(), DEC); 31 | Serial.println(" devices."); 32 | 33 | // report parasite power requirements 34 | Serial.print("Parasite power is: "); 35 | if (sensors.isParasitePowerMode()) Serial.println("ON"); 36 | else Serial.println("OFF"); 37 | 38 | // Assign address manually. The addresses below will need to be changed 39 | // to valid device addresses on your bus. Device address can be retrieved 40 | // by using either oneWire.search(deviceAddress) or individually via 41 | // sensors.getAddress(deviceAddress, index) 42 | // Note that you will need to use your specific address here 43 | //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; 44 | 45 | // Method 1: 46 | // Search for devices on the bus and assign based on an index. Ideally, 47 | // you would do this to initially discover addresses on the bus and then 48 | // use those addresses and manually assign them (see above) once you know 49 | // the devices on your bus (and assuming they don't change). 50 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 51 | 52 | // method 2: search() 53 | // search() looks for the next device. Returns 1 if a new address has been 54 | // returned. A zero might mean that the bus is shorted, there are no devices, 55 | // or you have already retrieved all of them. It might be a good idea to 56 | // check the CRC to make sure you didn't get garbage. The order is 57 | // deterministic. You will always get the same devices in the same order 58 | // 59 | // Must be called before search() 60 | //oneWire.reset_search(); 61 | // assigns the first address found to insideThermometer 62 | //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer"); 63 | 64 | // show the addresses we found on the bus 65 | Serial.print("Device 0 Address: "); 66 | printAddress(insideThermometer); 67 | Serial.println(); 68 | 69 | // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions) 70 | sensors.setResolution(insideThermometer, 9); 71 | 72 | Serial.print("Device 0 Resolution: "); 73 | Serial.print(sensors.getResolution(insideThermometer), DEC); 74 | Serial.println(); 75 | } 76 | 77 | // function to print the temperature for a device 78 | void printTemperature(DeviceAddress deviceAddress) 79 | { 80 | // method 1 - slower 81 | //Serial.print("Temp C: "); 82 | //Serial.print(sensors.getTempC(deviceAddress)); 83 | //Serial.print(" Temp F: "); 84 | //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit 85 | 86 | // method 2 - faster 87 | float tempC = sensors.getTempC(deviceAddress); 88 | if (tempC == DEVICE_DISCONNECTED_C) 89 | { 90 | Serial.println("Error: Could not read temperature data"); 91 | return; 92 | } 93 | Serial.print("Temp C: "); 94 | Serial.print(tempC); 95 | Serial.print(" Temp F: "); 96 | Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit 97 | } 98 | /* 99 | * Main function. It will request the tempC from the sensors and display on Serial. 100 | */ 101 | void loop(void) 102 | { 103 | // call sensors.requestTemperatures() to issue a global temperature 104 | // request to all devices on the bus 105 | Serial.print("Requesting temperatures..."); 106 | sensors.requestTemperatures(); // Send the command to get temperatures 107 | Serial.println("DONE"); 108 | delay(1500); 109 | 110 | // It responds almost immediately. Let's print out the data 111 | printTemperature(insideThermometer); // Use a simple function to print out the data 112 | } 113 | 114 | // function to print a device address 115 | void printAddress(DeviceAddress deviceAddress) 116 | { 117 | for (uint8_t i = 0; i < 8; i++) 118 | { 119 | if (deviceAddress[i] < 16) Serial.print("0"); 120 | Serial.print(deviceAddress[i], HEX); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /examples/Tester/Tester.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Data wire is plugged into port 2 on the Arduino 5 | #define ONE_WIRE_BUS 2 6 | #define TEMPERATURE_PRECISION 9 // Lower resolution 7 | 8 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 9 | OneWire oneWire(ONE_WIRE_BUS); 10 | 11 | // Pass our oneWire reference to Dallas Temperature. 12 | DallasTemperature sensors(&oneWire); 13 | 14 | int numberOfDevices; // Number of temperature devices found 15 | 16 | DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address 17 | 18 | void setup(void) 19 | { 20 | // start serial port 21 | Serial.begin(9600); 22 | Serial.println("Dallas Temperature IC Control Library Demo"); 23 | 24 | // Start up the library 25 | sensors.begin(); 26 | 27 | // Grab a count of devices on the wire 28 | numberOfDevices = sensors.getDeviceCount(); 29 | 30 | // locate devices on the bus 31 | Serial.print("Locating devices..."); 32 | 33 | Serial.print("Found "); 34 | Serial.print(numberOfDevices, DEC); 35 | Serial.println(" devices."); 36 | 37 | // report parasite power requirements 38 | Serial.print("Parasite power is: "); 39 | if (sensors.isParasitePowerMode()) Serial.println("ON"); 40 | else Serial.println("OFF"); 41 | 42 | // Loop through each device, print out address 43 | for (int i = 0; i < numberOfDevices; i++) 44 | { 45 | // Search the wire for address 46 | if (sensors.getAddress(tempDeviceAddress, i)) 47 | { 48 | Serial.print("Found device "); 49 | Serial.print(i, DEC); 50 | Serial.print(" with address: "); 51 | printAddress(tempDeviceAddress); 52 | Serial.println(); 53 | 54 | Serial.print("Setting resolution to "); 55 | Serial.println(TEMPERATURE_PRECISION, DEC); 56 | 57 | // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions) 58 | sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); 59 | 60 | Serial.print("Resolution actually set to: "); 61 | Serial.print(sensors.getResolution(tempDeviceAddress), DEC); 62 | Serial.println(); 63 | } else { 64 | Serial.print("Found ghost device at "); 65 | Serial.print(i, DEC); 66 | Serial.print(" but could not detect address. Check power and cabling"); 67 | } 68 | } 69 | 70 | } 71 | 72 | // function to print the temperature for a device 73 | void printTemperature(DeviceAddress deviceAddress) 74 | { 75 | // method 1 - slower 76 | //Serial.print("Temp C: "); 77 | //Serial.print(sensors.getTempC(deviceAddress)); 78 | //Serial.print(" Temp F: "); 79 | //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit 80 | 81 | // method 2 - faster 82 | float tempC = sensors.getTempC(deviceAddress); 83 | if (tempC == DEVICE_DISCONNECTED_C) 84 | { 85 | Serial.println("Error: Could not read temperature data"); 86 | return; 87 | } 88 | Serial.print("Temp C: "); 89 | Serial.print(tempC); 90 | Serial.print(" Temp F: "); 91 | Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit 92 | } 93 | 94 | void loop(void) 95 | { 96 | // call sensors.requestTemperatures() to issue a global temperature 97 | // request to all devices on the bus 98 | Serial.print("Requesting temperatures..."); 99 | sensors.requestTemperatures(); // Send the command to get temperatures 100 | Serial.println("DONE"); 101 | 102 | 103 | // Loop through each device, print out temperature data 104 | for (int i = 0; i < numberOfDevices; i++) 105 | { 106 | // Search the wire for address 107 | if (sensors.getAddress(tempDeviceAddress, i)) 108 | { 109 | // Output the device ID 110 | Serial.print("Temperature for device: "); 111 | Serial.println(i, DEC); 112 | 113 | // It responds almost immediately. Let's print out the data 114 | printTemperature(tempDeviceAddress); // Use a simple function to print out the data 115 | } 116 | //else ghost device! Check your power requirements and cabling 117 | 118 | } 119 | } 120 | 121 | // function to print a device address 122 | void printAddress(DeviceAddress deviceAddress) 123 | { 124 | for (uint8_t i = 0; i < 8; i++) 125 | { 126 | if (deviceAddress[i] < 16) Serial.print("0"); 127 | Serial.print(deviceAddress[i], HEX); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /examples/Timing/Timing.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: Timing.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.0.3 5 | // PURPOSE: show performance of DallasTemperature lib 6 | // compared to datasheet times per resolution 7 | // 8 | // HISTORY: 9 | // 0.0.1 2017-07-25 initial version 10 | // 0.0.2 2020-02-13 updates to work with current lib version 11 | // 0.0.3 2020-02-20 added timing measurement of setResolution 12 | 13 | #include 14 | #include 15 | 16 | #define ONE_WIRE_BUS 2 17 | 18 | OneWire oneWire(ONE_WIRE_BUS); 19 | DallasTemperature sensor(&oneWire); 20 | 21 | uint32_t start, stop; 22 | 23 | 24 | void setup() 25 | { 26 | Serial.begin(9600); 27 | Serial.println(__FILE__); 28 | Serial.print("DallasTemperature Library version: "); 29 | Serial.println(DALLASTEMPLIBVERSION); 30 | 31 | sensor.begin(); 32 | } 33 | 34 | void loop() 35 | { 36 | float ti[4] = { 94, 188, 375, 750 }; 37 | 38 | Serial.println(); 39 | Serial.println("Test takes about 30 seconds for 4 resolutions"); 40 | Serial.println("RES\tTIME\tACTUAL\tGAIN"); 41 | for (int r = 9; r < 13; r++) 42 | { 43 | start = micros(); 44 | sensor.setResolution(r); 45 | Serial.println(micros() - start); 46 | 47 | start = micros(); 48 | sensor.setResolution(r); 49 | Serial.println(micros() - start); 50 | 51 | uint32_t duration = run(20); 52 | float avgDuration = duration / 20.0; 53 | 54 | Serial.print(r); 55 | Serial.print("\t"); 56 | Serial.print(ti[r - 9]); 57 | Serial.print("\t"); 58 | Serial.print(avgDuration, 2); 59 | Serial.print("\t"); 60 | Serial.print(avgDuration * 100 / ti[r - 9], 1); 61 | Serial.println("%"); 62 | } 63 | delay(1000); 64 | } 65 | 66 | uint32_t run(int runs) 67 | { 68 | float t; 69 | start = millis(); 70 | for (int i = 0; i < runs; i++) 71 | { 72 | sensor.requestTemperatures(); 73 | t = sensor.getTempCByIndex(0); 74 | } 75 | stop = millis(); 76 | return stop - start; 77 | } 78 | -------------------------------------------------------------------------------- /examples/TwoPin_DS18B20/TwoPin_DS18B20.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: TwoPin_DS18B20.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.1.00 5 | // PURPOSE: two pins for two sensors demo 6 | // DATE: 2014-06-13 7 | // URL: http://forum.arduino.cc/index.php?topic=216835.msg1764333#msg1764333 8 | // 9 | // Released to the public domain 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define ONE_WIRE_BUS_1 2 16 | #define ONE_WIRE_BUS_2 4 17 | 18 | OneWire oneWire_in(ONE_WIRE_BUS_1); 19 | OneWire oneWire_out(ONE_WIRE_BUS_2); 20 | 21 | DallasTemperature sensor_inhouse(&oneWire_in); 22 | DallasTemperature sensor_outhouse(&oneWire_out); 23 | 24 | void setup(void) 25 | { 26 | Serial.begin(9600); 27 | Serial.println("Dallas Temperature Control Library Demo - TwoPin_DS18B20"); 28 | 29 | sensor_inhouse.begin(); 30 | sensor_outhouse.begin(); 31 | } 32 | 33 | void loop(void) 34 | { 35 | Serial.print("Requesting temperatures..."); 36 | sensor_inhouse.requestTemperatures(); 37 | sensor_outhouse.requestTemperatures(); 38 | Serial.println(" done"); 39 | 40 | Serial.print("Inhouse: "); 41 | Serial.println(sensor_inhouse.getTempCByIndex(0)); 42 | 43 | Serial.print("Outhouse: "); 44 | Serial.println(sensor_outhouse.getTempCByIndex(0)); 45 | } -------------------------------------------------------------------------------- /examples/UserDataDemo/UserDataDemo.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: UserDataDemo.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.1.0 5 | // PURPOSE: use of alarm field as user identification demo 6 | // DATE: 2019-12-23 7 | // URL: 8 | // 9 | // Released to the public domain 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define ONE_WIRE_BUS 2 16 | 17 | OneWire oneWire(ONE_WIRE_BUS); 18 | DallasTemperature sensors(&oneWire); 19 | 20 | uint8_t deviceCount = 0; 21 | 22 | // Add 4 prepared sensors to the bus 23 | // use the UserDataWriteBatch demo to prepare 4 different labeled sensors 24 | struct 25 | { 26 | int id; 27 | DeviceAddress addr; 28 | } T[4]; 29 | 30 | float getTempByID(int id) 31 | { 32 | for (uint8_t index = 0; index < deviceCount; index++) 33 | { 34 | if (T[index].id == id) 35 | { 36 | return sensors.getTempC(T[index].addr); 37 | } 38 | } 39 | return -999; 40 | } 41 | 42 | void printAddress(DeviceAddress deviceAddress) 43 | { 44 | for (uint8_t i = 0; i < 8; i++) 45 | { 46 | // zero pad the address if necessary 47 | if (deviceAddress[i] < 16) Serial.print("0"); 48 | Serial.print(deviceAddress[i], HEX); 49 | } 50 | } 51 | 52 | void setup(void) 53 | { 54 | Serial.begin(115200); 55 | Serial.println(__FILE__); 56 | Serial.println("Dallas Temperature Demo"); 57 | 58 | sensors.begin(); 59 | 60 | // count devices 61 | deviceCount = sensors.getDeviceCount(); 62 | Serial.print("#devices: "); 63 | Serial.println(deviceCount); 64 | 65 | // Read ID's per sensor 66 | // and put them in T array 67 | for (uint8_t index = 0; index < deviceCount; index++) 68 | { 69 | // go through sensors 70 | sensors.getAddress(T[index].addr, index); 71 | T[index].id = sensors.getUserData(T[index].addr); 72 | } 73 | 74 | // Check all 4 sensors are set 75 | for (uint8_t index = 0; index < deviceCount; index++) 76 | { 77 | Serial.println(); 78 | Serial.println(T[index].id); 79 | printAddress(T[index].addr); 80 | Serial.println(); 81 | } 82 | Serial.println(); 83 | 84 | } 85 | 86 | 87 | void loop(void) 88 | { 89 | Serial.println(); 90 | Serial.print(millis()); 91 | Serial.println("\treq temp"); 92 | sensors.requestTemperatures(); 93 | 94 | Serial.print(millis()); 95 | Serial.println("\tGet temp by address"); 96 | for (int i = 0; i < 4; i++) 97 | { 98 | Serial.print(millis()); 99 | Serial.print("\t temp:\t"); 100 | Serial.println(sensors.getTempC(T[i].addr)); 101 | } 102 | 103 | Serial.print(millis()); 104 | Serial.println("\tGet temp by ID"); // assume ID = 0, 1, 2, 3 105 | for (int id = 0; id < 4; id++) 106 | { 107 | Serial.print(millis()); 108 | Serial.print("\t temp:\t"); 109 | Serial.println(getTempByID(id)); 110 | } 111 | 112 | delay(1000); 113 | } 114 | 115 | // END OF FILE -------------------------------------------------------------------------------- /examples/UserDataWriteBatch/UserDataWriteBatch.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: UserDataWriteBatch.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.1.0 5 | // PURPOSE: use of alarm field as user identification demo 6 | // DATE: 2019-12-23 7 | // URL: 8 | // 9 | // Released to the public domain 10 | // 11 | 12 | #include 13 | #include 14 | 15 | #define ONE_WIRE_BUS 2 16 | 17 | OneWire oneWire(ONE_WIRE_BUS); 18 | DallasTemperature sensors(&oneWire); 19 | 20 | uint8_t deviceCount = 0; 21 | 22 | void printAddress(DeviceAddress deviceAddress) 23 | { 24 | for (uint8_t i = 0; i < 8; i++) 25 | { 26 | // zero pad the address if necessary 27 | if (deviceAddress[i] < 16) Serial.print("0"); 28 | Serial.print(deviceAddress[i], HEX); 29 | } 30 | } 31 | 32 | 33 | 34 | void setup(void) 35 | { 36 | Serial.begin(115200); 37 | Serial.println(__FILE__); 38 | Serial.println("Write user ID to DS18B20\n"); 39 | 40 | sensors.begin(); 41 | 42 | // count devices 43 | deviceCount = sensors.getDeviceCount(); 44 | Serial.print("#devices: "); 45 | Serial.println(deviceCount); 46 | 47 | Serial.println(); 48 | Serial.println("current ID's"); 49 | for (uint8_t index = 0; index < deviceCount; index++) 50 | { 51 | DeviceAddress t; 52 | sensors.getAddress(t, index); 53 | printAddress(t); 54 | Serial.print("\t\tID: "); 55 | int id = sensors.getUserData(t); 56 | Serial.println(id); 57 | } 58 | 59 | Serial.println(); 60 | Serial.print("Enter ID for batch: "); 61 | int c = 0; 62 | int id = 0; 63 | while (c != '\n' && c != '\r') 64 | { 65 | c = Serial.read(); 66 | switch (c) 67 | { 68 | case '0'...'9': 69 | id *= 10; 70 | id += (c - '0'); 71 | break; 72 | default: 73 | break; 74 | } 75 | } 76 | Serial.println(); 77 | Serial.println(id); 78 | Serial.println(); 79 | 80 | Serial.println("Start labeling ..."); 81 | for (uint8_t index = 0; index < deviceCount; index++) 82 | { 83 | Serial.print("."); 84 | DeviceAddress t; 85 | sensors.getAddress(t, index); 86 | sensors.setUserData(t, id); 87 | } 88 | Serial.println(); 89 | 90 | Serial.println(); 91 | Serial.println("Show results ..."); 92 | for (uint8_t index = 0; index < deviceCount; index++) 93 | { 94 | DeviceAddress t; 95 | sensors.getAddress(t, index); 96 | printAddress(t); 97 | Serial.print("\t\tID: "); 98 | int id = sensors.getUserData(t); 99 | Serial.println(id); 100 | } 101 | Serial.println("Done ..."); 102 | 103 | } 104 | 105 | void loop(void) {} 106 | 107 | // END OF FILE -------------------------------------------------------------------------------- /examples/WaitForConversion/WaitForConversion.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Data wire is plugged into port 2 on the Arduino 5 | #define ONE_WIRE_BUS 2 6 | 7 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 8 | OneWire oneWire(ONE_WIRE_BUS); 9 | 10 | // Pass our oneWire reference to Dallas Temperature. 11 | DallasTemperature sensors(&oneWire); 12 | 13 | void setup(void) 14 | { 15 | // start serial port 16 | Serial.begin(115200); 17 | Serial.println("Dallas Temperature Control Library - Async Demo"); 18 | Serial.println("\nDemo shows the difference in length of the call\n\n"); 19 | 20 | // Start up the library 21 | sensors.begin(); 22 | } 23 | 24 | void loop(void) 25 | { 26 | // Request temperature conversion (traditional) 27 | Serial.println("Before blocking requestForConversion"); 28 | unsigned long start = millis(); 29 | 30 | sensors.requestTemperatures(); 31 | 32 | unsigned long stop = millis(); 33 | Serial.println("After blocking requestForConversion"); 34 | Serial.print("Time used: "); 35 | Serial.println(stop - start); 36 | 37 | // get temperature 38 | Serial.print("Temperature: "); 39 | Serial.println(sensors.getTempCByIndex(0)); 40 | Serial.println("\n"); 41 | 42 | // Request temperature conversion - non-blocking / async 43 | Serial.println("Before NON-blocking/async requestForConversion"); 44 | start = millis(); 45 | sensors.setWaitForConversion(false); // makes it async 46 | sensors.requestTemperatures(); 47 | sensors.setWaitForConversion(true); 48 | stop = millis(); 49 | Serial.println("After NON-blocking/async requestForConversion"); 50 | Serial.print("Time used: "); 51 | Serial.println(stop - start); 52 | 53 | 54 | // 9 bit resolution by default 55 | // Note the programmer is responsible for the right delay 56 | // we could do something usefull here instead of the delay 57 | int resolution = 9; 58 | delay(750 / (1 << (12 - resolution))); 59 | 60 | // get temperature 61 | Serial.print("Temperature: "); 62 | Serial.println(sensors.getTempCByIndex(0)); 63 | Serial.println("\n\n\n\n"); 64 | 65 | delay(1500); 66 | } 67 | -------------------------------------------------------------------------------- /examples/WaitForConversion2/WaitForConversion2.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Sample of using Async reading of Dallas Temperature Sensors 3 | // 4 | #include 5 | #include 6 | 7 | // Data wire is plugged into port 2 on the Arduino 8 | #define ONE_WIRE_BUS 2 9 | 10 | // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) 11 | OneWire oneWire(ONE_WIRE_BUS); 12 | 13 | // Pass our oneWire reference to Dallas Temperature. 14 | DallasTemperature sensors(&oneWire); 15 | 16 | DeviceAddress tempDeviceAddress; 17 | 18 | int resolution = 12; 19 | unsigned long lastTempRequest = 0; 20 | int delayInMillis = 0; 21 | float temperature = 0.0; 22 | int idle = 0; 23 | // 24 | // SETUP 25 | // 26 | void setup(void) 27 | { 28 | Serial.begin(115200); 29 | Serial.println("Dallas Temperature Control Library - Async Demo"); 30 | Serial.print("Library Version: "); 31 | Serial.println(DALLASTEMPLIBVERSION); 32 | Serial.println("\n"); 33 | 34 | sensors.begin(); 35 | sensors.getAddress(tempDeviceAddress, 0); 36 | sensors.setResolution(tempDeviceAddress, resolution); 37 | 38 | sensors.setWaitForConversion(false); 39 | sensors.requestTemperatures(); 40 | delayInMillis = 750 / (1 << (12 - resolution)); 41 | lastTempRequest = millis(); 42 | 43 | pinMode(13, OUTPUT); 44 | } 45 | 46 | void loop(void) 47 | { 48 | 49 | if (millis() - lastTempRequest >= delayInMillis) // waited long enough?? 50 | { 51 | digitalWrite(13, LOW); 52 | Serial.print(" Temperature: "); 53 | temperature = sensors.getTempCByIndex(0); 54 | Serial.println(temperature, resolution - 8); 55 | Serial.print(" Resolution: "); 56 | Serial.println(resolution); 57 | Serial.print("Idle counter: "); 58 | Serial.println(idle); 59 | Serial.println(); 60 | 61 | idle = 0; 62 | 63 | // immediately after fetching the temperature we request a new sample 64 | // in the async modus 65 | // for the demo we let the resolution change to show differences 66 | resolution++; 67 | if (resolution > 12) resolution = 9; 68 | 69 | sensors.setResolution(tempDeviceAddress, resolution); 70 | sensors.requestTemperatures(); 71 | delayInMillis = 750 / (1 << (12 - resolution)); 72 | lastTempRequest = millis(); 73 | } 74 | 75 | digitalWrite(13, HIGH); 76 | // we can do usefull things here 77 | // for the demo we just count the idle time in millis 78 | delay(1); 79 | idle++; 80 | } 81 | -------------------------------------------------------------------------------- /examples/oneWireSearch/oneWireSearch.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: oneWireSearch.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.1.02 5 | // PURPOSE: scan for 1-Wire devices + code snippet generator 6 | // DATE: 2015-june-30 7 | // URL: http://forum.arduino.cc/index.php?topic=333923 8 | // 9 | // inspired by http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html 10 | // 11 | // Released to the public domain 12 | // 13 | // 0.1.00 initial version 14 | // 0.1.01 first published version 15 | // 0.1.02 small output changes 16 | 17 | #include 18 | 19 | void setup() 20 | { 21 | Serial.begin(115200); 22 | Serial.println("//\n// Start oneWireSearch.ino \n//"); 23 | 24 | for (uint8_t pin = 2; pin < 13; pin++) 25 | { 26 | findDevices(pin); 27 | } 28 | Serial.println("\n//\n// End oneWireSearch.ino \n//"); 29 | } 30 | 31 | void loop() 32 | { 33 | } 34 | 35 | uint8_t findDevices(int pin) 36 | { 37 | OneWire ow(pin); 38 | 39 | uint8_t address[8]; 40 | uint8_t count = 0; 41 | 42 | 43 | if (ow.search(address)) 44 | { 45 | Serial.print("\nuint8_t pin"); 46 | Serial.print(pin, DEC); 47 | Serial.println("[][8] = {"); 48 | do { 49 | count++; 50 | Serial.println(" {"); 51 | for (uint8_t i = 0; i < 8; i++) 52 | { 53 | Serial.print("0x"); 54 | if (address[i] < 0x10) Serial.print("0"); 55 | Serial.print(address[i], HEX); 56 | if (i < 7) Serial.print(", "); 57 | } 58 | Serial.println(" },"); 59 | } while (ow.search(address)); 60 | 61 | Serial.println("};"); 62 | Serial.print("// nr devices found: "); 63 | Serial.println(count); 64 | } 65 | 66 | return count; 67 | } 68 | -------------------------------------------------------------------------------- /examples/readPowerSupply/readPowerSupply.ino: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: readPowerSupply.ino 3 | // AUTHOR: Rob Tillaart 4 | // VERSION: 0.1.0 5 | // PURPOSE: demo 6 | // DATE: 2020-02-10 7 | // 8 | // Released to the public domain 9 | // 10 | 11 | // Include the libraries we need 12 | #include 13 | #include 14 | 15 | // Data wire is plugged into port 2 on the Arduino 16 | #define ONE_WIRE_BUS 2 17 | 18 | // Setup a oneWire instance to communicate with any OneWire devices 19 | OneWire oneWire(ONE_WIRE_BUS); 20 | 21 | // Pass our oneWire reference to Dallas Temperature. 22 | DallasTemperature sensors(&oneWire); 23 | 24 | // arrays to hold device addresses 25 | DeviceAddress insideThermometer, outsideThermometer; 26 | // Assign address manually. The addresses below will beed to be changed 27 | // to valid device addresses on your bus. Device address can be retrieved 28 | // by using either oneWire.search(deviceAddress) or individually via 29 | // sensors.getAddress(deviceAddress, index) 30 | // DeviceAddress insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 }; 31 | // DeviceAddress outsideThermometer = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 }; 32 | 33 | int devCount = 0; 34 | 35 | /* 36 | * The setup function. We only start the sensors here 37 | */ 38 | void setup(void) 39 | { 40 | Serial.begin(115200); 41 | Serial.println("Arduino Temperature Control Library Demo - readPowerSupply"); 42 | 43 | sensors.begin(); 44 | 45 | devCount = sensors.getDeviceCount(); 46 | Serial.print("#devices: "); 47 | Serial.println(devCount); 48 | 49 | // report parasite power requirements 50 | Serial.print("Parasite power is: "); 51 | if (sensors.readPowerSupply()) Serial.println("ON"); // no address means "scan all devices for parasite mode" 52 | else Serial.println("OFF"); 53 | 54 | // Search for devices on the bus and assign based on an index. 55 | if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 56 | if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 57 | 58 | // show the addresses we found on the bus 59 | Serial.print("Device 0 Address: "); 60 | printAddress(insideThermometer); 61 | Serial.println(); 62 | Serial.print("Power = parasite: "); 63 | Serial.println(sensors.readPowerSupply(insideThermometer)); 64 | Serial.println(); 65 | Serial.println(); 66 | 67 | Serial.print("Device 1 Address: "); 68 | printAddress(outsideThermometer); 69 | Serial.println(); 70 | Serial.print("Power = parasite: "); 71 | Serial.println(sensors.readPowerSupply(outsideThermometer)); 72 | Serial.println(); 73 | Serial.println(); 74 | } 75 | 76 | // function to print a device address 77 | void printAddress(DeviceAddress deviceAddress) 78 | { 79 | for (uint8_t i = 0; i < 8; i++) 80 | { 81 | // zero pad the address if necessary 82 | if (deviceAddress[i] < 0x10) Serial.print("0"); 83 | Serial.print(deviceAddress[i], HEX); 84 | } 85 | } 86 | 87 | // empty on purpose 88 | void loop(void) 89 | { 90 | } 91 | 92 | // END OF FILE -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For DallasTemperature 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | DallasTemperature KEYWORD1 9 | OneWire KEYWORD1 10 | AlarmHandler KEYWORD1 11 | DeviceAddress KEYWORD1 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | setOneWire KEYWORD2 18 | setPullupPin KEYWORD2 19 | setResolution KEYWORD2 20 | getResolution KEYWORD2 21 | getTemp KEYWORD2 22 | getTempC KEYWORD2 23 | toFahrenheit KEYWORD2 24 | getTempF KEYWORD2 25 | getTempCByIndex KEYWORD2 26 | getTempFByIndex KEYWORD2 27 | rawToCelsius KEYWORD2 28 | rawToFahrenheit KEYWORD2 29 | setWaitForConversion KEYWORD2 30 | getWaitForConversion KEYWORD2 31 | requestTemperatures KEYWORD2 32 | requestTemperaturesByAddress KEYWORD2 33 | requestTemperaturesByIndex KEYWORD2 34 | setCheckForConversion KEYWORD2 35 | getCheckForConversion KEYWORD2 36 | isConversionComplete KEYWORD2 37 | millisToWaitForConversion KEYWORD2 38 | isParasitePowerMode KEYWORD2 39 | begin KEYWORD2 40 | getDeviceCount KEYWORD2 41 | getDS18Count KEYWORD2 42 | getAddress KEYWORD2 43 | validAddress KEYWORD2 44 | validFamily KEYWORD2 45 | isConnected KEYWORD2 46 | readScratchPad KEYWORD2 47 | writeScratchPad KEYWORD2 48 | readPowerSupply KEYWORD2 49 | saveScratchPadByIndex KEYWORD2 50 | saveScratchPad KEYWORD2 51 | recallScratchPadByIndex KEYWORD2 52 | recallScratchPad KEYWORD2 53 | setAutoSaveScratchPad KEYWORD2 54 | getAutoSaveScratchPad KEYWORD2 55 | setHighAlarmTemp KEYWORD2 56 | setLowAlarmTemp KEYWORD2 57 | getHighAlarmTemp KEYWORD2 58 | getLowAlarmTemp KEYWORD2 59 | resetAlarmSearch KEYWORD2 60 | alarmSearch KEYWORD2 61 | hasAlarm KEYWORD2 62 | toCelsius KEYWORD2 63 | processAlarms KEYWORD2 64 | setAlarmHandler KEYWORD2 65 | hasAlarmHandler KEYWORD2 66 | setUserData KEYWORD2 67 | setUserDataByIndex KEYWORD2 68 | getUserData KEYWORD2 69 | getUserDataByIndex KEYWORD2 70 | calculateTemperature KEYWORD2 71 | 72 | ####################################### 73 | # Constants (LITERAL1) 74 | ####################################### 75 | 76 | DEVICE_DISCONNECTED_C LITERAL1 77 | DEVICE_DISCONNECTED_F LITERAL1 78 | DEVICE_DISCONNECTED_RAW LITERAL1 79 | DEVICE_FAULT_OPEN_C LITERAL1 80 | DEVICE_FAULT_OPEN_F LITERAL1 81 | DEVICE_FAULT_OPEN_RAW LITERAL1 82 | DEVICE_FAULT_SHORTGND_C LITERAL1 83 | DEVICE_FAULT_SHORTGND_F LITERAL1 84 | DEVICE_FAULT_SHORTGND_RAW LITERAL1 85 | DEVICE_FAULT_SHORTVDD_C LITERAL1 86 | DEVICE_FAULT_SHORTVDD_F LITERAL1 87 | DEVICE_FAULT_SHORTVDD_RAW LITERAL1 88 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DallasTemperature", 3 | "keywords": "onewire, 1-wire, bus, sensor, temperature, DS18B20, DS18S20, DS1822, DS1820, MAX31850", 4 | "description": "Arduino Library for Dallas Temperature ICs (DS18B20, DS18S20, DS1822, DS1820, MAX31850)", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/milesburton/Arduino-Temperature-Control-Library.git" 9 | }, 10 | "authors": 11 | [ 12 | { 13 | "name": "Miles Burton", 14 | "email": "mail@milesburton.com", 15 | "url": "http://www.milesburton.com", 16 | "maintainer": true 17 | }, 18 | { 19 | "name": "Tim Newsome", 20 | "email": "nuisance@casualhacker.net" 21 | }, 22 | { 23 | "name": "Guil Barros", 24 | "email": "gfbarros@bappos.com" 25 | }, 26 | { 27 | "name": "Rob Tillaart", 28 | "email": "rob.tillaart@gmail.com" 29 | } 30 | ], 31 | "dependencies": 32 | { 33 | "paulstoffregen/OneWire": "^2.3.5" 34 | }, 35 | "version": "4.0.4", 36 | "frameworks": "arduino", 37 | "platforms": "*" 38 | } 39 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=DallasTemperature 2 | version=4.0.4 3 | author=Miles Burton , Tim Newsome , Guil Barros , Rob Tillaart 4 | maintainer=Miles Burton 5 | sentence=Arduino library for Dallas/Maxim temperature ICs 6 | paragraph=Support for DS18B20 and other Dallas/Maxim 1-Wire temperature sensors 7 | category=Sensors 8 | url=https://github.com/milesburton/Arduino-Temperature-Control-Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /test/TestDallasTemperature.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unittest(test_initialization) { 5 | OneWire oneWire(2); // Simulate OneWire on pin 2 6 | DallasTemperature sensors(&oneWire); 7 | 8 | sensors.begin(); 9 | assertEqual(0, sensors.getDeviceCount()); 10 | } 11 | 12 | unittest(test_parasite_power_mode) { 13 | OneWire oneWire(2); 14 | DallasTemperature sensors(&oneWire); 15 | 16 | sensors.begin(); 17 | assertFalse(sensors.isParasitePowerMode()); 18 | } 19 | 20 | unittest_main() -------------------------------------------------------------------------------- /test/unit_test_001.cpp: -------------------------------------------------------------------------------- 1 | // FILE: unit_test_001.cpp 2 | // AUTHOR: Miles Burton / Rob Tillaart 3 | // DATE: 2021-01-10 4 | // PURPOSE: unit tests for the Arduino-Temperature-Control-Library 5 | // https://github.com/MilesBurton/Arduino-Temperature-Control-Library 6 | 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // Mock pin for testing 14 | #define ONE_WIRE_BUS 2 15 | 16 | unittest_setup() { 17 | fprintf(stderr, "VERSION: %s\n", DALLASTEMPLIBVERSION); 18 | } 19 | 20 | unittest_teardown() { 21 | fprintf(stderr, "\n"); 22 | } 23 | 24 | // Test constants defined in the library 25 | unittest(test_models) { 26 | assertEqual(0x10, DS18S20MODEL); 27 | assertEqual(0x28, DS18B20MODEL); 28 | assertEqual(0x22, DS1822MODEL); 29 | assertEqual(0x3B, DS1825MODEL); 30 | assertEqual(0x42, DS28EA00MODEL); 31 | } 32 | 33 | // Test error codes defined in the library 34 | unittest(test_error_code) { 35 | assertEqual(DEVICE_DISCONNECTED_C, -127); 36 | assertEqual(DEVICE_DISCONNECTED_F, -196.6); 37 | assertEqual(DEVICE_DISCONNECTED_RAW, -7040); 38 | 39 | assertEqual(DEVICE_FAULT_OPEN_C, -254); 40 | assertEqualFloat(DEVICE_FAULT_OPEN_F, -425.2, 0.1); 41 | assertEqual(DEVICE_FAULT_OPEN_RAW, -32512); 42 | 43 | assertEqual(DEVICE_FAULT_SHORTGND_C, -253); 44 | assertEqualFloat(DEVICE_FAULT_SHORTGND_F, -423.4, 0.1); 45 | assertEqual(DEVICE_FAULT_SHORTGND_RAW, -32384); 46 | 47 | assertEqual(DEVICE_FAULT_SHORTVDD_C, -252); 48 | assertEqualFloat(DEVICE_FAULT_SHORTVDD_F, -421.6, 0.1); 49 | assertEqual(DEVICE_FAULT_SHORTVDD_RAW, -32256); 50 | } 51 | 52 | // Test basic initialization and functionality of the DallasTemperature library 53 | unittest(test_initialization) { 54 | OneWire oneWire(ONE_WIRE_BUS); 55 | DallasTemperature sensors(&oneWire); 56 | 57 | sensors.begin(); 58 | 59 | // Initially, there should be no devices detected 60 | assertEqual(0, sensors.getDeviceCount()); 61 | assertFalse(sensors.isParasitePowerMode()); 62 | } 63 | 64 | // Simulate a basic temperature read (mocked) 65 | unittest(test_temperature_read) { 66 | OneWire oneWire(ONE_WIRE_BUS); 67 | DallasTemperature sensors(&oneWire); 68 | 69 | sensors.begin(); 70 | 71 | // Mock reading temperature 72 | float tempC = sensors.getTempCByIndex(0); 73 | assertEqual(DEVICE_DISCONNECTED_C, tempC); // Simulated no device connected 74 | } 75 | 76 | unittest_main() --------------------------------------------------------------------------------