Digital Humidity Sensor SHT2x (RH/T)

SHT2X.cpp

Committer:
mcm
Date:
2018-09-04
Revision:
2:5893455b8c6c
Parent:
1:9f1fcd1e4c9c

File content as of revision 2:5893455b8c6c:

/**
 * @brief       SHT2X.cpp
 * @details     Humidity and Temperature Sensor IC.
 *              Functions file.
 *
 *
 * @return      N/A
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018    The ORIGIN
 * @pre         N/A
 * @warning     N/A
 * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
 */

#include "SHT2X.h"


SHT2X::SHT2X ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
    : _i2c         ( sda, scl )
    , _SHT2X_Addr  ( addr )
{
    _i2c.frequency( freq );
}


SHT2X::~SHT2X()
{
}



/**
 * @brief       SHT2X_Conf    ( SHT2X_measurement_resolution_t , SHT2X_on_chip_heater_t )
 * @details     It configures the SHT2X device.
 *
 * @param[in]    myResolution:      SHT2X Resolution.
 * @param[in]    myHeater:          SHT2X Heater EN/Abled or Disabled.
 *
 * @param[out]   N/A
 *
 *
 * @return      Status of SHT2X_Init.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018    The ORIGIN
 * @pre         N/A
 * @warning     N/A.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_Conf    ( SHT2X_measurement_resolution_t myResolution, SHT2X_on_chip_heater_t myHeater )
{
    char     cmd[]   =    { SHT2X_READ_USER_REGISTER, 0 };
    uint32_t aux;


    /*
        Reserved bits must not be changed. Therefore, for any writing to user register, default values of reserved bits must be read first
        Datasheet: 5.6. User register p.19/14.
    */
    aux = _i2c.write ( _SHT2X_Addr, &cmd[0], 1U, true );
    aux = _i2c.read  ( _SHT2X_Addr, &cmd[1], 1U );

    cmd[1]  &=  ~( USER_REGISTER_RESOLUTION_MASK | USER_REGISTER_STATUS_END_BATTERY_MASK | USER_REGISTER_HEATER_MASK | USER_REGISTER_OTP_MASK );
    cmd[1]  |=   ( myResolution | myHeater | USER_REGISTER_OTP_DISABLED );
    cmd[0]   =   SHT2X_WRITE_USER_REGISTER;

    aux = _i2c.write  ( _SHT2X_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}



/**
* @brief       SHT2X_SoftReset   ( void )
* @details     Rebooting the SHT2X sensor switching the power off and on again.
*
* @param[in]    N/A.
*
* @param[out]   N/A
*
*
* @return      Status of SHT2X_SoftReset.
*
* @author      Manuel Caballero
* @date        3/September/2018
* @version     3/September/2018        The ORIGIN
* @pre         N/A
* @warning     The soft reset takes less than 15ms. The user MUST take this into account.
*/
SHT2X::SHT2X_status_t  SHT2X::SHT2X_SoftReset   ( void )
{
    char     cmd   =   SHT2X_SOFT_RESET;
    uint32_t aux;


    aux = _i2c.write ( _SHT2X_Addr, &cmd, 1U, false );


    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}


/**
* @brief       SHT2X_TriggerTemperature   ( SHT2X_master_mode_t )
* @details     It triggers a new temperature measurement.
*
* @param[in]    myMode:            Hold/No Hold mode.
*
* @param[out]   N/A
*
*
* @return      Status of SHT2X_TriggerTemperature.
*
* @author      Manuel Caballero
* @date        3/September/2018
* @version     3/September/2018        The ORIGIN
* @pre         N/A
* @warning     The user MUST respect the total conversion time.
*              14-bit temperature: 66ms ( 85ms max )
*              13-bit temperature: 33ms ( 43ms max )
*              12-bit temperature: 17ms ( 22ms max )
*              11-bit temperature:  9ms (  11ms max )
*/
SHT2X::SHT2X_status_t  SHT2X::SHT2X_TriggerTemperature    ( SHT2X_master_mode_t myMode )
{
    char     cmd        =    0;
    bool     myI2C_stop =    false;
    uint32_t aux;


    /* Check the mode if it is HOLD MASTER MODE, if so, not to generate a stop bit    */
    if ( myMode == SHT2X_HOLD_MASTER_MODE ) {
        cmd         =    SHT2X_TRIGGER_TEMPERATURE_MEASUREMENT_HOLD_MASTER;
        myI2C_stop  =    true;
    } else {
        cmd         =    SHT2X_TRIGGER_TEMPERATURE_MEASUREMENT_NO_HOLD_MASTER;
        myI2C_stop  =    false;
    }


    aux = _i2c.write ( _SHT2X_Addr, &cmd, 1U, myI2C_stop );


    /* NOTE: The user has to respect the total conversion time!  */




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}


