Digital humidity sensor with temperature output
Revision 2:ad5e3555c7ef, committed 2017-09-05
- Comitter:
- mcm
- Date:
- Tue Sep 05 13:18:23 2017 +0000
- Parent:
- 1:da1f21719567
- Commit message:
- The library was completed and tested, it works as expected.
Changed in this revision
HTU21D.cpp | Show annotated file Show diff for this revision Revisions of this file |
HTU21D.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/HTU21D.cpp Thu Aug 31 20:28:28 2017 +0000 +++ b/HTU21D.cpp Tue Sep 05 13:18:23 2017 +0000 @@ -0,0 +1,464 @@ +/** + * @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; +}
--- a/HTU21D.h Thu Aug 31 20:28:28 2017 +0000 +++ b/HTU21D.h Tue Sep 05 13:18:23 2017 +0000 @@ -25,7 +25,7 @@ #include "mbed.h" #include "HTU21D.h" -HTU21D myBarometricSensor ( I2C_SDA, I2C_SCL, HTU21D::HTU21D_ADDRESS, 400000 ); +HTU21D myTempRXSensor ( I2C_SDA, I2C_SCL, HTU21D::HTU21D_ADDRESS, 400000 ); Serial pc ( USBTX, USBRX ); // tx, rx @@ -33,46 +33,37 @@ DigitalOut myled(LED1); -HTU21D::Vector_cal_coeff_t myCalCoeff; -HTU21D::Vector_temp_f myUT; -HTU21D::Vector_pressure_f myUP; -HTU21D::Vector_compensated_data_f myTrueData; +HTU21D::Vector_temperature_f myTemperature; +HTU21D::Vector_humidity_f myHumidity; -uint32_t myState = 0; + void sendDATA ( void ) { - switch ( myState ) { - case 0: - // Trigger a new temperature measurement - myBarometricSensor.HTU21D_TriggerTemperature (); - myState = 1; - break; - - case 1: - // Read the uncompensated temperature data and trigger a new pressure measurement - myBarometricSensor.HTU21D_ReadRawTemperature ( &myUT ); - myBarometricSensor.HTU21D_TriggerPressure ( HTU21D::PRESSURE_STANDARD_MODE ); - myState = 2; - break; - - case 2: - // Read the uncompensated pressure data, calculate the compensated temperature and pressure and send it through the UART - myled = 1; - myBarometricSensor.HTU21D_ReadRawPressure ( &myUP ); - - myTrueData = myBarometricSensor.HTU21D_CalculateCompensated_Temperature_Pressure ( myCalCoeff, myUT, myUP, HTU21D::PRESSURE_STANDARD_MODE ); - - pc.printf( "Temperature: %0.1f\nPressure: %ld\r\n", ( float )myTrueData.Temperature/10, myTrueData.Pressure ); - myled = 0; - myState = 0; - break; - - default: - myState = 0; - break; - } - + HTU21D::HTU21D_user_register_status_t myBatteryStatus; + + myled = 1; + + // Get Temperature + myTempRXSensor.HTU21D_TriggerTemperature (); + myTempRXSensor.HTU21D_ReadTemperature ( &myTemperature ); + + // Get Humidity + myTempRXSensor.HTU21D_TriggerHumidity (); + myTempRXSensor.HTU21D_ReadHumidity ( &myHumidity ); + + // Get Battery Status + myTempRXSensor.HTU21D_BatteryStatus ( &myBatteryStatus ); + + // Send data through the UART + pc.printf( "\nTemperature: %0.01f\nHumidity: %0.01f\n", myTemperature.Temperature, myHumidity.Humidity ); + + if ( myBatteryStatus == HTU21D::STATUS_END_BATTERY_HIGH_2V25 ) + pc.printf( "Battery status higher than 2.25V\r\n" ); + else + pc.printf( "Battery status lower than 2.25V\r\n" ); + + myled = 0; } @@ -80,12 +71,8 @@ { pc.baud ( 115200 ); - myBarometricSensor.HTU21D_GetCalibrationCoefficients ( &myCalCoeff ); - - // Print the calibration coefficients - pc.printf( "AC1: %ld\nAC2: %ld\nAC3: %ld\nAC4: %ld\nAC5: %ld\nAC6: %ld\nB1: %ld\nB2: %ld\nMB: %ld\nMC: %ld\nMD: %ld\r\n", - myCalCoeff.AC1, myCalCoeff.AC2, myCalCoeff.AC3, myCalCoeff.AC4, myCalCoeff.AC5, myCalCoeff.AC6, myCalCoeff.B1, - myCalCoeff.B2, myCalCoeff.MB, myCalCoeff.MC, myCalCoeff.MD ); + myTempRXSensor.HTU21D_SoftReset (); + myTempRXSensor.HTU21D_Init ( HTU21D::MODE_NO_HOLD_MASTER, HTU21D::RESOLUTION_12RH_14TEMP, HTU21D::HEATER_DISABLED ); serial.attach( &sendDATA, 1 ); // the address of the function to be attached ( sendDATA ) and the interval ( 1s ) @@ -175,11 +162,11 @@ #ifndef VECTOR_STRUCT_H #define VECTOR_STRUCT_H typedef struct { - uint8_t RawTemperature[3]; + char RawTemperature[3]; } Vector_raw_temperature_t; typedef struct { - uint8_t RawHumidity[3]; + char RawHumidity[3]; } Vector_raw_humidity_t; typedef struct { @@ -219,7 +206,7 @@ /** It configures the device. */ - HTU21D_status_t HTU21D_Init ( HTU21D_master_mode_t myMode, HTU21D_user_register_resolution_t myResolution, HTU21D_user_register_otp_t myHeater ); + HTU21D_status_t HTU21D_Init ( HTU21D_master_mode_t myMode, HTU21D_user_register_resolution_t myResolution, HTU21D_user_register_heater_t myHeater ); /** It resets the device by software. */