Digital humidity sensor with temperature output

HTU21D.cpp

Committer:
mcm
Date:
2017-09-05
Revision:
2:ad5e3555c7ef
Parent:
0:d15aa997f9c1

File content as of revision 2:ad5e3555c7ef:

/**
 * @brief       HTU21D.c
 * @details     Digital humidity sensor with temperature output.
 *              Functions file.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        4/September/2017
 * @version     4/September/2017    The ORIGIN
 * @pre         NaN.
 * @warning     NaN
 * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
 */

#include "HTU21D.h"


HTU21D::HTU21D ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
    : i2c          ( sda, scl )
    , HTU21D_Addr  ( addr )
{
    i2c.frequency( freq );
}


HTU21D::~HTU21D()
{
}



/**
 * @brief       HTU21D_Init   ( HTU21D_master_mode_t , HTU21D_user_register_resolution_t , HTU21D_user_register_otp_t )
 *
 * @details     It initializes the device.
 *
 * @param[in]    myMode:        Hold/No Hold master mode.
 * @param[in]    myResolution:  Resolution of the sensor.
 * @param[in]    myHeater:      Heater enabled or disabled.
 *
 * @param[out]   NaN.
 *
 *
 * @return       Status of HTU21D_Init.
 *
 *
 * @author      Manuel Caballero
 * @date        4/September/2017
 * @version     4/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     NaN.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_Init    ( HTU21D_master_mode_t myMode, HTU21D_user_register_resolution_t myResolution, HTU21D_user_register_heater_t myHeater )
{
    char        cmd[]             =   { HTU21D_READ_REGISTER, 0 };
    uint32_t    aux               =    0;


    HTU21D_Mode         =   myMode;
    HTU21D_Resolution   =   myResolution;


    // Reserved bits must not be changed. Therefore, for any writing to user register, default values of reserved bits must be read first
    // Datasheet: User register p.13.
    aux = i2c.write ( HTU21D_Addr, &cmd[0], 1 );
    aux = i2c.read  ( HTU21D_Addr, &cmd[0], 1 );


    cmd[0]          &=   0x38;          // Mask reserved bits

    // On-chip heater
    if ( myHeater == HEATER_ENABLED )
        cmd[0]   |=  0x04;              

    // Resolution
    switch ( HTU21D_Resolution ) {
        default:
        case RESOLUTION_12RH_14TEMP:
            cmd[0]   &=  0x7E;          
            break;

        case RESOLUTION_8RH_12TEMP:
            cmd[0]   |=  0x01;          
            break;

        case RESOLUTION_10RH_13TEMP:
            cmd[0]   |=  0x80;          
            break;

        case RESOLUTION_11RH_11TEMP:
            cmd[0]   |=  0x81;          
            break;
    }


    cmd[1]           =    ( cmd[0] | 0x02 );            //  OTP reload disabled
    cmd[0]           =    HTU21D_WRITE_REGISTER;

    aux = i2c.write  ( HTU21D_Addr, &cmd[0], 2 );



    if ( aux == I2C_SUCCESS )
        return   HTU21D_SUCCESS;
    else
        return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_SoftReset   ( void )
 * @details     Rebooting the HTU21D sensor switching the power off and on again.
 *
 * @param[in]    NaN.
 *
 * @param[out]   Status of HTU21D_SoftReset.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     The soft reset takes less than 15ms.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_SoftReset   ( void )
{
    char        cmd                 =    HTU21D_SOFT_RESET;
    uint32_t    aux                 =    0;

    
    aux = i2c.write  ( HTU21D_Addr, &cmd, 1 );
    wait ( 0.015 );
    

    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



 /**
 * @brief       HTU21D_TriggerTemperature   ( void )
 * @details     Trigger a new temperature measurement.
 *
 * @param[in]    NaN.
 *
 * @param[out]   Status of HTU21D_TriggerTemperature.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     The measuring time depends on the chosen resolution.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_TriggerTemperature    ( void )
{
    char        cmd                 =    0;
    uint32_t    aux                 =    0;
    float       myDelay             =    0;
    
    
    // Check if the event is by Hold Master Mode
    if ( HTU21D_Mode == MODE_HOLD_MASTER )
        cmd   =   HTU21D_TRIGGER_TEMPERATURE_MEASUREMENT_HOLD_MASTER;
    else
        cmd   =   HTU21D_TRIGGER_TEMPERATURE_MEASUREMENT_NO_HOLD_MASTER;
    
    
    aux = i2c.write  ( HTU21D_Addr, &cmd, 1 );
    
    // Measuring time
    switch ( HTU21D_Resolution ){
        default:
        case RESOLUTION_12RH_14TEMP:
            myDelay  =  0.05;          
            break;

        case RESOLUTION_8RH_12TEMP:
            myDelay  =  0.013;          
            break;

        case RESOLUTION_10RH_13TEMP:
            myDelay  =  0.025;          
            break;

        case RESOLUTION_11RH_11TEMP:
            myDelay  =  0.007;          
            break;
    }
    
    wait ( myDelay );


    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_ReadTemperature   ( Vector_temperature_f* )
 * @details     Read a new temperature measurement.
 *
 * @param[in]    mytemperature:  Variable to store the temperature.
 *
 * @param[out]   Status of HTU21D_ReadTemperature.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     HTU21D_TriggerTemperature MUST be called before.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_ReadTemperature    ( Vector_temperature_f* mytemperature )
{
    char        aux                 =    0;
    char        myRawTemp[]         =   { 0, 0, 0};

    
    aux = i2c.read  ( HTU21D_Addr, &myRawTemp[0], 3 );


    mytemperature->Temperature    =   ( myRawTemp[0] << 8 ) | myRawTemp[1];
    mytemperature->Temperature   /=   65536.0;
    mytemperature->Temperature   *=   175.72;
    mytemperature->Temperature   -=   46.85;



    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_ReadRawTemperature   ( Vector_raw_temperature_t* )
 * @details     Read a new raw temperature measurement.
 *
 * @param[in]    myRawtemperature:  Variable to store the temperature.
 *
 * @param[out]   Status of HTU21D_ReadTemperature.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     HTU21D_TriggerTemperature MUST be called before.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_ReadRawTemperature    ( Vector_raw_temperature_t* myRawtemperature )
{
    uint32_t    aux                 =    0;

    
    aux = i2c.read  ( HTU21D_Addr, &myRawtemperature->RawTemperature[0], 3 );


    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}


/**
 * @brief       HTU21D_TriggerHumidity   ( void  )
 * @details     Trigger a new humidity measurement.
 *
 * @param[in]    NaN.
 *
 * @param[out]   Status of HTU21D_TriggerHumidity.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     The measuring time depends on the chosen resolution.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_TriggerHumidity    ( void )
{
    char        cmd                 =    0;
    uint32_t    aux                 =    0;
    float       myDelay             =    0;
    
    
    // Check if the event is by Hold Master Mode
    if ( HTU21D_Mode == MODE_HOLD_MASTER )
        cmd   =   HTU21D_TRIGGER_HUMIDITY_MEASUREMENT_HOLD_MASTER;
    else
        cmd   =   HTU21D_TRIGGER_HUMIDITY_MEASUREMENT_NO_HOLD_MASTER;
    
    
    aux = i2c.write  ( HTU21D_Addr, &cmd, 1 );
    
    // Measuring time
    switch ( HTU21D_Resolution ){
        default:
        case RESOLUTION_12RH_14TEMP:
            myDelay  =  0.05;          
            break;

        case RESOLUTION_8RH_12TEMP:
            myDelay  =  0.013;          
            break;

        case RESOLUTION_10RH_13TEMP:
            myDelay  =  0.025;          
            break;

        case RESOLUTION_11RH_11TEMP:
            myDelay  =  0.007;          
            break;
    }
    
    wait ( myDelay );


    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_ReadHumidity   ( Vector_humidity_f* )
 * @details     Read a new humidity measurement.
 *
 * @param[in]    myhumidity:    Variable to store the humidity.
 *
 * @param[out]   Status of HTU21D_ReadHumidity.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     HTU21D_TriggerHumidity MUST be called before.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_ReadHumidity    ( Vector_humidity_f* myhumidity )
{
    uint32_t    aux                 =    0;
    char        myRawRH[]           =    { 0, 0, 0};

    
    aux = i2c.read  ( HTU21D_Addr, &myRawRH[0], 3 );


    myhumidity->Humidity    =   ( myRawRH[0] << 8 ) | myRawRH[1];
    myhumidity->Humidity   /=   65536.0;
    myhumidity->Humidity   *=   125.0;
    myhumidity->Humidity   -=   6.0;



    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_ReadRawHumidity   ( Vector_raw_humidity_t* )
 * @details     Read a new raw humidity measurement.
 *
 * @param[in]    myRawhumidity:    Variable to store the raw humidity.
 *
 * @param[out]   Status of HTU21D_ReadHumidity.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     The measuring time depends on the chosen resolution.
 * @warning     HTU21D_TriggerHumidity MUST be called before.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_ReadRawHumidity    ( Vector_raw_humidity_t* myRawhumidity )
{
    uint32_t    aux                 =    0;

    
    aux = i2c.read  ( HTU21D_Addr, &myRawhumidity->RawHumidity[0], 3 );



    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}



/**
 * @brief       HTU21D_BatteryStatus   ( HTU21D_user_register_status_t* )
 * @details     Read the user register to check the battery status.
 *
 * @param[in]    battStatus:    Variable to store the battery status.
 *
 * @param[out]   Status of HTU21D_BatteryStatus.
 *
 *
 * @return      NA
 *
 * @author      Manuel Caballero
 * @date        5/September/2017
 * @version     5/September/2017   The ORIGIN
 * @pre         NaN
 * @warning     NaN.
 */
HTU21D::HTU21D_status_t  HTU21D::HTU21D_BatteryStatus      ( HTU21D_user_register_status_t* battStatus )
{
    char        cmd                 =    HTU21D_READ_REGISTER;
    uint32_t    aux                 =    0;

    
    aux = i2c.write ( HTU21D_Addr, &cmd, 1 );
    aux = i2c.read  ( HTU21D_Addr, &cmd, 1 );
    
    
    cmd         &=   0x40;          // Mask 'Status: End of Batter' bit
    
    if ( cmd == 0x40 )
        *battStatus  =   STATUS_END_BATTERY_LOW_2V25;
    else
        *battStatus  =   STATUS_END_BATTERY_HIGH_2V25;


    if ( aux == HTU21D_SUCCESS )
       return   HTU21D_SUCCESS;
    else
       return   HTU21D_FAILURE;
}