/**
* @brief       SHT2X_ReadTemperature   ( SHT2X_vector_data_t* )
* @details     It reads a new temperature measurement.
*
* @param[in]    N/A
*
* @param[out]   myTemperature:     Variable to store the temperature.
*
*
* @return      Status of SHT2X_ReadTemperature.
*
* @author      Manuel Caballero
* @date        3/September/2018
* @version     3/September/2018        The ORIGIN
* @pre         CRC is NOT taken into account.
* @warning     The measuring time depends on the chosen resolution. The user MUST take this into account.
* @warning     SHT2X_TriggerTemperature MUST be call before.
*/
SHT2X::SHT2X_status_t  SHT2X::SHT2X_ReadTemperature    ( SHT2X_vector_data_t* myTemperature )
{
    char     cmd[]     =   { 0, 0, 0 };
    uint32_t aux;


    /* Read the temperature  */
    aux = _i2c.read ( _SHT2X_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );

    /* Parse the data   */
    myTemperature->Temperature     =   ( ( cmd[0] << 8U ) | cmd[1] );
    myTemperature->Temperature    /=   65536.0f;
    myTemperature->Temperature    *=   175.72f;
    myTemperature->Temperature    -=   46.85f;



    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}



/**
 * @brief       SHT2X_ReadRawTemperature   ( SHT2X_vector_data_t* )
 * @details     It reads a new raw temperature measurement.
 *
 * @param[in]    N/A
 *
 * @param[out]   myRawTemperature:  Variable to store the temperature.
 *
 *
 * @return      Status of SHT2X_ReadTemperature.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018       The ORIGIN
 * @pre         CRC is NOT taken into account.
 * @warning     The measuring time depends on the chosen resolution. The user MUST take this into account.
 * @warning     No Hold Master is ONLY implemented.
 * @warning     SHT2X_TriggerTemperature MUST be call before.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_ReadRawTemperature    ( SHT2X_vector_data_t* myRawTemperature )
{
    char     cmd[]         =   { 0, 0, 0 };
    uint32_t aux;


    /* Read the temperature  */
    aux = _i2c.read ( _SHT2X_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );

    /* Parse the data   */
    myRawTemperature->RawTemperature    =   ( ( cmd[0] << 8U ) | cmd[1] );




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}


/**
* @brief       SHT2X_TriggerHumidity   ( SHT2X_master_mode_t )
* @details     It triggers a new humidity measurement.
*
* @param[in]    myMode:            Hold/No Hold mode.
*
* @param[out]   N/A
*
*
* @return      Status of SHT2X_TriggerHumidity.
*
* @author      Manuel Caballero
* @date        3/September/2018
* @version     3/September/2018        The ORIGIN
* @pre         N/A
* @warning     The user MUST respect the total conversion time.
*              12-bit RH: 22ms   ( 29ms max )
*              11-bit RH: 12ms   ( 15ms max )
*              10-bit RH:  7ms   (  9ms max )
*               8-bit RH:  3ms   (  4ms max )
*/
SHT2X::SHT2X_status_t  SHT2X::SHT2X_TriggerHumidity    ( SHT2X_master_mode_t myMode )
{
    char     cmd        =    0;
    bool     myI2C_stop =    false;
    uint32_t aux;


    /* Check the mode if it is HOLD MASTER MODE, then not generate a stop bit    */
    if ( myMode == SHT2X_HOLD_MASTER_MODE ) {
        cmd         =    SHT2X_TRIGGER_HUMIDITY_MEASUREMENT_HOLD_MASTER;
        myI2C_stop  =    true;
    } else {
        cmd         =    SHT2X_TRIGGER_HUMIDITY_MEASUREMENT_NO_HOLD_MASTER;
        myI2C_stop  =    false;
    }


    aux = _i2c.write ( _SHT2X_Addr, &cmd, 1U, myI2C_stop );


    /* NOTE: The user has to respect the total conversion time!  */


    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}


/**
 * @brief       SHT2X_ReadHumidity   ( SHT2X_vector_data_t* )
 * @details     It reads a new humidity measurement.
 *
 * @param[in]    N/A
 *
 * @param[out]   myHumidity:        Variable to store the humidity.
 *
 *
 * @return      Status of SHT2X_ReadHumidity.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018        The ORIGIN
 * @pre         CRC is NOT taken into account.
 * @warning     The measuring time depends on the chosen resolution. The user MUST take this into account.
 * @warning     SHT2X_TriggerHumidity MUST be call before.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_ReadHumidity    ( SHT2X_vector_data_t* myHumidity )
{
    char     cmd[]   =    { 0, 0, 0 };
    uint32_t aux;


    /* Read the relative humidity  */
    aux = _i2c.read ( _SHT2X_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ) );

    /* Parse the data   */
    myHumidity->RelativeHumidity    =   ( ( cmd[0] << 8U ) | cmd[1] );
    myHumidity->RelativeHumidity   /=   65536.0f;
    myHumidity->RelativeHumidity   *=   125.0f;
    myHumidity->RelativeHumidity   -=   6.0f;




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}



