1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #3300 from gebart/pr/hih6130-initial

drivers/hih6310: Initial commit of HIH6310 driver
This commit is contained in:
Joakim Gebart 2015-07-20 19:23:58 +02:00
commit 7211208bdb
7 changed files with 327 additions and 0 deletions

View File

@ -330,3 +330,7 @@ endif
ifneq (,$(filter newlib,$(USEMODULE))) ifneq (,$(filter newlib,$(USEMODULE)))
USEMODULE += uart_stdio USEMODULE += uart_stdio
endif endif
ifneq (,$(filter hih6130,$(USEMODULE)))
USEMODULE += vtimer
endif

3
drivers/hih6130/Makefile Normal file
View File

@ -0,0 +1,3 @@
MODULE = hih6130
include $(RIOTBASE)/Makefile.base

140
drivers/hih6130/hih6130.c Normal file
View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup driver_hih6130
* @{
*
* @file
* @brief Device driver implementation for Honeywell HumidIcon Digital
* Humidity/Temperature Sensors: HIH-6130/6131 Series
*
* @author Joakim Gebart <joakim.gebart@eistec.se>
*
* @}
*/
#include <stddef.h>
#include <stdint.h>
#include "hih6130.h"
#include "periph/i2c.h"
#include "timex.h"
#include "vtimer.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/* Humidity is stored in the first 2 bytes of data */
#define HIH6130_HUMIDITY_DATA_LENGTH (2)
/* Humidity + temperature data is 4 bytes long */
#define HIH6130_FULL_DATA_LENGTH (4)
/* Bit mask for the status bits in the first byte transferred */
#define HIH6130_STATUS_MASK (0xc0)
/* Bit mask for the humidity data */
#define HIH6130_HUMIDITY_MASK (0x3fff)
/* Temperature data is left adjusted within the word */
#define HIH6130_TEMPERATURE_SHIFT (2)
enum {
HIH6130_STATUS_OK = 0x00,
/**
* stale data: data that has already been fetched since the last measurement
* cycle, or data fetched before the first measurement has been completed.
*/
HIH6130_STATUS_STALE_DATA = 0x40,
HIH6130_STATUS_COMMAND_MODE = 0x80,
HIH6130_STATUS_DIAGNOSTIC = 0xc0,
};
/** @brief Delay between requesting a measurement and data becoming ready */
static const timex_t measurement_delay = {
.seconds = 0, .microseconds = 50 * MS_IN_USEC, };
/** @brief Trigger a new measurement on the sensor */
static inline int hih6130_measurement_request(hih6130_t *dev)
{
i2c_acquire(dev->i2c);
/* An empty write request triggers a new measurement */
if (i2c_write_bytes(dev->i2c, dev->addr, (char *)NULL, 0) < 0) {
i2c_release(dev->i2c);
return -1;
}
i2c_release(dev->i2c);
return 0;
}
void hih6130_init(hih6130_t *dev, i2c_t i2c, uint8_t address)
{
/* write device descriptor */
dev->i2c = i2c;
dev->addr = address;
}
static inline int hih6130_get_humidity_temperature_raw(hih6130_t *dev, uint16_t *humidity_raw, uint16_t *temperature_raw)
{
int status;
uint8_t buf[HIH6130_FULL_DATA_LENGTH];
i2c_acquire(dev->i2c);
if (i2c_read_bytes(dev->i2c, dev->addr, (char*)&buf[0], sizeof(buf)) != sizeof(buf)) {
i2c_release(dev->i2c);
return -1;
}
i2c_release(dev->i2c);
/* data is in big-endian format, with status bits in the first byte. */
switch (buf[0] & HIH6130_STATUS_MASK) {
case HIH6130_STATUS_OK:
status = 0;
break;
case HIH6130_STATUS_STALE_DATA:
status = 1;
break;
default:
return -2;
}
*humidity_raw = ((buf[0] << 8) | buf[1]) & HIH6130_HUMIDITY_MASK;
*temperature_raw = (((buf[2] << 8) | buf[3]) >> HIH6130_TEMPERATURE_SHIFT);
return status;
}
int hih6130_get_humidity_temperature_float(hih6130_t *dev,
float *relative_humidity_percent, float *temperature_celsius)
{
uint16_t hum_raw, temp_raw;
int status;
if (hih6130_measurement_request(dev) != 0) {
return -1;
}
vtimer_sleep(measurement_delay);
status = hih6130_get_humidity_temperature_raw(dev, &hum_raw, &temp_raw);
if (status < 0) {
return -1;
}
if (relative_humidity_percent != NULL) {
*relative_humidity_percent = hum_raw * (100.f / 16383.f);
}
if (temperature_celsius != NULL) {
*temperature_celsius = temp_raw * (165.f / 16383.f) - 40.f;
}
return status;
}

