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 : Written with reference to the PX4 driver written by Roman Dvorak <[email protected]>
16 :
17 : */
18 :
19 : #include "AP_TemperatureSensor_SHT3x.h"
20 :
21 : #if AP_TEMPERATURE_SENSOR_SHT3X_ENABLED
22 : #include <utility>
23 : #include <stdio.h>
24 : #include <AP_HAL/I2CDevice.h>
25 : #include <AP_Math/AP_Math.h>
26 :
27 : #include <GCS_MAVLink/GCS.h>
28 :
29 : extern const AP_HAL::HAL &hal;
30 :
31 9 : void AP_TemperatureSensor_SHT3x::init()
32 : {
33 9 : constexpr char name[] = "SHT3x";
34 : (void)name; // sometimes this is unused (e.g. HAL_GCS_ENABLED false)
35 :
36 9 : _dev = hal.i2c_mgr->get_device_ptr(_params.bus, _params.bus_address);
37 9 : if (!_dev) {
38 0 : GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s device is null!", name);
39 6 : return;
40 : }
41 :
42 9 : WITH_SEMAPHORE(_dev->get_semaphore());
43 :
44 9 : _dev->set_retries(10);
45 :
46 : // read serial number
47 : static const uint8_t read_sn_cmd[2] { 0x37, 0x80 };
48 : uint8_t sn[6];
49 9 : if (!_dev->transfer(read_sn_cmd, ARRAY_SIZE(read_sn_cmd), sn, ARRAY_SIZE(sn))) {
50 6 : GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s read sn failed", name);
51 6 : return;
52 : }
53 : // emit serial number, more of confirmation we have the sensor:
54 3 : GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "SHT3x: SN%x%x%x%x%x%x", sn[0], sn[1], sn[2], sn[3], sn[4], sn[5]);
55 :
56 : // reset
57 : static const uint8_t soft_reset_cmd[2] { 0x30, 0xA2 }; // page 12
58 3 : if (!_dev->transfer(soft_reset_cmd, ARRAY_SIZE(soft_reset_cmd), nullptr, 0)) {
59 0 : GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s reset failed", name);
60 0 : return;
61 : }
62 :
63 3 : hal.scheduler->delay(4);
64 :
65 3 : start_next_sample();
66 :
67 : // lower retries for run
68 3 : _dev->set_retries(3);
69 :
70 : /* Request 20Hz update */
71 3 : _dev->register_periodic_callback(50 * AP_USEC_PER_MSEC,
72 : FUNCTOR_BIND_MEMBER(&AP_TemperatureSensor_SHT3x::_timer, void));
73 9 : }
74 :
75 847 : bool AP_TemperatureSensor_SHT3x::read_measurements(uint16_t &temp, uint16_t &humidity) const
76 : {
77 : uint8_t val[6];
78 847 : if (!_dev->transfer(nullptr, 1, val, ARRAY_SIZE(val))) {
79 0 : return 0;
80 : }
81 :
82 847 : if (val[2] != crc8_generic(&val[0], 2, 0x31, 0xff)) {
83 : // temperature CRC is incorrect
84 0 : return false;
85 : }
86 :
87 847 : if (val[5] != crc8_generic(&val[3], 2, 0x31, 0xff)) {
88 : // humidity CRC is incorrect
89 0 : return false;
90 : }
91 :
92 847 : temp = val[0] << 8 | val[1];
93 847 : humidity = val[3] << 8 | val[4];
94 847 : return true;
95 : }
96 :
97 847 : void AP_TemperatureSensor_SHT3x::_timer(void)
98 : {
99 : uint16_t encoded_temp;
100 : uint16_t encoded_humidity;
101 847 : if (read_measurements(encoded_temp, encoded_humidity)) {
102 847 : const float temp = -45 + 175 * (encoded_temp/65535.0);
103 847 : set_temperature(temp);
104 : }
105 :
106 847 : start_next_sample();
107 847 : }
108 :
109 850 : void AP_TemperatureSensor_SHT3x::start_next_sample()
110 : {
111 : static const uint8_t start_measurement_command[2] { 0x2c, 0x06 };
112 850 : _dev->transfer(start_measurement_command, ARRAY_SIZE(start_measurement_command), nullptr, 0);
113 850 : }
114 :
115 : #endif // AP_TEMPERATURE_SENSOR_SHT3X_ENABLED
|