si7005: Initial Implementation Silicon Labs Si7005 humidity and temperature sensor

Signed-off-by: Henry Bruce <henry.bruce@intel.com>
Signed-off-by: Abhishek Malik <abhishek.malik@intel.com>
This commit is contained in:
Henry Bruce 2016-01-06 15:31:05 -08:00 committed by Abhishek Malik
parent 4aeccf7714
commit 6f080db5cb
7 changed files with 484 additions and 0 deletions

View File

@ -0,0 +1,6 @@
include_directories(..)
set (libname "si7005")
set (libdescription "upm SI7005")
set (module_src ${libname}.cxx mraa-utils.cxx)
set (module_h ${libname}.h)
upm_module_init()

View File

@ -0,0 +1,8 @@
%module jsupm_si7005
%include "../upm.i"
%{
#include "si7005.h"
%}
%include "si7005.h"

72
src/si7005/mraa-utils.cxx Normal file
View File

@ -0,0 +1,72 @@
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "mraa-utils.h"
#include "mraa/gpio.hpp"
#define UPM_THROW(msg) throw std::runtime_error(std::string(__FUNCTION__) + ": " + (msg))
void MraaUtils::setGpio(int pin, int level)
{
/*
mraa_result_t status = MRAA_ERROR_NO_RESOURCES;
mraa_gpio_context gpio = mraa_gpio_init(pin);
if (gpio != NULL)
{
mraa_gpio_dir(gpio, MRAA_GPIO_OUT);
status = mraa_gpio_write(gpio, level);
mraa_gpio_close(gpio);
}
return status;
*/
mraa::Gpio gpio(pin);
gpio.dir(mraa::DIR_OUT);
if (gpio.write(level) != mraa::SUCCESS)
UPM_THROW("gpio write failed");
}
int MraaUtils::getGpio(int pin)
{
/*
mraa_result_t status = MRAA_ERROR_NO_RESOURCES;
mraa_gpio_context gpio = mraa_gpio_init(pin);
if (gpio != NULL)
{
status = mraa_gpio_dir(gpio, MRAA_GPIO_IN);
int value = mraa_gpio_read(gpio);
if (value != -1)
*level = value;
else
status = MRAA_ERROR_NO_RESOURCES;
mraa_gpio_close(gpio);
}
return status;
*/
mraa::Gpio gpio(pin);
gpio.dir(mraa::DIR_IN);
return gpio.read();
}

37
src/si7005/mraa-utils.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Author: Henry Bruce <henry.bruce@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "mraa/types.h"
class __attribute__ ((visibility("hidden"))) MraaUtils
{
public:
static void setGpio(int pin, int level);
static int getGpio(int pin);
};

11
src/si7005/pyupm_si7005.i Normal file
View File

@ -0,0 +1,11 @@
%module pyupm_si7005
%include "../upm.i"
%include "stdint.i"
%feature("autodoc", "3");
%include "si7005.h"
%{
#include "si7005.h"
%}

207
src/si7005/si7005.cxx Normal file
View File

