mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/si70xx: Add support for Si705x sensors
The Silicon Labs Si705x sensors (Si7050/1/3/4/5) are very similar to the Si7021 sensors featuring only a temperature sensor and no humidity sensor. The only difference between the Si705x is the temperature accuracy of the reading, ranging from +/- 0.1 C in the Si7051 to +/- 1 C in the Si7050. This patch adds support for this family of sensors extending the functionality of the existing si70xx driver. Following the style of other modules, this implements a pseudomodule per supported chip, adding si7050, si7051, si7053, si7054 and si7055 pseudomodules. As a minor change this patch also implements the missing si70xx_get_serial, si70xx_get_id and si70xx_get_revision functions that were declared in the si70xx.h header but implemented as private functions. The si70xx_get_id() may be relevant for the application to know at run time exactly which version of the hardware is installed. The updated test running with a Si7051 shows the following output, which seems consistent with the room temperature conditions during the test. ``` make SI70XX_VARIANT=si7051 -C tests/driver_si70xx/ all flash ``` ``` SI70XX temperature and humidity sensor test application Initializing sensor... [OK] Found SI7051 sensor, revision 32 temperature: 24.71 C temperature: 24.69 C ```
This commit is contained in:
parent
dec82b2475
commit
f72efb1daf
@ -7,10 +7,19 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_si70xx Si7006/13/20/21 temperature and humidity sensors
|
||||
* @defgroup drivers_si70xx Si7006/13/20/21/5x temperature and humidity sensors
|
||||
* @ingroup drivers_sensors
|
||||
* @ingroup drivers_saul
|
||||
* @brief Driver for the Si7006/13/20/21 temperature and humidity sensor
|
||||
* @brief Driver for the Si7006/13/20/21/5x temperature and humidity sensor
|
||||
*
|
||||
* The Si70xx driver supports a range of similar temperature and humidity
|
||||
* sensors from Silicon Labs.
|
||||
*
|
||||
* The Si7006/13/20/21 sensors support both temperature and relative humidity
|
||||
* reading, while the Si7050/1/3/4/5 sensors only provide a temperature reading
|
||||
* varying in accuracy between +/- 0.1 C to +/- 1.0 C depending on the model.
|
||||
*
|
||||
* For any of the Si705x models, use the pseudo module @p si705x.
|
||||
*
|
||||
* This driver provides @ref drivers_saul capabilities.
|
||||
* @{
|
||||
@ -30,6 +39,17 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Compile time macro telling whether the chip has a humidity sensor.
|
||||
*/
|
||||
#if MODULE_SI7050 || MODULE_SI7051 || MODULE_SI7053 || MODULE_SI7054 || \
|
||||
MODULE_SI7055
|
||||
/* Si705x sensors don't have a humidity sensor hardware, only temperature. */
|
||||
#define SI70XX_HAS_HUMIDITY_SENSOR 0
|
||||
#else
|
||||
#define SI70XX_HAS_HUMIDITY_SENSOR 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Driver return codes
|
||||
*/
|
||||
@ -67,13 +87,17 @@ typedef struct {
|
||||
*/
|
||||
int si70xx_init(si70xx_t *dev, const si70xx_params_t *params);
|
||||
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN
|
||||
/**
|
||||
* @brief Read the relative humidity from the sensor. Uses clock stretching.
|
||||
*
|
||||
* This function is only available in models that have a humidity sensor.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @return relative humidity in centi-percent (times 100)
|
||||
*/
|
||||
uint16_t si70xx_get_relative_humidity(const si70xx_t *dev);
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Read the current temperature from the sensor. Uses clock stretching.
|
||||
@ -84,15 +108,19 @@ uint16_t si70xx_get_relative_humidity(const si70xx_t *dev);
|
||||
*/
|
||||
int16_t si70xx_get_temperature(const si70xx_t *dev);
|
||||
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN
|
||||
/**
|
||||
* @brief Read the relative humidity and temperature from the sensor. Uses
|
||||
* clock stretching.
|
||||
*
|
||||
* This function is only available in models that have a humidity sensor.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] humidity pointer to relative humidity (in centi-percent)
|
||||
* @param[out] temperature pointer to temperature (in centi-degrees Celsius)
|
||||
*/
|
||||
void si70xx_get_both(const si70xx_t *dev, uint16_t *humidity, int16_t *temperature);
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR || DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Read the sensor serial number.
|
||||
|
@ -29,6 +29,15 @@
|
||||
*/
|
||||
#define SI70XX_NUM ARRAY_SIZE(si70xx_params)
|
||||
|
||||
/**
|
||||
* @brief Define the number of SAUL registry entries
|
||||
*/
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
#define SI70XX_SAUL_ENTRIES_NUM 2
|
||||
#else
|
||||
#define SI70XX_SAUL_ENTRIES_NUM 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Allocation of memory for device descriptors
|
||||
*/
|
||||
@ -37,7 +46,7 @@ static si70xx_t si70xx_devs[SI70XX_NUM];
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[SI70XX_NUM * 2];
|
||||
static saul_reg_t saul_entries[SI70XX_NUM * SI70XX_SAUL_ENTRIES_NUM];
|
||||
|
||||
/**
|
||||
* @brief Define the number of saul info
|
||||
@ -56,6 +65,7 @@ void auto_init_si70xx(void)
|
||||
{
|
||||
assert(SI70XX_INFO_NUM == SI70XX_NUM);
|
||||
|
||||
unsigned entry = 0;
|
||||
for (unsigned i = 0; i < SI70XX_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing SI70xx #%u\n", i);
|
||||
|
||||
@ -65,17 +75,17 @@ void auto_init_si70xx(void)
|
||||
}
|
||||
|
||||
/* temperature */
|
||||
saul_entries[i * 2].dev = &si70xx_devs[i];
|
||||
saul_entries[i * 2].name = si70xx_saul_info[i].name;
|
||||
saul_entries[i * 2].driver = &si70xx_temperature_saul_driver;
|
||||
saul_entries[entry].dev = &si70xx_devs[i];
|
||||
saul_entries[entry].name = si70xx_saul_info[i].name;
|
||||
saul_entries[entry].driver = &si70xx_temperature_saul_driver;
|
||||
saul_reg_add(&saul_entries[entry++]);
|
||||
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
/* relative humidity */
|
||||
saul_entries[(i * 2) + 1].dev = &si70xx_devs[i];
|
||||
saul_entries[(i * 2) + 1].name = si70xx_saul_info[i].name;
|
||||
saul_entries[(i * 2) + 1].driver = \
|
||||
&si70xx_relative_humidity_saul_driver;
|
||||
|
||||
saul_reg_add(&saul_entries[i * 2]);
|
||||
saul_reg_add(&saul_entries[(i * 2) + 1]);
|
||||
saul_entries[entry].dev = &si70xx_devs[i];
|
||||
saul_entries[entry].name = si70xx_saul_info[i].name;
|
||||
saul_entries[entry].driver = &si70xx_relative_humidity_saul_driver;
|
||||
saul_reg_add(&saul_entries[entry++]);
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
}
|
||||
}
|
||||
|
@ -55,15 +55,25 @@ extern "C" {
|
||||
* @{
|
||||
*/
|
||||
#if defined(MODULE_SI7006)
|
||||
#define SI70XX_ID (0x06)
|
||||
#define SI70XX_ID (6)
|
||||
#elif defined(MODULE_SI7013)
|
||||
#define SI70XX_ID (0x0D)
|
||||
#define SI70XX_ID (13)
|
||||
#elif defined(MODULE_SI7020)
|
||||
#define SI70XX_ID (0x14)
|
||||
#define SI70XX_ID (20)
|
||||
#elif defined(MODULE_SI7021)
|
||||
#define SI70XX_ID (0x15)
|
||||
#define SI70XX_ID (21)
|
||||
#elif defined(MODULE_SI7050)
|
||||
#define SI70XX_ID (50)
|
||||
#elif defined(MODULE_SI7051)
|
||||
#define SI70XX_ID (51)
|
||||
#elif defined(MODULE_SI7053)
|
||||
#define SI70XX_ID (53)
|
||||
#elif defined(MODULE_SI7054)
|
||||
#define SI70XX_ID (54)
|
||||
#elif defined(MODULE_SI7055)
|
||||
#define SI70XX_ID (55)
|
||||
#else
|
||||
#error "Please provide a valid Si70xx variant (Si7006/13/20/21)"
|
||||
#error "Please provide a valid Si70xx variant (Si7006/13/20/21/5X)"
|
||||
#endif
|
||||
|
||||
#define SI70XX_REVISION_1 (0xFF)
|
||||
|
@ -53,10 +53,7 @@ static uint16_t _do_measure(const si70xx_t *dev, uint8_t command)
|
||||
return ((uint16_t)result[0] << 8) + (result[1] & 0xfc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal helper function that reads the device serial number.
|
||||
*/
|
||||
static uint64_t _get_serial(const si70xx_t *dev)
|
||||
uint64_t si70xx_get_serial(const si70xx_t *dev)
|
||||
{
|
||||
uint8_t out[2];
|
||||
uint8_t in_first[8] = { 0 };
|
||||
@ -95,18 +92,12 @@ static uint64_t _get_serial(const si70xx_t *dev)
|
||||
return (((uint64_t) id_first) << 32) + id_second;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal helper function that reads the device identifier.
|
||||
*/
|
||||
static uint8_t _get_id(const si70xx_t *dev)
|
||||
uint8_t si70xx_get_id(const si70xx_t *dev)
|
||||
{
|
||||
return (_get_serial(dev) >> 24) & 0xff;
|
||||
return (si70xx_get_serial(dev) >> 24) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Internal helper function that reads the device serial revision.
|
||||
*/
|
||||
static uint8_t _get_revision(const si70xx_t *dev)
|
||||
uint8_t si70xx_get_revision(const si70xx_t *dev)
|
||||
{
|
||||
uint8_t out[2];
|
||||
uint8_t in = 0;
|
||||
@ -128,17 +119,19 @@ static uint8_t _get_revision(const si70xx_t *dev)
|
||||
|
||||
static int _test_device(const si70xx_t *dev)
|
||||
{
|
||||
uint8_t revision = _get_revision(dev);
|
||||
uint8_t revision = si70xx_get_revision(dev);
|
||||
|
||||
if (revision != SI70XX_REVISION_1 && revision != SI70XX_REVISION_2) {
|
||||
DEBUG("[ERROR] Bad device revision (%d).\n", revision);
|
||||
return -SI70XX_ERR_NODEV;
|
||||
}
|
||||
|
||||
uint8_t id = _get_id(dev);
|
||||
uint8_t id = si70xx_get_id(dev);
|
||||
|
||||
if (id != SI70XX_ID) {
|
||||
DEBUG("[ERROR] Not a valid Si7006/13/20/21 device\n");
|
||||
const bool valid_id = (id == SI70XX_ID);
|
||||
if (!valid_id) {
|
||||
DEBUG("[ERROR] Not a valid Si7006/13/20/21/5x device: %u\n",
|
||||
(unsigned)id);
|
||||
return -SI70XX_ERR_NODEV;;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ static int read_temperature(const void *dev, phydat_t *res)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
static int read_relative_humidity(const void *dev, phydat_t *res)
|
||||
{
|
||||
res->val[0] = (int32_t) si70xx_get_relative_humidity((const si70xx_t *)dev);
|
||||
@ -39,6 +40,7 @@ static int read_relative_humidity(const void *dev, phydat_t *res)
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
|
||||
const saul_driver_t si70xx_temperature_saul_driver = {
|
||||
.read = read_temperature,
|
||||
@ -46,8 +48,10 @@ const saul_driver_t si70xx_temperature_saul_driver = {
|
||||
.type = SAUL_SENSE_TEMP
|
||||
};
|
||||
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
const saul_driver_t si70xx_relative_humidity_saul_driver = {
|
||||
.read = read_relative_humidity,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_HUM
|
||||
};
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
|
@ -262,6 +262,11 @@ PSEUDOMODULES += si7006
|
||||
PSEUDOMODULES += si7013
|
||||
PSEUDOMODULES += si7020
|
||||
PSEUDOMODULES += si7021
|
||||
PSEUDOMODULES += si7050
|
||||
PSEUDOMODULES += si7051
|
||||
PSEUDOMODULES += si7053
|
||||
PSEUDOMODULES += si7054
|
||||
PSEUDOMODULES += si7055
|
||||
|
||||
#include variants of tmp00x drivers as pseudo modules
|
||||
PSEUDOMODULES += tmp006
|
||||
|
@ -1,6 +1,8 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
# This test should also work with Si7006, Si7013 and Si7020 variants.
|
||||
USEMODULE += si7021
|
||||
# This test should also work with si7006, si7013, si7020 and si705x variants.
|
||||
SI70XX_VARIANT ?= si7021
|
||||
|
||||
USEMODULE += $(SI70XX_VARIANT)
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
@ -29,10 +29,10 @@ int main(void)
|
||||
{
|
||||
si70xx_t dev;
|
||||
|
||||
puts("SI7021 temperature and humidity sensor test application");
|
||||
puts("SI70XX temperature and humidity sensor test application");
|
||||
|
||||
/* initialize the sensor */
|
||||
printf("Initializing sensor... ");
|
||||
puts("Initializing sensor... ");
|
||||
|
||||
if (si70xx_init(&dev, &si70xx_params[0]) == 0) {
|
||||
puts("[OK]");
|
||||
@ -42,13 +42,17 @@ int main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Found SI70%02d sensor, revision %d\n", si70xx_get_id(&dev),
|
||||
si70xx_get_revision(&dev));
|
||||
|
||||
/* read temperature and humidity every 1 seconds */
|
||||
bool both = false;
|
||||
|
||||
int16_t temperature;
|
||||
uint16_t humidity;
|
||||
|
||||
while (1) {
|
||||
int16_t temperature;
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
uint16_t humidity;
|
||||
|
||||
/* rotate the way of getting the data */
|
||||
if (both) {
|
||||
si70xx_get_both(&dev, &humidity, &temperature);
|
||||
@ -57,12 +61,17 @@ int main(void)
|
||||
temperature = si70xx_get_temperature(&dev);
|
||||
humidity = si70xx_get_relative_humidity(&dev);
|
||||
}
|
||||
|
||||
#else /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
temperature = si70xx_get_temperature(&dev);
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
both = !both;
|
||||
|
||||
/* display results */
|
||||
#if SI70XX_HAS_HUMIDITY_SENSOR
|
||||
printf("relative humidity: %d.%02d\n", humidity / 100, humidity % 100);
|
||||
printf("temperature: %d.%02d C\n", temperature / 100, temperature % 100);
|
||||
#endif /* SI70XX_HAS_HUMIDITY_SENSOR */
|
||||
printf("temperature: %d.%02d C\n", temperature / 100,
|
||||
temperature % 100);
|
||||
|
||||
/* sleep between measurements */
|
||||
xtimer_msleep(1000);
|
||||
|
Loading…
Reference in New Issue
Block a user