-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/shtc1: Initial support for the SHTC1 temperature and humidity sensor #7866
Changes from 13 commits
3111bbe
448e2a0
8aa22ba
aef067f
6a7303e
7ca0828
c4176e6
ac94832
f0b479a
9dabe3a
c7db4bf
60f548e
f04d8f9
090d720
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/* | ||
* Copyright 2017, RWTH Aachen. All rights reserved. | ||
* | ||
* 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 drivers_shtc1 | ||
* @ingroup drivers_sensors | ||
* @name Device driver interface for the SHTC1 Temperature and humidity sensor | ||
* @{ | ||
* | ||
* @file | ||
* @brief Device driver interface for the SHTC1 Temperature and humidity sensor | ||
* | ||
* @author Steffen Robertz <[email protected]> | ||
* @author Josua Arndt <[email protected]> | ||
*/ | ||
|
||
#ifndef SHTC1_H | ||
#define SHTC1_H | ||
|
||
#include <stdint.h> | ||
#include "periph/i2c.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef enum { | ||
CRC_DISABLED = 0, | ||
CRC_ENABLED | ||
} shtc1_crc_type_t; | ||
|
||
/** | ||
* @brief value struct, where all results obtained from the sensor will be saved. | ||
* @{ | ||
*/ | ||
typedef struct { | ||
float temp; /**< Temperature after an according call to the measurement function. */ | ||
float rel_humidity; /**< Relative humidity after an according call to the measuerment funtion. */ | ||
unsigned int id; /**< ID read from the sensor, only available after shtc1_id() was called. */ | ||
} shtc1_values_t; | ||
/** @} */ | ||
|
||
/** | ||
* @brief settings struct with all relevant parameters | ||
* @{ | ||
*/ | ||
typedef struct { | ||
i2c_t bus; /**< I2C bus descriptor. */ | ||
uint8_t addr; /**< I2C address of the sensor. */ | ||
shtc1_crc_type_t crc; /**< crc check enabled or disabled (CRC_ENABLED/CRC_DISABLED). */ | ||
} shtc1_params_t; | ||
/** @} */ | ||
|
||
/** | ||
* @brief device descriptor for the SHTC1 | ||
* @{ | ||
*/ | ||
typedef struct { | ||
shtc1_values_t values; /**< Values struct, where all read data will be stored. */ | ||
shtc1_params_t params; /**< Paramteres struct with all settings set. */ | ||
} shtc1_t; | ||
/** @} */ | ||
|
||
enum { | ||
SHTC1_OK = 0, | ||
SHTC1_ERROR = -1 | ||
}; | ||
|
||
/** | ||
* @brief Initializes the sensor and I2C. | ||
* | ||
* @param[in] dev I2C device descriptor. | ||
* @param[in] params SHTC1 parameters to be used. | ||
* | ||
* @return SHTC1_OK on a working initialization. | ||
* @return SHTC1_ERROR on error. | ||
*/ | ||
int8_t shtc1_init(shtc1_t* const dev, const shtc1_params_t* params); | ||
|
||
/** | ||
* @brief Reads temperature and humidity values. | ||
* @details The values will be saved in the device descriptor (values struct). | ||
* The temperature is in °C and the humidity in %. | ||
* | ||
* @param[in] dev The I2C device descriptor. | ||
* | ||
* @return SHTC1_OK if a measurement completed. The values will be stored | ||
* in the values struct. Temperature in °C and humidity in %. | ||
* @return SHTC1_ERROR on checksum error. | ||
*/ | ||
int8_t shtc1_measure(shtc1_t* const dev); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be nice to have a function that directly returns the data instead of fiddling around with the device struct? Furthermore, I expected some intentions to cache sensor data when you introduced There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Just passing the struckt instead of dev, temp, hum pointer is much more convinient. IMHO. |
||
|
||
/** | ||
* @brief Reads the ID and saves it in the device descriptor | ||
* | ||
* @details When working correctly ID should equal xxxx'xxxx'xx00'0111 where x is unspecified. | ||
* | ||
* @param[in] dev The I2C device descriptor. | ||
* | ||
* @return SHTC1_OK on everything done. | ||
* @return SHTC1_ERROR on error. | ||
*/ | ||
int8_t shtc1_id(shtc1_t* const dev); | ||
|
||
/** | ||
* @brief Resets sensor | ||
* | ||
* This will reset all internal state machines and reload calibration data from the memory. | ||
* | ||
* @param[in] dev The I2C device descriptor. | ||
* | ||
* @return SHTC1_OK on everything done. | ||
* @return SHTC1_ERROR on error. | ||
*/ | ||
int8_t shtc1_reset(const shtc1_t* const dev); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* SHTC1_H */ | ||
/** @} */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include $(RIOTBASE)/Makefile.base |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright 2017, RWTH Aachen. All rights reserved. | ||
* | ||
* 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 drivers_shtc1 | ||
* @name Default parameters for the SHTC1 Temperature and humidity sensor | ||
* @{ | ||
* | ||
* @file | ||
* @brief Default parameters for the SHTC1 Temperature and humidity sensor | ||
* | ||
* @author Steffen Robertz <[email protected]> | ||
* @author Josua Arndt <[email protected]> | ||
*/ | ||
|
||
#ifndef SHTC1_PARAMS_H | ||
#define SHTC1_PARAMS_H | ||
|
||
#include "board.h" | ||
#include "shtc1.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Default configuration parameters for SHTC1 sensors | ||
* @{ | ||
*/ | ||
#ifndef SHTC1_PARAM_I2C | ||
#define SHTC1_PARAM_I2C (I2C_DEV(0)) | ||
#endif | ||
#ifndef SHTC1_PARAM_ADDR | ||
#define SHTC1_PARAM_ADDR (0x70) | ||
#endif | ||
#ifndef SHTC1_PARAM_CRC | ||
#define SHTC1_PARAM_CRC CRC_ENABLED | ||
#endif | ||
|
||
#ifndef SHTC1_PARAMS | ||
#define SHTC1_PARAMS { .bus = SHTC1_PARAM_I2C, \ | ||
.addr = SHTC1_PARAM_ADDR, \ | ||
.crc = SHTC1_PARAM_CRC } | ||
#endif | ||
/** @} */ | ||
|
||
/** | ||
* @brief Allocation of SHTC1 configuration | ||
*/ | ||
static const shtc1_params_t shtc1_params[] = { | ||
#ifdef SHTC1_PARAMS_BOARD | ||
SHTC1_PARAMS_BOARD | ||
#else | ||
SHTC1_PARAMS | ||
#endif | ||
}; | ||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* SHTC1_PARAMS_H */ | ||
/** @} */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright 2017, RWTH Aachen. All rights reserved. | ||
* | ||
* 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 drivers_shtc1 | ||
* @name Register definition for the SHTC1 Temperature and humidity sensor | ||
* @{ | ||
* | ||
* @file | ||
* @brief Register definition for the SHTC1 Temperature and humidity sensor | ||
* | ||
* @author Steffen Robertz <[email protected]> | ||
* @author Josua Arndt <[email protected]> | ||
*/ | ||
|
||
#ifndef SHTC1_REGS_H | ||
#define SHTC1_REGS_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define SHTC1_CRC (0x31) /* crc polynomial */ | ||
#define SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_HIGH (0x7C) | ||
#define SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_LOW (0xA2) | ||
#define SHTC1_COMMAND_RESET_HIGH (0x80) | ||
#define SHTC1_COMMAND_RESET_LOW (0x5D) | ||
#define SHTC1_COMMAND_ID_HIGH (0xEF) | ||
#define SHTC1_COMMAND_ID_LOW (0xC8) | ||
#define SHTC1_ID (0x07) /* ID Mask */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* SHTC1_REGS_H */ | ||
/** @} */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* Copyright 2017, RWTH-Aachen, Steffen Robertz, Josua Arndt | ||
* | ||
* 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. | ||
*/ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add doxygen header and author field in the following form:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Obviously this belongs to the group you defined above. |
||
/** | ||
* @ingroup drivers_shtc1 | ||
* @{ | ||
* | ||
* @file | ||
* @brief Device driver implementation for the Sensirion SHTC1 temperature and humidity sensor | ||
* | ||
* @author Steffen Robertz <[email protected]> | ||
* @author Josua Arndt <[email protected]> | ||
* @} | ||
*/ | ||
|
||
#include "shtc1.h" | ||
#include "shtc1_regs.h" | ||
#define ENABLE_DEBUG (0) | ||
#include "debug.h" | ||
#include "assert.h" | ||
|
||
|
||
/* | ||
* does a crc check and returns 0 for passed and -1 for failed | ||
* 2 bytes will be checked for the checksum, rec_value is pointer | ||
* to first value | ||
*/ | ||
static int8_t _check_crc(uint8_t *rec_values, uint8_t right_crc) | ||
{ | ||
uint8_t crc = 0xFF; | ||
uint8_t current_byte; | ||
uint8_t bit; | ||
|
||
for (current_byte = 0; current_byte < 2; current_byte++) { | ||
crc ^= (rec_values[current_byte]); | ||
for (bit = 8; bit > 0; bit--) { | ||
if (crc & 0x80) { | ||
crc = (crc << 1) ^ SHTC1_CRC; | ||
} | ||
else { | ||
crc = (crc << 1); | ||
} | ||
} | ||
} | ||
return !(crc == right_crc); | ||
} | ||
|
||
int8_t shtc1_init(shtc1_t *const dev, const shtc1_params_t *params) | ||
{ | ||
/* check for a valid device descriptor and parameters */ | ||
assert(dev && params); | ||
/* copy settings into the device descriptor */ | ||
dev->params = *params; | ||
/* Verify the connection by reading the SHTC1's ID and checking its value */ | ||
if (shtc1_id(dev) != SHTC1_OK || ((dev->values.id & 0x3F) != SHTC1_ID)) { | ||
return SHTC1_ERROR; | ||
} | ||
return SHTC1_OK; | ||
} | ||
|
||
int8_t shtc1_measure(shtc1_t *const dev) | ||
{ | ||
/* Build and issue the measurement command */ | ||
uint8_t cmd[] = { SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_HIGH, SHTC1_MEASURE_CLOCK_STRETCHING_TEMP_LOW }; | ||
|
||
i2c_acquire(dev->params.bus); | ||
if (i2c_write_bytes(dev->params.bus, dev->params.addr, cmd, 2, 0)) { | ||
return SHTC1_ERROR; | ||
} | ||
/* Receive the measurement */ | ||
/* 16 bit Temperature | ||
* 8 bit CRC temp | ||
* 16 Bit Absolute Humidity | ||
* 8 bit CRC Hum | ||
*/ | ||
uint8_t received[6]; | ||
if(i2c_read_bytes(dev->params.bus, dev->params.addr, received, 6, 0)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe spend a comment about the format (upper 8bit, lower 8bit, crc) |
||
return SHTC1_ERROR; | ||
} | ||
i2c_release(dev->params.bus); | ||
/* get 16bit values and check crc */ | ||
uint16_t temp_f = ((received[0] << 8) | received[1]); | ||
uint16_t abs_humidity = ((received[3] << 8) | received[4]); | ||
if (dev->params.crc) { | ||
if (!((_check_crc(&received[0], received[2]) == 0) && (_check_crc(&received[3], received[5]) == 0))) { | ||
/* crc check failed */ | ||
DEBUG("CRC Error"); | ||
return SHTC1_ERROR; | ||
} | ||
DEBUG("CRC Passed! \n"); | ||
} | ||
/* calculate the relative humidity and convert the temperature to °C */ | ||
dev->values.temp = (175.0 * temp_f / 65536) - 45; | ||
dev->values.rel_humidity = 100 * (abs_humidity / 65536.0); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually we abstain from extra divisions and normalization operations to represent a value in persent or something. Do you think we can simplify here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe that a conversion of the temperature to °C is neccessary. The raw values does not hold a lot of information to a user. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
return SHTC1_OK; | ||
} | ||
|
||
int8_t shtc1_id(shtc1_t *const dev) | ||
{ | ||
/* Build and send measurement command */ | ||
uint8_t data[] = { SHTC1_COMMAND_ID_HIGH, SHTC1_COMMAND_ID_LOW }; | ||
int8_t check = 0; | ||
|
||
i2c_acquire(dev->params.bus); | ||
check = i2c_write_bytes(dev->params.bus, dev->params.addr, data, 2, 0); | ||
/* receive ID and check if the send and receive commands were successfull */ | ||
check += i2c_read_bytes(dev->params.bus, dev->params.addr, data, 2, 0); | ||
i2c_release(dev->params.bus); | ||
if (check != 0) { | ||
/* error occured */ | ||
return SHTC1_ERROR; | ||
} | ||
/* Save ID in device descriptor */ | ||
dev->values.id = (data[0] << 8) | data[1]; | ||
return SHTC1_OK; | ||
} | ||
|
||
int8_t shtc1_reset(const shtc1_t *const dev) | ||
{ | ||
/* Build and issue the reset command */ | ||
uint8_t data[] = { SHTC1_COMMAND_RESET_HIGH, SHTC1_COMMAND_RESET_LOW }; | ||
|
||
i2c_acquire(dev->params.bus); | ||
if (i2c_write_bytes(dev->params.bus, dev->params.addr, data, 2, 0)) { | ||
i2c_release(dev->params.bus); | ||
return SHTC1_ERROR; | ||
} | ||
i2c_release(dev->params.bus); | ||
return SHTC1_OK; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
APPLICATION = driver_shtc1 | ||
include ../Makefile.tests_common | ||
|
||
FEATURES_REQUIRED = periph_i2c | ||
|
||
USEMODULE += shtc1 | ||
USEMODULE += xtimer | ||
|
||
include $(RIOTBASE)/Makefile.include |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reduce line width of the doc