@ -0,0 +1,207 @@
/*
* Author: Scott Ware <scott.r.ware@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include "mraa-utils.h"
#include "si7005.h"
/* REGISTER ADDRESSES */
#define SI7005_REG_STATUS ( 0x00 )
#define SI7005_REG_DATA_LENGTH ( 2 )
#define SI7005_REG_DATA_START ( 0x01 )
#define SI7005_REG_DATA_HIGH ( 0 )
#define SI7005_REG_DATA_LOW ( 1 )
#define SI7005_REG_CONFIG ( 0x03 )
#define SI7005_REG_ID ( 0x11 )
/* STATUS REGISTER */
#define SI7005_STATUS_NOT_READY ( 0x01 )
/* CONFIG REGISTER */
#define SI7005_CONFIG_START ( 0x01 )
#define SI7005_CONFIG_HEAT ( 0x02 )
#define SI7005_CONFIG_HUMIDITY ( 0x00 )
#define SI7005_CONFIG_TEMPERATURE ( 0x10 )
#define SI7005_CONFIG_FAST ( 0x20 )
#define SI7005_CONFIG_RESET ( 0x00 )
/* ID REGISTER */
#define SI7005_ID ( 0x50 )
/* COEFFICIENTS */
#define SI7005_TEMPERATURE_OFFSET ( 50 )
#define SI7005_TEMPERATURE_SLOPE ( 32 )
#define SI7005_HUMIDITY_OFFSET ( 24 )
#define SI7005_HUMIDITY_SLOPE ( 16 )
#define A0 ( -4.7844 )
#define A1 ( 0.4008 )
#define A2 ( -0.00393 )
#define Q0 ( 0.1973 )
#define Q1 ( 0.00237 )
/* MISCELLANEOUS */
#define SI7005_WAKE_UP_TIME ( 15000 )
using namespace upm;
SI7005::SI7005 (int bus, int pin) {
m_controlAddr = SI7005_ADDRESS;
m_bus = bus;
m_pin = pin;
last_temperature = 25.0;
config_reg = SI7005_CONFIG_RESET;
// Disable chip until we need to do something with it
MraaUtils::setGpio(m_pin, 1);
m_i2c = new mraa::I2c(m_bus);
status = m_i2c->address(m_controlAddr);
if (!isAvailable())
UPM_THROW("config failure");
}
SI7005::~SI7005() {
delete m_i2c;
}
uint16_t
SI7005::getTemperatureRaw () {
return getMeasurement( SI7005_CONFIG_TEMPERATURE );
}
int
SI7005::getTemperatureCelcius () {
uint16_t rawTemperature = getTemperatureRaw();
rawTemperature = ((rawTemperature >> 2) & 0xFFFF);
last_temperature = ((float)rawTemperature) / SI7005_TEMPERATURE_SLOPE - SI7005_TEMPERATURE_OFFSET;
return static_cast<int>(last_temperature + 0.5);
}
uint16_t
SI7005::getHumidityRaw () {
return getMeasurement( SI7005_CONFIG_HUMIDITY );
}
int
SI7005::getHumidityRelative () {
uint16_t rawHumidity = getHumidityRaw();
rawHumidity = ((rawHumidity >> 4) & 0xFFFF);
float linearHumidity = ((float)rawHumidity) / SI7005_HUMIDITY_SLOPE - SI7005_HUMIDITY_OFFSET;
linearHumidity -= A2 * linearHumidity * linearHumidity + A1 * linearHumidity + A0;
linearHumidity += ( last_temperature - 30 ) * ( Q1 * linearHumidity + Q0 );
return static_cast<int>(linearHumidity + 0.5);
}
uint16_t SI7005::getMeasurement(uint8_t configValue) {
uint16_t rawData;
uint8_t data[SI7005_REG_DATA_LENGTH];
uint8_t measurementStatus;
// Enable the sensor
MraaUtils::setGpio(m_pin, 0);
// Wait for sensor to wake up
usleep(SI7005_WAKE_UP_TIME);
// Setup config register
m_i2c->address(m_controlAddr);
status = m_i2c->writeReg(SI7005_REG_CONFIG, SI7005_CONFIG_START | configValue | config_reg);
// FIXME: readReg() returns 0 on failure which is same as "reading ready" status
// FIXME: no timeout if device never gets to "reading ready" status
// Wait for the measurement to finish
measurementStatus = SI7005_STATUS_NOT_READY;
while ( measurementStatus == SI7005_STATUS_NOT_READY ) {
measurementStatus = m_i2c->readReg(SI7005_REG_STATUS);
}
// Read data registers
int length = m_i2c->readBytesReg(SI7005_REG_DATA_START, data, SI7005_REG_DATA_LENGTH);
// Disable the sensor
MraaUtils::setGpio(m_pin, 1);
// Check we got the data we need
if(length != SI7005_REG_DATA_LENGTH)
UPM_THROW("read error");
// Merge MSB and LSB
rawData = ((uint16_t)( data[SI7005_REG_DATA_LOW] & 0xFFFF )) + ( (uint16_t)(( data[SI7005_REG_DATA_HIGH] & 0xFFFF ) << 8 ));
return rawData;
}
bool
SI7005::isConfigured() {
return status == mraa::SUCCESS;
}
bool
SI7005::isAvailable( )
{
// Enable the sensor
MraaUtils::setGpio(m_pin, 0);
// Wait for sensor to wake up
usleep(SI7005_WAKE_UP_TIME);
// Read id register
m_i2c->address(m_controlAddr);
uint8_t deviceID = m_i2c->readReg(SI7005_REG_ID);
// Disable the sensor
MraaUtils::setGpio(m_pin, 1);
return (( deviceID & SI7005_ID) == SI7005_ID );
}
void
SI7005::enableHeater( )
{
config_reg |= SI7005_CONFIG_HEAT;
}
void
SI7005::disableHeater( )
{
config_reg ^= SI7005_CONFIG_HEAT;
}
void
SI7005::enableFastConversionMode( )
{
config_reg |= SI7005_CONFIG_FAST;
}
void
SI7005::disableFastConversionMode( )
{
config_reg ^= SI7005_CONFIG_FAST;
}

