-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathI2CSoilMoistureSensor.cpp
More file actions
executable file
·231 lines (209 loc) · 10.6 KB
/
I2CSoilMoistureSensor.cpp
File metadata and controls
executable file
·231 lines (209 loc) · 10.6 KB
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
/*----------------------------------------------------------------------*
* I2CSoilMoistureSensor.cpp - Arduino library for the Sensor version of*
* I2C Soil Moisture Sensor version from Chrirp *
* (https://github.com/Miceuz/i2c-moisture-sensor). *
* *
* Ingo Fischer 11Nov2015 *
* https://github.com/Apollon77/I2CSoilMoistureSensor *
* *
* MIT license *
*----------------------------------------------------------------------*/
#include "I2CSoilMoistureSensor.h"
//define release-independent I2C functions
#if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
#include <TinyWireM.h>
#define i2cBegin TinyWireM.begin
#define i2cBeginTransmission TinyWireM.beginTransmission
#define i2cEndTransmission TinyWireM.endTransmission
#define i2cRequestFrom TinyWireM.requestFrom
#define i2cRead TinyWireM.receive
#define i2cWrite TinyWireM.send
#elif ARDUINO >= 100
#include <Wire.h>
#define i2cBegin Wire.begin
#define i2cBeginTransmission Wire.beginTransmission
#define i2cEndTransmission Wire.endTransmission
#define i2cRequestFrom Wire.requestFrom
#define i2cRead Wire.read
#define i2cWrite Wire.write
#else
#include <Wire.h>
#define i2cBegin Wire.begin
#define i2cBeginTransmission Wire.beginTransmission
#define i2cEndTransmission Wire.endTransmission
#define i2cRequestFrom Wire.requestFrom
#define i2cRead Wire.receive
#define i2cWrite Wire.send
#endif
/*----------------------------------------------------------------------*
* Constructor. *
* Optionally set sensor I2C address if different from default *
*----------------------------------------------------------------------*/
I2CSoilMoistureSensor::I2CSoilMoistureSensor(uint8_t addr) : sensorAddress(addr) {
// nothing to do ... Wire.begin needs to be put outside of class
}
/*----------------------------------------------------------------------*
* Initializes anything ... it does a reset. *
* When used without parameter or parameter value is false then a *
* waiting time of at least 1 second is expected to give the sensor *
* some time to boot up. *
* Alternatively use true as parameter and the method waits for a *
* second and returns after that. *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::begin(bool wait) {
resetSensor();
if (wait) {
delay(1000);
}
}
/*----------------------------------------------------------------------*
* Return measured Soil Moisture Capacitance *
* Moisture is somewhat linear. More moisture will give you higher *
* reading. Normally all sensors give about 290 - 310 as value in free *
* air at 5V supply. *
*----------------------------------------------------------------------*/
unsigned int I2CSoilMoistureSensor::getCapacitance() {
return readI2CRegister16bitUnsigned(sensorAddress, SOILMOISTURESENSOR_GET_CAPACITANCE);
}
/*----------------------------------------------------------------------*
* Change I2C address of the sensor to the provided address (1..127) *
* and do a reset after it in order for the new address to become *
* effective if second parameter is true. *
* Method returns true if the new address is set successfully on sensor.*
*----------------------------------------------------------------------*/
bool I2CSoilMoistureSensor::setAddress(int addr, bool reset) {
writeI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_SET_ADDRESS, addr);
writeI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_SET_ADDRESS, addr);
if (reset) {
resetSensor();
delay(1000);
}
sensorAddress=addr;
return (readI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_GET_ADDRESS) == addr);
}
/*----------------------------------------------------------------------*
* Change the address (1..127) this instance is trying to read from *
* and do a reset after to initialize. *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::changeSensor(int addr, bool wait) {
sensorAddress=addr;
begin(wait);
}
/*----------------------------------------------------------------------*
* Return current Address of the Sensor *
*----------------------------------------------------------------------*/
uint8_t I2CSoilMoistureSensor::getAddress() {
return sensorAddress;
}
/*----------------------------------------------------------------------*
* Starts the measurement for the Light sensor. Wait at least 3 seconds *
* till you call method getLight to get the Light value. *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::startMeasureLight() {
writeI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_MEASURE_LIGHT);
}
/*----------------------------------------------------------------------*
* Read the Light Measurement from the sensor. When used without *
* parameter or parameter value is false then a former call to *
* method startMeasureLight and a waiting time of at least 3 seconds is *
* expected. *
* Alternatively use true as parameter and the method does the call to *
* startMeasureLight and a 3 seconds delay automatically and no former *
* call is needed. *
* The measurement gives 65535 in a dark room away form desk lamp - so *
* more light, lower reading. When it's dark, it takes longer to *
* measure light, reading the light register while measurement is in *
* progress (e.g. wait time too short) will return the previous reading.*
* Be aware, light sensor is pretty noisy. *
*----------------------------------------------------------------------*/
unsigned int I2CSoilMoistureSensor::getLight(bool wait) {
if (wait) {
startMeasureLight();
delay(3000);
}
return readI2CRegister16bitUnsigned(sensorAddress, SOILMOISTURESENSOR_GET_LIGHT);
}
/*----------------------------------------------------------------------*
* Read the Temperature Measurement. Temperature is measured by the *
* thermistor on the tip of the sensor. Calculated absolute measurement *
* accuracy is better than 2%. The returned value is in degrees Celsius *
* with factor 10, so need to divide by 10 to get real value *
*----------------------------------------------------------------------*/
int I2CSoilMoistureSensor::getTemperature() {
return readI2CRegister16bitSigned(sensorAddress, SOILMOISTURESENSOR_GET_TEMPERATURE);
}
/*----------------------------------------------------------------------*
* Resets sensor. Give the sensor 0.5-1 second time to boot up after *
* reset. *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::resetSensor() {
writeI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_RESET);
}
/*----------------------------------------------------------------------*
* Get Firmware Version. 0x22 means 2.2 *
*----------------------------------------------------------------------*/
uint8_t I2CSoilMoistureSensor::getVersion() {
return readI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_GET_VERSION);
}
/*----------------------------------------------------------------------*
* Sleep sensor. Initiates SLEEP_MODE_PWR_DOWN in the sensor's MCU. *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::sleep() {
writeI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_SLEEP);
}
/*----------------------------------------------------------------------*
* Check if sensor is busy. Returns true if a measurement is running. *
*----------------------------------------------------------------------*/
bool I2CSoilMoistureSensor::isBusy() {
return (readI2CRegister8bit(sensorAddress, SOILMOISTURESENSOR_GET_BUSY) == 1);
}
/*----------------------------------------------------------------------*
* Helper method to write an 8 bit value to the sensor via I2C *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::writeI2CRegister8bit(int addr, int value) {
i2cBeginTransmission(addr);
i2cWrite(value);
i2cEndTransmission();
}
/*----------------------------------------------------------------------*
* Helper method to write an 8 bit value to the sensor via I2C to the *
* given register *
*----------------------------------------------------------------------*/
void I2CSoilMoistureSensor::writeI2CRegister8bit(int addr, int reg, int value) {
i2cBeginTransmission(addr);
i2cWrite(reg);
i2cWrite(value);
i2cEndTransmission();
}
/*----------------------------------------------------------------------*
* Helper method to read a 16 bit unsigned value from the given register*
*----------------------------------------------------------------------*/
uint16_t I2CSoilMoistureSensor::readI2CRegister16bitUnsigned(int addr, byte reg)
{
uint16_t value;
i2cBeginTransmission((uint8_t)addr);
i2cWrite((uint8_t)reg);
i2cEndTransmission();
delay(20);
i2cRequestFrom((uint8_t)addr, (byte)2);
value = (i2cRead() << 8) | i2cRead();
return value;
}
/*----------------------------------------------------------------------*
* Helper method to read a 16 bit signed value from the given register*
*----------------------------------------------------------------------*/
int16_t I2CSoilMoistureSensor::readI2CRegister16bitSigned(int addr, byte reg)
{
return (int16_t)readI2CRegister16bitUnsigned(addr, reg);
}
/*----------------------------------------------------------------------*
* Helper method to read a 8 bit value from the given register *
*----------------------------------------------------------------------*/
uint8_t I2CSoilMoistureSensor::readI2CRegister8bit(int addr, int reg) {
i2cBeginTransmission(addr);
i2cWrite(reg);
i2cEndTransmission();
delay(20);
i2cRequestFrom(addr, 1);
return i2cRead();
}