70
drivers/include/hih6130.h Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup driver_hih6130 HIH6130 humidity and temperature sensor
* @ingroup drivers
* @brief Device driver for Honeywell HumidIcon Digital
* Humidity/Temperature Sensors: HIH-6130/6131 Series
* @{
*
* @file
* @brief Device driver for Honeywell HumidIcon Digital
* Humidity/Temperature Sensors: HIH-6130/6131 Series
*
* @author Joakim Gebart <joakim.gebart@eistec.se>
*/
#ifndef HIH6130_H_
#define HIH6130_H_
#include <stdint.h>
#include "periph/i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Device descriptor for HIH6130/HIH6131 sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device the sensor is connected to */
uint8_t addr; /**< the slave address of the sensor on the I2C bus */
} hih6130_t;
/**
* @brief Initialize a sensor
*
* @param[out] dev device descriptor of sensor to initialize
* @param[in] i2c I2C bus the sensor is connected to
* @param[in] address I2C slave address of the sensor
*/
void hih6130_init(hih6130_t *dev, i2c_t i2c, uint8_t address);
/**
* @brief Read humidity and temperature from sensor and convert to floating-point
*
* @param[in] dev Sensor device descriptor
* @param[out] relative_humidity_percent Measured relative humidity in percent
* @param[out] temperature_celsius Measured temperature in degrees Celsius
*
* @return 0 on success
* @return -1 on error
* @return 1 if data is stale
*/
int hih6130_get_humidity_temperature_float(hih6130_t *dev,
float *relative_humidity_percent, float *temperature_celsius);
#ifdef __cplusplus
}
#endif
#endif /* HIH6130_H_ */
/** @} */

View File

@ -0,0 +1,22 @@
APPLICATION = driver_hih6130
include ../Makefile.tests_common
FEATURES_REQUIRED = periph_i2c
USEMODULE += hih6130
USEMODULE += vtimer
ifneq (,$(TEST_HIH6130_I2C))
CFLAGS += -DTEST_HIH6130_I2C=$(TEST_HIH6130_I2C)
else
# set arbitrary default
CFLAGS += -DTEST_HIH6130_I2C=I2C_0
endif
ifneq (,$(TEST_HIH6130_ADDR))
CFLAGS += -DTEST_HIH6130_ADDR=$(TEST_HIH6130_ADDR)
else
# factory default address
CFLAGS += -DTEST_HIH6130_ADDR=0x27
endif
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,7 @@
# About
This is a manual test application for the HIH6130 humidity and temperature sensor.
# Usage
After initialization, the sensor reads the measurement values every 100ms
and prints them to the STDOUT.

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for the HIH6130 sensor driver
*
* @author Joakim Gebart <joakim.gebart@eistec.se>
*
* @}
*/
#ifndef TEST_HIH6130_I2C
#error "TEST_HIH6130_I2C not defined"
#endif
#ifndef TEST_HIH6130_ADDR
#error "TEST_HIH6130_ADDR not defined"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "vtimer.h"
#include "hih6130.h"
#define SLEEP (100 * 1000U)
int main(void)
{
hih6130_t dev;
puts("HIH6130 sensor driver test application\n");
printf("Initializing I2C_%i... ", TEST_HIH6130_I2C);
if (i2c_init_master(TEST_HIH6130_I2C, I2C_SPEED_FAST) < 0) {
puts("[Failed]");
return -1;
}
puts("[OK]");
printf("Initializing HIH6130 sensor at I2C_%i, address 0x%02x... ",
TEST_HIH6130_I2C, TEST_HIH6130_ADDR);
hih6130_init(&dev, TEST_HIH6130_I2C, TEST_HIH6130_ADDR);
puts("[OK]");
while (1) {
float hum = 0.f;
float temp = 0.f;
int status;
float integral = 0.f;
float fractional;
vtimer_usleep(SLEEP);
status = hih6130_get_humidity_temperature_float(&dev, &hum, &temp);
if (status < 0) {
printf("Communication error: %d\n", status);
continue;
} else if (status == 1) {
puts("Stale values");
}
/* Several platforms usually build with nano.specs, (without float printf) */
/* Split value into two integer parts for printing. */
fractional = modff(hum, &integral);
printf("humidity: %4d.%04u %%",
(int)integral, (unsigned int)abs(fractional * 10000.f));
fractional = modff(temp, &integral);
printf(" temperature: %4d.%04u C\n",
(int)integral, (unsigned int)abs(fractional * 10000.f));
}
return 0;
}