supla-device
Loading...
Searching...
No Matches
DS18B20.h
1// SPDX-FileCopyrightText: AC SOFTWARE SP. Z O.O.
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#ifndef SRC_SUPLA_SENSOR_DS18B20_H_
5#define SRC_SUPLA_SENSOR_DS18B20_H_
6
7#include <Arduino.h>
8#include <DallasTemperature.h>
9#include <OneWire.h>
10
11#include <supla/log_wrapper.h>
12
13#include "supla/sensor/thermometer.h"
14
15namespace Supla {
16namespace Sensor {
17
19 public:
20 explicit OneWireBus(uint8_t pinNumber)
21 : pin(pinNumber), nextBus(nullptr), lastReadTime(0), oneWire(pinNumber) {
22 SUPLA_LOG_DEBUG("Initializing OneWire bus at pin %d", pinNumber);
23 sensors.setOneWire(&oneWire);
24 sensors.begin();
25 if (sensors.isParasitePowerMode()) {
26 SUPLA_LOG_DEBUG("OneWire(pin %d) Parasite power is ON", pinNumber);
27 } else {
28 SUPLA_LOG_DEBUG("OneWire(pin %d) Parasite power is OFF", pinNumber);
29 }
30
31 SUPLA_LOG_DEBUG(
32 "OneWire(pin %d) Found %d devices:",
33 pinNumber,
34 sensors.getDeviceCount());
35
36 // report parasite power requirements
37
38 DeviceAddress address;
39 char strAddr[64];
40 for (int i = 0; i < sensors.getDeviceCount(); i++) {
41 if (!sensors.getAddress(address, i)) {
42 SUPLA_LOG_DEBUG("Unable to find address for Device %d", i);
43 } else {
44 snprintf(
45 strAddr, sizeof(strAddr),
46 "{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}",
47 address[0],
48 address[1],
49 address[2],
50 address[3],
51 address[4],
52 address[5],
53 address[6],
54 address[7]);
55 SUPLA_LOG_DEBUG("Index %d - address %s", i, strAddr);
56 sensors.setResolution(address, 12);
57 }
58 delay(0);
59 }
60 sensors.setWaitForConversion(true);
61 sensors.requestTemperatures();
62 sensors.setWaitForConversion(false);
63 }
64
65 int8_t getIndex(uint8_t *deviceAddress) {
66 DeviceAddress address;
67 for (int i = 0; i < sensors.getDeviceCount(); i++) {
68 if (sensors.getAddress(address, i)) {
69 bool found = true;
70 for (int j = 0; j < 8; j++) {
71 if (deviceAddress[j] != address[j]) {
72 found = false;
73 }
74 }
75 if (found) {
76 return i;
77 }
78 }
79 }
80 return -1;
81 }
82
83 uint8_t pin;
84 OneWireBus *nextBus;
85 uint32_t lastReadTime;
86 DallasTemperature sensors;
87
88 protected:
89 OneWire oneWire;
90};
91
92class DS18B20 : public Thermometer {
93 public:
94 explicit DS18B20(uint8_t pin, uint8_t *deviceAddress = nullptr) {
95 OneWireBus *bus = oneWireBus;
96 OneWireBus *prevBus = nullptr;
97 address[0] = 0;
98 lastValidValue = TEMPERATURE_NOT_AVAILABLE;
99 retryCounter = 0;
100
101 if (bus) {
102 while (bus) {
103 if (bus->pin == pin) {
104 myBus = bus;
105 break;
106 }
107 prevBus = bus;
108 bus = bus->nextBus;
109 }
110 }
111
112 // There is no OneWire bus created yet for this pin
113 if (!bus) {
114 SUPLA_LOG_DEBUG("Creating OneWire bus for pin: %d", pin);
115 myBus = new OneWireBus(pin);
116 if (prevBus) {
117 prevBus->nextBus = myBus;
118 } else {
119 oneWireBus = myBus;
120 }
121 }
122 if (deviceAddress == nullptr) {
123 SUPLA_LOG_DEBUG(
124 "Device address not provided. Using device from index 0");
125 } else {
126 memcpy(address, deviceAddress, 8);
127 }
128 }
129
131 if (millis() - myBus->lastReadTime > 10000) {
132 myBus->sensors.requestTemperatures();
133 myBus->lastReadTime = millis();
134 }
135 if (millis() - myBus->lastReadTime > 5000 &&
136 (lastReadTime != myBus->lastReadTime)) {
137 channel.setNewValue(getValue());
138 lastReadTime = myBus->lastReadTime;
139 }
140 }
141
142 double getValue() {
143 double value = TEMPERATURE_NOT_AVAILABLE;
144 if (address[0] == 0) {
145 value = myBus->sensors.getTempCByIndex(0);
146 } else {
147 value = myBus->sensors.getTempC(address);
148 }
149
150 if (value == DEVICE_DISCONNECTED_C || value == 85.0) {
151 value = TEMPERATURE_NOT_AVAILABLE;
152 }
153
154 if (value == TEMPERATURE_NOT_AVAILABLE) {
155 retryCounter++;
156 if (retryCounter > 3) {
157 retryCounter = 0;
158 } else {
159 value = lastValidValue;
160 }
161 } else {
162 retryCounter = 0;
163 }
164 lastValidValue = value;
165
166 return value;
167 }
168
169 DallasTemperature &getHwSensors() {
170 return myBus->sensors;
171 }
172
173 protected:
174 static OneWireBus *oneWireBus;
175 OneWireBus *myBus;
176 DeviceAddress address;
177 int8_t retryCounter;
178 double lastValidValue;
179};
180
181OneWireBus *DS18B20::oneWireBus = nullptr;
182
183}; // namespace Sensor
184}; // namespace Supla
185
186#endif // SRC_SUPLA_SENSOR_DS18B20_H_
Definition DS18B20.h:92
void iterateAlways()
Method called on each SuplaDevice iteration.
Definition DS18B20.h:130
Definition DS18B20.h:18
Definition thermometer.h:13