supla-device
Toggle main menu visibility
Loading...
Searching...
No Matches
src
supla
sensor
DS18B20.h
1
/*
2
Copyright (C) AC SOFTWARE SP. Z O.O.
3
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
*/
18
19
#ifndef SRC_SUPLA_SENSOR_DS18B20_H_
20
#define SRC_SUPLA_SENSOR_DS18B20_H_
21
22
#include <Arduino.h>
23
#include <DallasTemperature.h>
24
#include <OneWire.h>
25
26
#include <supla/log_wrapper.h>
27
28
#include "supla/sensor/thermometer.h"
29
30
namespace
Supla {
31
namespace
Sensor {
32
33
class
OneWireBus {
34
public
:
35
explicit
OneWireBus(uint8_t pinNumber)
36
: pin(pinNumber), nextBus(
nullptr
), lastReadTime(0), oneWire(pinNumber) {
37
SUPLA_LOG_DEBUG(
"Initializing OneWire bus at pin %d"
, pinNumber);
38
sensors.setOneWire(&oneWire);
39
sensors.begin();
40
if
(sensors.isParasitePowerMode()) {
41
SUPLA_LOG_DEBUG(
"OneWire(pin %d) Parasite power is ON"
, pinNumber);
42
}
else
{
43
SUPLA_LOG_DEBUG(
"OneWire(pin %d) Parasite power is OFF"
, pinNumber);
44
}
45
46
SUPLA_LOG_DEBUG(
47
"OneWire(pin %d) Found %d devices:"
,
48
pinNumber,
49
sensors.getDeviceCount());
50
51
// report parasite power requirements
52
53
DeviceAddress address;
54
char
strAddr[64];
55
for
(
int
i = 0; i < sensors.getDeviceCount(); i++) {
56
if
(!sensors.getAddress(address, i)) {
57
SUPLA_LOG_DEBUG(
"Unable to find address for Device %d"
, i);
58
}
else
{
59
snprintf(
60
strAddr,
sizeof
(strAddr),
61
"{0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X}"
,
62
address[0],
63
address[1],
64
address[2],
65
address[3],
66
address[4],
67
address[5],
68
address[6],
69
address[7]);
70
SUPLA_LOG_DEBUG(
"Index %d - address %s"
, i, strAddr);
71
sensors.setResolution(address, 12);
72
}
73
delay(0);
74
}
75
sensors.setWaitForConversion(
true
);
76
sensors.requestTemperatures();
77
sensors.setWaitForConversion(
false
);
78
}
79
80
int8_t getIndex(uint8_t *deviceAddress) {
81
DeviceAddress address;
82
for
(
int
i = 0; i < sensors.getDeviceCount(); i++) {
83
if
(sensors.getAddress(address, i)) {
84
bool
found =
true
;
85
for
(
int
j = 0; j < 8; j++) {
86
if
(deviceAddress[j] != address[j]) {
87
found =
false
;
88
}
89
}
90
if
(found) {
91
return
i;
92
}
93
}
94
}
95
return
-1;
96
}
97
98
uint8_t pin;
99
OneWireBus *nextBus;
100
uint32_t lastReadTime;
101
DallasTemperature sensors;
102
103
protected
:
104
OneWire oneWire;
105
};
106
107
class
DS18B20 :
public
Thermometer {
108
public
:
109
explicit
DS18B20(uint8_t pin, uint8_t *deviceAddress =
nullptr
) {
110
OneWireBus
*bus = oneWireBus;
111
OneWireBus
*prevBus =
nullptr
;
112
address[0] = 0;
113
lastValidValue = TEMPERATURE_NOT_AVAILABLE;
114
retryCounter = 0;
115
116
if
(bus) {
117
while
(bus) {
118
if
(bus->pin == pin) {
119
myBus = bus;
120
break
;
121
}
122
prevBus = bus;
123
bus = bus->nextBus;
124
}
125
}
126
127
// There is no OneWire bus created yet for this pin
128
if
(!bus) {
129
SUPLA_LOG_DEBUG(
"Creating OneWire bus for pin: %d"
, pin);
130
myBus =
new
OneWireBus
(pin);
131
if
(prevBus) {
132
prevBus->nextBus = myBus;
133
}
else
{
134
oneWireBus = myBus;
135
}
136
}
137
if
(deviceAddress ==
nullptr
) {
138
SUPLA_LOG_DEBUG(
139
"Device address not provided. Using device from index 0"
);
140
}
else
{
141
memcpy(address, deviceAddress, 8);
142
}
143
}
144
145
void
iterateAlways
() {
146
if
(millis() - myBus->lastReadTime > 10000) {
147
myBus->sensors.requestTemperatures();
148
myBus->lastReadTime = millis();
149
}
150
if
(millis() - myBus->lastReadTime > 5000 &&
151
(lastReadTime != myBus->lastReadTime)) {
152
channel.setNewValue(getValue());
153
lastReadTime = myBus->lastReadTime;
154
}
155
}
156
157
double
getValue() {
158
double
value = TEMPERATURE_NOT_AVAILABLE;
159
if
(address[0] == 0) {
160
value = myBus->sensors.getTempCByIndex(0);
161
}
else
{
162
value = myBus->sensors.getTempC(address);
163
}
164
165
if
(value == DEVICE_DISCONNECTED_C || value == 85.0) {
166
value = TEMPERATURE_NOT_AVAILABLE;
167
}
168
169
if
(value == TEMPERATURE_NOT_AVAILABLE) {
170
retryCounter++;
171
if
(retryCounter > 3) {
172
retryCounter = 0;
173
}
else
{
174
value = lastValidValue;
175
}
176
}
else
{
177
retryCounter = 0;
178
}
179
lastValidValue = value;
180
181
return
value;
182
}
183
184
DallasTemperature &getHwSensors() {
185
return
myBus->sensors;
186
}
187
188
protected
:
189
static
OneWireBus *oneWireBus;
190
OneWireBus *myBus;
191
DeviceAddress address;
192
int8_t retryCounter;
193
double
lastValidValue;
194
};
195
196
OneWireBus
*DS18B20::oneWireBus =
nullptr
;
197
198
};
// namespace Sensor
199
};
// namespace Supla
200
201
#endif
// SRC_SUPLA_SENSOR_DS18B20_H_
Supla::Sensor::DS18B20::iterateAlways
void iterateAlways()
Method called on each SuplaDevice iteration.
Definition
DS18B20.h:145
Supla::Sensor::OneWireBus
Definition
DS18B20.h:33
Generated by
1.17.0