-
Notifications
You must be signed in to change notification settings - Fork 12
/
SparkFun_Si7021_Breakout_Library.cpp
executable file
·250 lines (209 loc) · 5.4 KB
/
SparkFun_Si7021_Breakout_Library.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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/*
SparkFun Si7021 Temperature and HUmidity Breakout
By: Joel Bartlett
SparkFun Electronics
Date: December 10, 2015
This is an Arduino library for the Si7021 Temperature and Humidity Sensor Breakout
This library is based on the following libraries:
HTU21D Temperature / Humidity Sensor Library
By: Nathan Seidle
https://github.com/sparkfun/HTU21D_Breakout/tree/master/Libraries
Arduino Si7010 relative humidity + temperature sensor
By: Jakub Kaminski, 2014
https://github.com/teoqba/ADDRESS
This Library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
For a copy of the GNU General Public License, see
<http://www.gnu.org/licenses/>.
*/
#if defined(ARDUINO)
#include "Wire.h"
#include "SparkFun_Si7021_Breakout_Library.h"
#elif defined(SPARK)
#include "SparkFun_Si7021_Breakout_Library/SparkFun_Si7021_Breakout_Library.h"
#endif
//Initialize
Weather::Weather(){}
int Weather::begin(void)
{
int x = 0;
Wire.begin();
uint8_t ID_Temp_Hum = checkID();
if(ID_Temp_Hum == 0x15)//Ping CheckID register
x = 1;
else if(ID_Temp_Hum == 0x32)
x = 2;
else
x = 0;
if(x == 1)
{
#ifdef PRINT
Serial.println(F("Si7021 Sensor Found."));
//Serial.println(ID_Temp_Hum, HEX);
#endif
}
else if(x == 2)
{
#ifdef PRINT
Serial.println(F("HTU21D Sensor Found."));
//Serial.println(ID_Temp_Hum, HEX);
#endif
}
else
{
#ifdef PRINT
Serial.println(F("Si7021 / HTU21D not Found."));
//Serial.println(ID_Temp_Hum, HEX);
#endif
}
return x;
}
/****************Si7021 & HTU21D Functions**************************************/
float Weather::getRH()
{
// Measure the relative humidity
uint16_t RH_Code = makeMeasurment(HUMD_MEASURE_NOHOLD);
float result = (125.0*RH_Code/65536)-6;
return result;
}
float Weather::readTemp()
{
// Read temperature from previous RH measurement.
uint16_t temp_Code = makeMeasurment(TEMP_PREV);
float result = (175.25*temp_Code/65536)-46.85;
return result;
}
float Weather::getTemp()
{
// Measure temperature
uint16_t temp_Code = makeMeasurment(TEMP_MEASURE_NOHOLD);
float result = (175.25*temp_Code/65536)-46.85;
return result;
}
//Give me temperature in fahrenheit!
float Weather::readTempF()
{
return((readTemp() * 1.8) + 32.0); // Convert celsius to fahrenheit
}
float Weather::getTempF()
{
return((getTemp() * 1.8) + 32.0); // Convert celsius to fahrenheit
}
void Weather::heaterOn()
{
// Turns on the ADDRESS heater
uint8_t regVal = readReg();
regVal |= _BV(HTRE);
//turn on the heater
writeReg(regVal);
}
void Weather::heaterOff()
{
// Turns off the ADDRESS heater
uint8_t regVal = readReg();
regVal &= ~_BV(HTRE);
writeReg(regVal);
}
void Weather::changeResolution(uint8_t i)
{
// Changes to resolution of ADDRESS measurements.
// Set i to:
// RH Temp
// 0: 12 bit 14 bit (default)
// 1: 8 bit 12 bit
// 2: 10 bit 13 bit
// 3: 11 bit 11 bit
uint8_t regVal = readReg();
// zero resolution bits
regVal &= 0b011111110;
switch (i) {
case 1:
regVal |= 0b00000001;
break;
case 2:
regVal |= 0b10000000;
break;
case 3:
regVal |= 0b10000001;
default:
regVal |= 0b00000000;
break;
}
// write new resolution settings to the register
writeReg(regVal);
}
void Weather::reset()
{
//Reset user resister
writeReg(SOFT_RESET);
}
uint8_t Weather::checkID()
{
uint8_t ID_1;
// Check device ID
Wire.beginTransmission(ADDRESS);
Wire.write(0xFC);
Wire.write(0xC9);
Wire.endTransmission();
Wire.requestFrom(ADDRESS,1);
ID_1 = Wire.read();
return(ID_1);
}
uint16_t Weather::makeMeasurment(uint8_t command)
{
// Take one ADDRESS measurement given by command.
// It can be either temperature or relative humidity
// TODO: implement checksum checking
uint16_t nBytes = 3;
// if we are only reading old temperature, read olny msb and lsb
if (command == 0xE0) nBytes = 2;
Wire.beginTransmission(ADDRESS);
Wire.write(command);
Wire.endTransmission();
// When not using clock stretching (*_NOHOLD commands) delay here
// is needed to wait for the measurement.
// According to datasheet the max. conversion time is ~22ms
delay(100);
Wire.requestFrom(ADDRESS,nBytes);
//Wait for data
int counter = 0;
while (Wire.available() < nBytes){
delay(1);
counter ++;
if (counter >100){
// Timeout: Sensor did not return any data
return 100;
}
}
unsigned int msb = Wire.read();
unsigned int lsb = Wire.read();
// Clear the last to bits of LSB to 00.
// According to datasheet LSB of RH is always xxxxxx10
lsb &= 0xFC;
unsigned int mesurment = msb << 8 | lsb;
return mesurment;
}
void Weather::writeReg(uint8_t value)
{
// Write to user register on ADDRESS
Wire.beginTransmission(ADDRESS);
Wire.write(WRITE_USER_REG);
Wire.write(value);
Wire.endTransmission();
}
uint8_t Weather::readReg()
{
// Read from user register on ADDRESS
Wire.beginTransmission(ADDRESS);
Wire.write(READ_USER_REG);
Wire.endTransmission();
Wire.requestFrom(ADDRESS,1);
uint8_t regVal = Wire.read();
return regVal;
}