143
src/si7005/si7005.h Normal file
View File

@ -0,0 +1,143 @@
/*
* Author: Scott Ware <scott.r.ware@intel.com>
* Copyright (c) 2014 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <mraa/i2c.hpp>
#include "upm/iTemperatureSensor.h"
#include "upm/iHumiditySensor.h"
/* ADDRESS AND NOT_FOUND VALUE */
#define SI7005_ADDRESS ( 0x40 )
#define SI7005_NOT_FOUND ( 0x00 )
namespace upm {
/**
* @brief Si7005 digital I2C humidity and temperature sensor library
* @defgroup si7005 libupm-si7005
* @ingroup i2c silabs temp itemperaturesensor
*/
/**
* @brief C++ API for SI7005 sensor (Humidity And Temperature Sensor)
*
* The Silicon Labs Si7005
* [SI7005](https://www.silabs.com/Support%20Documents/TechnicalDocs/Si7005.pdf)
* is a digital relative humidity and temperature sensor.
*
* @library si7005
* @sensor si7005
* @comname Silicon Labs Si7005 LED lighting controller
* @altname Si7005
* @type temp
* @man silabs
* @con i2c
* @if itemperaturesensor
*/
class SI7005 : public ITemperatureSensor, public IHumiditySensor {
public:
/**
* Instantiates a SI7005 object
*
* @param bus number of used bus
* @param devAddr address of used i2c device
* @param pin mraa gpio number for chip select pin
*/
SI7005 (int bus, int pin);
/**
* SI7005 object destructor.
*/
~SI7005 ();
/**
* Get temperature measurement.
*/
uint16_t getTemperatureRaw ();
/**
* Get temperature measurement.
*/
int getTemperatureCelcius ();
/**
* Get relative humidity measurement.
*/
uint16_t getHumidityRaw ();
/**
* Get relative humidity measurement.
*/
int getHumidityRelative ();
/**
* Returns whether the sensor is configured.
*/
bool isConfigured();
/**
* Returns sensor module name
*/
const char* getModuleName() { return "si7005"; }
/**
* Detects the sensor to ensure it is connected as required.
*/
bool isAvailable();
/**
* Enables the integrated heating element.
*/
void enableHeater();
/**
* Disables the integrated heating element.
*/
void disableHeater();
/**
* Enables fast conversion mode.
*/
void enableFastConversionMode();
/**
* Enables fast conversion mode.
*/
void disableFastConversionMode();
private:
int m_controlAddr;
int m_bus;
int m_pin;
mraa::I2c* m_i2c;
mraa::Result status;
uint8_t config_reg;
float last_temperature;
uint16_t getMeasurement(uint8_t configValue);
};
}