osd-contiki/examples/osd/arduino-soil-moisture/I2CSoilMoistureSensor-master/I2CSoilMoistureSensor.cpp
2017-03-24 11:08:45 +01:00

232 lines
10 KiB
C++
Executable file

/*----------------------------------------------------------------------*
* 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);
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();
i2cEndTransmission();
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();
}