Line data Source code
1 : /*
2 : This program is free software: you can redistribute it and/or modify
3 : it under the terms of the GNU General Public License as published by
4 : the Free Software Foundation, either version 3 of the License, or
5 : (at your option) any later version.
6 :
7 : This program is distributed in the hope that it will be useful,
8 : but WITHOUT ANY WARRANTY; without even the implied warranty of
9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 : GNU General Public License for more details.
11 :
12 : You should have received a copy of the GNU General Public License
13 : along with this program. If not, see <http://www.gnu.org/licenses/>.
14 : */
15 :
16 : #include "AP_TemperatureSensor.h"
17 :
18 : #if AP_TEMPERATURE_SENSOR_ENABLED
19 :
20 : #include <AP_Vehicle/AP_Vehicle_Type.h>
21 :
22 : #ifndef AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED
23 : #define AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED (!(APM_BUILD_TYPE(APM_BUILD_ArduSub) || (AP_TEMPERATURE_SENSOR_ENABLED == 1)))
24 : #endif
25 :
26 :
27 : #if !AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED
28 :
29 : #include "AP_TemperatureSensor_TSYS01.h"
30 : #include "AP_TemperatureSensor_TSYS03.h"
31 : #include "AP_TemperatureSensor_MCP9600.h"
32 : #include "AP_TemperatureSensor_MAX31865.h"
33 : #include "AP_TemperatureSensor_Analog.h"
34 : #include "AP_TemperatureSensor_DroneCAN.h"
35 : #include "AP_TemperatureSensor_MLX90614.h"
36 : #include "AP_TemperatureSensor_SHT3x.h"
37 : #include "AP_TemperatureSensor_TMP119.h"
38 :
39 : #include <AP_Logger/AP_Logger.h>
40 : #include <AP_Vehicle/AP_Vehicle_Type.h>
41 :
42 : extern const AP_HAL::HAL& hal;
43 :
44 : const AP_Param::GroupInfo AP_TemperatureSensor::var_info[] = {
45 :
46 : // SKIP INDEX 0
47 :
48 : #if HAL_LOGGING_ENABLED
49 : // @Param: _LOG
50 : // @DisplayName: Logging
51 : // @Description: Enables temperature sensor logging
52 : // @Values: 0:Disabled, 1:Log all instances, 2: Log only instances with sensor source set to None
53 : // @User: Standard
54 : AP_GROUPINFO("_LOG", 1, AP_TemperatureSensor, _logging_type, 0),
55 : #endif
56 :
57 : // SKIP Index 2-9 to be for parameters that apply to every sensor
58 :
59 : // @Group: 1_
60 : // @Path: AP_TemperatureSensor_Params.cpp
61 : AP_SUBGROUPINFO(_params[0], "1_", 10, AP_TemperatureSensor, AP_TemperatureSensor_Params),
62 :
63 : // @Group: 1_
64 : // @Path: AP_TemperatureSensor_Analog.cpp
65 : // @Group: 1_
66 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
67 : // @Group: 1_
68 : // @Path: AP_TemperatureSensor_MAX31865.cpp
69 : AP_SUBGROUPVARPTR(drivers[0], "1_", 19, AP_TemperatureSensor, backend_var_info[0]),
70 :
71 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 2
72 : // @Group: 2_
73 : // @Path: AP_TemperatureSensor_Params.cpp
74 : AP_SUBGROUPINFO(_params[1], "2_", 11, AP_TemperatureSensor, AP_TemperatureSensor_Params),
75 :
76 : // @Group: 2_
77 : // @Path: AP_TemperatureSensor_Analog.cpp
78 : // @Group: 2_
79 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
80 : // @Group: 2_
81 : // @Path: AP_TemperatureSensor_MAX31865.cpp
82 : AP_SUBGROUPVARPTR(drivers[1], "2_", 20, AP_TemperatureSensor, backend_var_info[1]),
83 : #endif
84 :
85 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 3
86 : // @Group: 3_
87 : // @Path: AP_TemperatureSensor_Params.cpp
88 : AP_SUBGROUPINFO(_params[2], "3_", 12, AP_TemperatureSensor, AP_TemperatureSensor_Params),
89 :
90 : // @Group: 3_
91 : // @Path: AP_TemperatureSensor_Analog.cpp
92 : // @Group: 3_
93 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
94 : // @Group: 3_
95 : // @Path: AP_TemperatureSensor_MAX31865.cpp
96 : AP_SUBGROUPVARPTR(drivers[2], "3_", 21, AP_TemperatureSensor, backend_var_info[2]),
97 : #endif
98 :
99 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 4
100 : // @Group: 4_
101 : // @Path: AP_TemperatureSensor_Params.cpp
102 : AP_SUBGROUPINFO(_params[3], "4_", 13, AP_TemperatureSensor, AP_TemperatureSensor_Params),
103 :
104 : // @Group: 4_
105 : // @Path: AP_TemperatureSensor_Analog.cpp
106 : // @Group: 4_
107 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
108 : // @Group: 4_
109 : // @Path: AP_TemperatureSensor_MAX31865.cpp
110 : AP_SUBGROUPVARPTR(drivers[3], "4_", 22, AP_TemperatureSensor, backend_var_info[3]),
111 : #endif
112 :
113 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 5
114 : // @Group: 5_
115 : // @Path: AP_TemperatureSensor_Params.cpp
116 : AP_SUBGROUPINFO(_params[4], "5_", 14, AP_TemperatureSensor, AP_TemperatureSensor_Params),
117 :
118 : // @Group: 5_
119 : // @Path: AP_TemperatureSensor_Analog.cpp
120 : // @Group: 5_
121 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
122 : // @Group: 5_
123 : // @Path: AP_TemperatureSensor_MAX31865.cpp
124 : AP_SUBGROUPVARPTR(drivers[4], "5_", 23, AP_TemperatureSensor, backend_var_info[4]),
125 : #endif
126 :
127 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 6
128 : // @Group: 6_
129 : // @Path: AP_TemperatureSensor_Params.cpp
130 : AP_SUBGROUPINFO(_params[5], "6_", 15, AP_TemperatureSensor, AP_TemperatureSensor_Params),
131 :
132 : // @Group: 6_
133 : // @Path: AP_TemperatureSensor_Analog.cpp
134 : // @Group: 6_
135 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
136 : // @Group: 6_
137 : // @Path: AP_TemperatureSensor_MAX31865.cpp
138 : AP_SUBGROUPVARPTR(drivers[5], "6_", 24, AP_TemperatureSensor, backend_var_info[5]),
139 : #endif
140 :
141 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 7
142 : // @Group: 7_
143 : // @Path: AP_TemperatureSensor_Params.cpp
144 : AP_SUBGROUPINFO(_params[6], "7_", 16, AP_TemperatureSensor, AP_TemperatureSensor_Params),
145 :
146 : // @Group: 7_
147 : // @Path: AP_TemperatureSensor_Analog.cpp
148 : // @Group: 7_
149 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
150 : // @Group: 7_
151 : // @Path: AP_TemperatureSensor_MAX31865.cpp
152 : AP_SUBGROUPVARPTR(drivers[6], "7_", 25, AP_TemperatureSensor, backend_var_info[6]),
153 : #endif
154 :
155 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 8
156 : // @Group: 8_
157 : // @Path: AP_TemperatureSensor_Params.cpp
158 : AP_SUBGROUPINFO(_params[7], "8_", 17, AP_TemperatureSensor, AP_TemperatureSensor_Params),
159 :
160 : // @Group: 8_
161 : // @Path: AP_TemperatureSensor_Analog.cpp
162 : // @Group: 8_
163 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
164 : // @Group: 8_
165 : // @Path: AP_TemperatureSensor_MAX31865.cpp
166 : AP_SUBGROUPVARPTR(drivers[7], "8_", 26, AP_TemperatureSensor, backend_var_info[7]),
167 : #endif
168 :
169 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 9
170 : // @Group: 9_
171 : // @Path: AP_TemperatureSensor_Params.cpp
172 : AP_SUBGROUPINFO(_params[8], "9_", 18, AP_TemperatureSensor, AP_TemperatureSensor_Params),
173 :
174 : // @Group: 9_
175 : // @Path: AP_TemperatureSensor_Analog.cpp
176 : // @Group: 9_
177 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
178 : // @Group: 9_
179 : // @Path: AP_TemperatureSensor_MAX31865.cpp
180 : AP_SUBGROUPVARPTR(drivers[8], "9_", 27, AP_TemperatureSensor, backend_var_info[8]),
181 : #endif
182 :
183 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 10
184 : // @Group: 10_
185 : // @Path: AP_TemperatureSensor_Params.cpp
186 : AP_SUBGROUPINFO(_params[9], "10_", 28, AP_TemperatureSensor, AP_TemperatureSensor_Params),
187 :
188 : // @Group: 10_
189 : // @Path: AP_TemperatureSensor_Analog.cpp
190 : // @Group: 10_
191 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
192 : // @Group: 10_
193 : // @Path: AP_TemperatureSensor_MAX31865.cpp
194 : AP_SUBGROUPVARPTR(drivers[9], "10_", 29, AP_TemperatureSensor, backend_var_info[9]),
195 : #endif
196 :
197 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 11
198 : // @Group: 11_
199 : // @Path: AP_TemperatureSensor_Params.cpp
200 : AP_SUBGROUPINFO(_params[10], "11_", 30, AP_TemperatureSensor, AP_TemperatureSensor_Params),
201 :
202 : // @Group: 11_
203 : // @Path: AP_TemperatureSensor_Analog.cpp
204 : // @Group: 11_
205 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
206 : // @Group: 11_
207 : // @Path: AP_TemperatureSensor_MAX31865.cpp
208 : AP_SUBGROUPVARPTR(drivers[10], "11_", 31, AP_TemperatureSensor, backend_var_info[10]),
209 : #endif
210 :
211 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 12
212 : // @Group: 12_
213 : // @Path: AP_TemperatureSensor_Params.cpp
214 : AP_SUBGROUPINFO(_params[11], "12_", 32, AP_TemperatureSensor, AP_TemperatureSensor_Params),
215 :
216 : // @Group: 12_
217 : // @Path: AP_TemperatureSensor_Analog.cpp
218 : // @Group: 12_
219 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
220 : // @Group: 12_
221 : // @Path: AP_TemperatureSensor_MAX31865.cpp
222 : AP_SUBGROUPVARPTR(drivers[11], "12_", 33, AP_TemperatureSensor, backend_var_info[11]),
223 : #endif
224 :
225 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 13
226 : // @Group: 13_
227 : // @Path: AP_TemperatureSensor_Params.cpp
228 : AP_SUBGROUPINFO(_params[12], "13_", 34, AP_TemperatureSensor, AP_TemperatureSensor_Params),
229 :
230 : // @Group: 13_
231 : // @Path: AP_TemperatureSensor_Analog.cpp
232 : // @Group: 13_
233 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
234 : // @Group: 13_
235 : // @Path: AP_TemperatureSensor_MAX31865.cpp
236 : AP_SUBGROUPVARPTR(drivers[12], "13_", 35, AP_TemperatureSensor, backend_var_info[12]),
237 : #endif
238 :
239 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 14
240 : // @Group: 14_
241 : // @Path: AP_TemperatureSensor_Params.cpp
242 : AP_SUBGROUPINFO(_params[13], "14_", 36, AP_TemperatureSensor, AP_TemperatureSensor_Params),
243 :
244 : // @Group: 14_
245 : // @Path: AP_TemperatureSensor_Analog.cpp
246 : // @Group: 14_
247 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
248 : // @Group: 14_
249 : // @Path: AP_TemperatureSensor_MAX31865.cpp
250 : AP_SUBGROUPVARPTR(drivers[13], "14_", 37, AP_TemperatureSensor, backend_var_info[13]),
251 : #endif
252 :
253 : #if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 15
254 : // @Group: 15_
255 : // @Path: AP_TemperatureSensor_Params.cpp
256 : AP_SUBGROUPINFO(_params[14], "15_", 38, AP_TemperatureSensor, AP_TemperatureSensor_Params),
257 :
258 : // @Group: 15_
259 : // @Path: AP_TemperatureSensor_Analog.cpp
260 : // @Group: 15_
261 : // @Path: AP_TemperatureSensor_DroneCAN.cpp
262 : // @Group: 15_
263 : // @Path: AP_TemperatureSensor_MAX31865.cpp
264 : AP_SUBGROUPVARPTR(drivers[14], "15_", 39, AP_TemperatureSensor, backend_var_info[14]),
265 : #endif
266 :
267 : AP_GROUPEND
268 : };
269 :
270 : const AP_Param::GroupInfo *AP_TemperatureSensor::backend_var_info[AP_TEMPERATURE_SENSOR_MAX_INSTANCES];
271 :
272 : // Default Constructor
273 8392 : AP_TemperatureSensor::AP_TemperatureSensor()
274 : {
275 2098 : AP_Param::setup_object_defaults(this, var_info);
276 :
277 2098 : if (_singleton != nullptr) {
278 0 : AP_HAL::panic("AP_TemperatureSensor must be singleton");
279 : }
280 2098 : _singleton = this;
281 2098 : }
282 :
283 : // init - instantiate the temperature sensors
284 2086 : void AP_TemperatureSensor::init()
285 : {
286 : // check init has not been called before
287 2086 : if (_num_instances != 0) {
288 0 : return;
289 : }
290 :
291 : // For Sub set the Default: Type to TSYS01 and I2C_ADDR of 0x77
292 : #if APM_BUILD_TYPE(APM_BUILD_ArduSub) && AP_TEMPERATURE_SENSOR_TSYS01_ENABLED
293 82 : AP_Param::set_default_by_name("TEMP1_TYPE", (float)AP_TemperatureSensor_Params::Type::TSYS01);
294 82 : AP_Param::set_default_by_name("TEMP1_ADDR", TSYS01_ADDR_CSB0);
295 : #endif
296 :
297 : // create each instance
298 8344 : for (uint8_t instance = 0; instance < AP_TEMPERATURE_SENSOR_MAX_INSTANCES; instance++) {
299 6258 : _state[instance].instance = instance;
300 :
301 6258 : switch (get_type(instance)) {
302 : #if AP_TEMPERATURE_SENSOR_TSYS01_ENABLED
303 80 : case AP_TemperatureSensor_Params::Type::TSYS01:
304 80 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_TSYS01(*this, _state[instance], _params[instance]);
305 80 : break;
306 : #endif
307 : #if AP_TEMPERATURE_SENSOR_MCP9600_ENABLED
308 0 : case AP_TemperatureSensor_Params::Type::MCP9600:
309 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_MCP9600(*this, _state[instance], _params[instance]);
310 0 : break;
311 : #endif
312 : #if AP_TEMPERATURE_SENSOR_MAX31865_ENABLED
313 0 : case AP_TemperatureSensor_Params::Type::MAX31865_2_or_4_wire:
314 : case AP_TemperatureSensor_Params::Type::MAX31865_3_wire:
315 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_MAX31865(*this, _state[instance], _params[instance]);
316 0 : break;
317 : #endif
318 : #if AP_TEMPERATURE_SENSOR_SHT3X_ENABLED
319 9 : case AP_TemperatureSensor_Params::Type::SHT3x:
320 9 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_SHT3x(*this, _state[instance], _params[instance]);
321 9 : break;
322 : #endif // AP_TEMPERATURE_SENSOR_SHT3X_ENABLED
323 : #if AP_TEMPERATURE_SENSOR_TSYS03_ENABLED
324 0 : case AP_TemperatureSensor_Params::Type::TSYS03:
325 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_TSYS03(*this, _state[instance], _params[instance]);
326 0 : break;
327 : #endif
328 : #if AP_TEMPERATURE_SENSOR_ANALOG_ENABLED
329 0 : case AP_TemperatureSensor_Params::Type::ANALOG:
330 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_Analog(*this, _state[instance], _params[instance]);
331 0 : break;
332 : #endif
333 : #if AP_TEMPERATURE_SENSOR_DRONECAN_ENABLED
334 0 : case AP_TemperatureSensor_Params::Type::DRONECAN:
335 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_DroneCAN(*this, _state[instance], _params[instance]);
336 0 : break;
337 : #endif
338 : #if AP_TEMPERATURE_SENSOR_MLX90614_ENABLED
339 0 : case AP_TemperatureSensor_Params::Type::MLX90614:
340 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_MLX90614(*this, _state[instance], _params[instance]);
341 0 : break;
342 : #endif
343 : #if AP_TEMPERATURE_SENSOR_TMP119_ENABLED
344 0 : case AP_TemperatureSensor_Params::Type::TMP119:
345 0 : drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_TMP119(*this, _state[instance], _params[instance]);
346 0 : break;
347 : #endif
348 6169 : case AP_TemperatureSensor_Params::Type::NONE:
349 : default:
350 6169 : break;
351 : }
352 :
353 : // call init function for each backend
354 6258 : if (drivers[instance] != nullptr) {
355 89 : if (_state[instance].var_info != nullptr) {
356 : // Load backend specific params
357 0 : backend_var_info[instance] = _state[instance].var_info;
358 0 : AP_Param::load_object_from_eeprom(drivers[instance], backend_var_info[instance]);
359 : }
360 :
361 89 : drivers[instance]->init();
362 : // _num_instances is actually the index for looping over instances
363 : // the user may have TEMP_TYPE=0 and TEMP2_TYPE=7, in which case
364 : // there will be a gap, but as we always check for drivers[instances] being nullptr
365 : // this is safe
366 89 : _num_instances = instance + 1;
367 : }
368 : }
369 :
370 2086 : if (_num_instances > 0) {
371 : // param count could have changed
372 89 : AP_Param::invalidate_count();
373 : }
374 : }
375 :
376 : // update: - For all active instances update temperature and log TEMP
377 751641 : void AP_TemperatureSensor::update()
378 : {
379 779026 : for (uint8_t i=0; i<_num_instances; i++) {
380 27385 : if (drivers[i] != nullptr && get_type(i) != AP_TemperatureSensor_Params::Type::NONE) {
381 27379 : drivers[i]->update();
382 :
383 : #if HAL_LOGGING_ENABLED
384 27379 : const AP_Logger *logger = AP_Logger::get_singleton();
385 54565 : const bool should_log = (_logging_type == LoggingType::All) ||
386 27186 : ((_logging_type == LoggingType::SourceNone) && (_params[i].source == AP_TemperatureSensor_Params::Source::None));
387 27379 : if (logger != nullptr && should_log) {
388 193 : drivers[i]->Log_Write_TEMP();
389 : }
390 : #endif
391 : }
392 : }
393 751641 : }
394 :
395 33643 : AP_TemperatureSensor_Params::Type AP_TemperatureSensor::get_type(const uint8_t instance) const
396 : {
397 33643 : if (instance >= AP_TEMPERATURE_SENSOR_MAX_INSTANCES) {
398 0 : return AP_TemperatureSensor_Params::Type::NONE;
399 : }
400 33643 : return (AP_TemperatureSensor_Params::Type)_params[instance].type.get();
401 : }
402 :
403 : // returns true if there is a temperature reading
404 52070 : bool AP_TemperatureSensor::get_temperature(float &temp, const uint8_t instance) const
405 : {
406 52070 : if (!healthy(instance)) {
407 72 : return false;
408 : }
409 :
410 51998 : temp = _state[instance].temperature;
411 51998 : return true;
412 : }
413 :
414 52070 : bool AP_TemperatureSensor::healthy(const uint8_t instance) const
415 : {
416 52070 : return instance < _num_instances && drivers[instance] != nullptr && drivers[instance]->healthy();
417 : }
418 :
419 0 : AP_TemperatureSensor_Params::Source AP_TemperatureSensor::get_source(const uint8_t instance) const
420 : {
421 0 : return healthy(instance) ? (AP_TemperatureSensor_Params::Source)_params[instance].source.get() : AP_TemperatureSensor_Params::Source::None;
422 : }
423 :
424 0 : int32_t AP_TemperatureSensor::get_source_id(const uint8_t instance) const
425 : {
426 0 : return healthy(instance) ? _params[instance].source_id.get() : 0;
427 : }
428 : #else
429 : const AP_Param::GroupInfo AP_TemperatureSensor::var_info[] = { AP_GROUPEND };
430 :
431 : void AP_TemperatureSensor::init() { };
432 : void AP_TemperatureSensor::update() { };
433 : bool AP_TemperatureSensor::get_temperature(float &temp, const uint8_t instance) const { return false; };
434 : bool AP_TemperatureSensor::healthy(const uint8_t instance) const { return false; };
435 : AP_TemperatureSensor_Params::Type AP_TemperatureSensor::get_type(const uint8_t instance) const { return AP_TemperatureSensor_Params::Type::NONE; };
436 : AP_TemperatureSensor_Params::Source AP_TemperatureSensor::get_source(const uint8_t instance) const { return AP_TemperatureSensor_Params::Source::None; };
437 : int32_t AP_TemperatureSensor::get_source_id(const uint8_t instance) const { return false; };
438 :
439 : AP_TemperatureSensor::AP_TemperatureSensor() {}
440 :
441 : #endif // AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED
442 :
443 : AP_TemperatureSensor *AP_TemperatureSensor::_singleton;
444 :
445 : namespace AP {
446 0 : AP_TemperatureSensor &temperature_sensor() {
447 0 : return *AP_TemperatureSensor::get_singleton();
448 : }
449 : };
450 :
451 : #endif // AP_TEMPERATURE_SENSOR_ENABLED
|