/**
 * @brief       SHT2X_ReadRawHumidity   ( SHT2X_vector_data_t* )
 * @details     It reads a new raw humidity measurement.
 *
 * @param[in]    mN/A
 *
 * @param[out]   myHumidity:        Variable to store the humidity.
 *
 *
 * @return      Status of SHT2X_ReadHumidity.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018       The ORIGIN
 * @pre         CRC is NOT taken into account.
 * @warning     The measuring time depends on the chosen resolution. The user MUST take this into account.
 * @warning     No Hold Master is ONLY implemented.
 * @warning     SHT2X_TriggerHumidity MUST be call before.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_ReadRawHumidity    ( SHT2X_vector_data_t* myHumidity )
{
    char     cmd[]           =    { 0, 0, 0 };
    uint32_t aux;


    /* Read the relative humidity  */
    aux = _i2c.read ( _SHT2X_Addr, &cmd[0], 3U );

    /* Parse the data   */
    myHumidity->RawRelativeHumidity    =   ( ( cmd[0] << 8U ) | cmd[1] );




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}


/**
 * @brief       SHT2X_BatteryStatus   ( SHT2X_vector_data_t* )
 * @details     It reads the user register to check the battery status.
 *
 * @param[in]    N/A
 *
 * @param[out]   myBattStatus:      Variable to store the battery status.
 *
 *
 * @return      Status of SHT2X_BatteryStatus.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018        The ORIGIN
 * @pre         CRC is NOT taken into account.
 * @warning     N/A.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_BatteryStatus      ( SHT2X_vector_data_t* myBattStatus )
{
    char     cmd     =   SHT2X_READ_USER_REGISTER;
    uint32_t aux;


    /* Get the battery status    */
    aux = _i2c.write ( _SHT2X_Addr, &cmd, 1U, true );
    aux = _i2c.read  ( _SHT2X_Addr, &cmd, 1U );

    /* Parse the data    */
    myBattStatus->BatteryStatus   =   ( cmd & USER_REGISTER_STATUS_END_BATTERY_MASK );




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}



/**
 * @brief       SHT2X_GetSerialNumber   ( SHT2X_vector_data_t* )
 * @details     It gets the serial number ( Electronic Identification Code ).
 *
 * @param[in]    N/A
 *
 * @param[out]   mySerialNumber:    Device serial number.
 *
 *
 * @return      Status of SHT2X_GetSerialNumber.
 *
 * @author      Manuel Caballero
 * @date        3/September/2018
 * @version     3/September/2018        The ORIGIN
 * @pre         Composition of Serial Number: SNA_1 | SNA_0 | SNB_3 | SNB_2 | SNB_1 | SNB_0 | SNC_1 | SNC_0
 * @pre         CRC is NOT taken into account.
 * @warning     N/A.
 */
SHT2X::SHT2X_status_t  SHT2X::SHT2X_GetSerialNumber ( SHT2X_vector_data_t* mySerialNumber )
{
    char     cmd[14]     =   { 0 };
    uint32_t aux;


    /* Serial number: first memory access    */
    cmd[0]   =   SHT2X_SERIAL_NUMBER_FIRST_MEMORY_ACCESS_MSB;
    cmd[1]   =   SHT2X_SERIAL_NUMBER_FIRST_MEMORY_ACCESS_LSB;
    aux      =   _i2c.write ( _SHT2X_Addr, &cmd[0], 2U, true );
    aux      =   _i2c.read  ( _SHT2X_Addr, &cmd[0], 8U );

    /* Serial number: second memory access    */
    cmd[8]   =   SHT2X_SERIAL_NUMBER_SECOND_MEMORY_ACCESS_MSB;
    cmd[9]   =   SHT2X_SERIAL_NUMBER_SECOND_MEMORY_ACCESS_LSB;
    aux      =   _i2c.write ( _SHT2X_Addr, &cmd[8], 2U, true );
    aux      =   _i2c.read  ( _SHT2X_Addr, &cmd[8], 6U );


    /* Parse the data    */
    mySerialNumber->SerialNumber     =   cmd[11];       // SNA_1
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[12];       // SNA_0
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[0];        // SNB_3
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[2];        // SNB_2
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[4];        // SNB_1
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[6];        // SNB_0
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[8];        // SNC_1
    mySerialNumber->SerialNumber   <<=   8U;

    mySerialNumber->SerialNumber    |=   cmd[9];        // SNC_0




    if ( aux == I2C_SUCCESS ) {
        return   SHT2X_SUCCESS;
    } else {
        return   SHT2X_FAILURE;
    }
}