-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSHT40.cpp
215 lines (161 loc) · 4.73 KB
/
SHT40.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/**
* @file SHT40.cpp
* @author silvio3105 (www.github.com/silvio3105)
* @brief SHT40 driver translation unit file.
*
* @copyright Copyright (c) 2022, silvio3105
*
*/
/*
License
Copyright (c) 2022, silvio3105
Access and use of this Project and its contents are granted free of charge to any Person.
The Person is allowed to copy, modify and use The Project and its contents only for non-commercial use.
Commercial use of this Project and its contents is prohibited.
Modifying this License and/or sublicensing is prohibited.
THE PROJECT AND ITS CONTENT ARE PROVIDED "AS IS" WITH ALL FAULTS AND WITHOUT EXPRESSED OR IMPLIED WARRANTY.
THE AUTHOR KEEPS ALL RIGHTS TO CHANGE OR REMOVE THE CONTENTS OF THIS PROJECT WITHOUT PREVIOUS NOTICE.
THE AUTHOR IS NOT RESPONSIBLE FOR DAMAGE OF ANY KIND OR LIABILITY CAUSED BY USING THE CONTENTS OF THIS PROJECT.
This License shall be included in all functional textual files.
*/
// ----- INCLUDE FILES
#include "SHT40.h"
#include <string.h>
// ----- STATIC FUNCTION DECLARATIONS
/**
* @brief Get required delay for measurement type.
*
* @param type Measurement type. See \ref SHT40_meas_t
* @return Required delay in ms.
*/
static uint16_t getMeasureDelay(SHT40_meas_t type);
// ----- METHODS DEFINITIONS
SHT40::SHT40(uint8_t addr, extI2C i2cr, extI2C i2cw)
{
// Store arguments into object
address = addr;
I2CRead = i2cr;
I2CWrite = i2cw;
// Set temperature unit
setUnit(SHT40_unit_t::SHT40_UNIT_C);
// Clear measured data
clear();
}
SHT40::~SHT40(void)
{
// Reset object to default
address = 0x00;
I2CRead = nullptr;
I2CWrite = nullptr;
controlReg = 0;
// Clear measured data
clear();
}
uint8_t SHT40::measure(SHT40_meas_t type)
{
// Write command to SHT40
I2CWrite(address, (uint8_t*)&type, 1, getMeasureDelay(type));
// Read from SHT40
I2CRead(address, (uint8_t*)&mData, 6, 0);
// If NAK is received
if (header == SHT40_NAK) return SHT40_NOK;
// Clear old data flags
controlReg &= ~(SHT40_OLD_RH | SHT40_OLD_TEMP);
return SHT40_OK;
}
uint8_t SHT40::temperature(int8_t& out)
{
uint8_t ret = SHT40_OK;
// If temperature data is zero or old
if (!mData.temp[0] && !mData.temp[1]) return SHT40_NOK;
if (controlReg & SHT40_OLD_TEMP) ret = SHT40_OLD_DATA;
// Calculate temperature from SHT40 data in desired temperature unit
if (getUnit() == SHT40_UNIT_C) out = -45 + (175 * ((mData.temp[0] << 8) | mData.temp[1]) / 655) / 100;
else out = -49 + (315 * (((mData.temp[0] << 8) | mData.temp[1]) / 655)) / 100;
// Set old data flag for temperature
controlReg |= SHT40_OLD_TEMP;
return ret;
}
uint8_t SHT40::rh(uint8_t& out)
{
uint8_t ret = SHT40_OK;
// If RH data is zero or old
if (!mData.rh[0] && !mData.rh[1]) return SHT40_NOK;
if (controlReg & SHT40_OLD_RH) ret = SHT40_OLD_DATA;
// Calculate RH from SHT40 data
out = -6 + (125 * (((mData.rh[0] << 8) | mData.rh[1]) / 655)) / 100;
// Limit output value between 0 and 100
if (out > 100) out = 100;
else if (out < 0) out = 0;
// Set old data flag FOR RH
controlReg |= SHT40_OLD_RH;
return ret;
}
uint32_t SHT40::whoAmI(void)
{
uint8_t cmd = SHT40_SN;
// Send S/N read command
I2CWrite(address, (uint8_t*)&cmd, 1, 1);
// Read S/N from SHT40
I2CRead(address, (uint8_t*)&snData, 6, 0);
// If NAK is received
if (header == SHT40_NAK) return SHT40_NOK;
// Concat 2x16-bit S/N data to 32-bit S/N
return ((snData.sn1 << 16) | snData.sn2);
}
void SHT40::reset(void) const
{
uint8_t cmd = SHT40_RST;
// Send reset command to SHT40
I2CWrite(address, (uint8_t*)&cmd, 1, 0);
}
uint8_t SHT40::init(SHT40_unit_t u)
{
// If external read and/or write methods are not provided
if (!I2CRead) return SHT40_I2CH_R;
if (!I2CWrite) return SHT40_I2CH_W;
// Set temperature unit
setUnit(u);
// Read SHT40's S/N
uint32_t tmp = whoAmI();
// If S/N is bits are not zeros or ones
if (!tmp || tmp == 0xFFFFFFFF) return SHT40_NOK;
return SHT40_OK;
}
void SHT40::setUnit(SHT40_unit_t unit)
{
// Set new temperature unit
controlReg &= ~SHT40_UNIT;
controlReg |= (unit << SHT40_UNIT_POS);
}
SHT40_unit_t SHT40::getUnit(void) const
{
// Return temperature unit
return (SHT40_unit_t)(controlReg & SHT40_UNIT);
}
void SHT40::clear(void)
{
// Clear measured data
memset(&mData, 0, sizeof(mData));
// Clear old data flags
controlReg &= ~(SHT40_OLD_RH | SHT40_OLD_TEMP);
}
// ----- STATIC FUNCTION DEFINITIONS
static uint16_t getMeasureDelay(SHT40_meas_t type)
{
switch (type)
{
case TRH_H: return 9; // 8.2ms
case TRH_M: return 5; // 4.5ms
case TRH_L: return 2; // 1.7ms
case TRH_H_H02W1S:
case TRH_H_H011W1S:
case TRH_H_H002W1S: return 1150; // 1100ms
case TRH_H_H02W01S:
case TRH_H_H011W01S:
case TRH_H_H002W01S: return 120; // 110ms
default: break;
}
return 1;
}
// END WITH NEW LINE