This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

HDC2080: Taking more time for data ready

Part Number: HDC2080
Other Parts Discussed in Thread: HDC2010, CC2640

Hi All,

I am working on a temperature sensor with cc2642.

I am reading registers 0x00 to 0x03 at one minute of the interval, the device will be in sleep mode for the rest of the time.

I have GPIO for powering HDC2080, so after power-up, I am waiting for at least 10ms for power-up.

After power-up, I am writing to register 0x0f with 0x01 to trigger the measurement.

After triggering measurement I am waiting for 10ms(Task_sleep(100000) 10 ticks for 1micro second).

After waiting for 10ms I am reading register 0x04 for 0x80.

but some times I am getting data ready but after every 3-4 reading, I am getting data not ready(or need to wait forever).

resolution is 14 bit for temp and humidity both.

measurement is manual.

For 2-3 readings it gives proper results but some times it does not please help me to solve the problem.

My read, write functions and sequence are as below.

int8_t hdc2080_i2c_read(uint8_t *hdc2080_RxBuffer,

                                  uint8_t data_read_count)
{
    I2C_Params      i2cParams;
    I2C_Transaction i2cTransaction;
    I2C_Handle     local_hdc2080_i2c_handle;
    int_fast16_t transferOK = 0;

    I2C_init();

    i2cParams.bitRate = HDC2080_BITRATE;

    I2C_Params_init(&i2cParams);

    local_hdc2080_i2c_handle = I2C_open(HDC2080_I2C_0, &i2cParams);
    if( NULL == local_hdc2080_i2c_handle)
    {
        Display_printf(dispHandle,0, 0,"I2C Open failed");
        return HDC2080_OPEN_FAIL;
    }

    i2cTransaction.writeCount = 1;
    i2cTransaction.writeBuf = (void*)&hdc2080_RxBuffer[0];
    i2cTransaction.readBuf = (void*)&hdc2080_RxBuffer[1];
    i2cTransaction.readCount = data_read_count;

    i2cTransaction.slaveAddress = HDC2080_I2C_ADDR;

    transferOK = I2C_transferTimeout(local_hdc2080_i2c_handle, &i2cTransaction,(1000000*tickPeriodUs));
    if(transferOK)
    {
        Display_printf(dispHandle,0, 0,"Read I2C Transfer failed %d",transferOK);
        I2C_close(local_hdc2080_i2c_handle);
        return HDC2080_I2C_READ_FAIL;
    }
    else
    {
        Display_printf(dispHandle,0, 0,"Read I2C Transfer success %d",transferOK);
        I2C_close(local_hdc2080_i2c_handle);
        return HDC2080_SUCCESS;
    }
} 

int8_t hdc2080_i2c_write(uint8_t  *hdc2080_TxBuffer)
{
    I2C_Transaction i2cTransaction;
    I2C_Handle     local_hdc2080_i2c_handle;
    int_fast16_t transferOK = 0;
    I2C_Params      i2cParams;

    I2C_init();

    i2cParams.bitRate = HDC2080_BITRATE;

    I2C_Params_init(&i2cParams);

    local_hdc2080_i2c_handle = I2C_open(HDC2080_I2C_0, &i2cParams);
    if( NULL == local_hdc2080_i2c_handle)
    {
        Display_printf(dispHandle,0, 0,"I2C Open failed");
        return HDC2080_OPEN_FAIL;
    }

    Display_printf(dispHandle,0, 0,"I2C Open Success");

    i2cTransaction.writeCount = 2;
    i2cTransaction.writeBuf = (void*)hdc2080_TxBuffer;
    i2cTransaction.readBuf = NULL;
    i2cTransaction.readCount = 0;

    i2cTransaction.slaveAddress = HDC2080_I2C_ADDR;

    transferOK = I2C_transferTimeout(local_hdc2080_i2c_handle, &i2cTransaction,(1000000*tickPeriodUs));
    if(transferOK)
    {
        Display_printf(dispHandle,0, 0,"write I2C Transfer Failed %d",transferOK);
        I2C_close(local_hdc2080_i2c_handle);
        return HDC2080_I2C_WRITE_FAIL;
    }
    else
    {
        Display_printf(dispHandle,0, 0,"write I2C Transfer success %d",transferOK);
        I2C_close(local_hdc2080_i2c_handle);
        return HDC2080_SUCCESS;
    }
}


static int8_t hdc2080_start_measurement(void)
{
    uint8_t status = HDC2080_SUCCESS;
    uint8_t config_contents[2] = {0x00};
    config_contents[0] = HDC2080_MEASUREMENT_CONFIGURATION;

    status = hdc2080_i2c_read(config_contents,1);
    if(status != 0)
    {
        return HDC2080_I2C_READ_FAIL;
    }

    /*  Bit 0 of the MEASUREMENT_CONFIG register can be used to trigger
     * measurements
     */
    config_contents[1] |= 1;

    status = hdc2080_i2c_write(config_contents);
    if(status != 0)
    {
        return HDC2080_I2C_WRITE_FAIL;
    }

    return status;
}


static int8_t hdc2080_is_data_ready(void)
{

    uint8_t status = 0;
    uint8_t config_contents[2] = {0x00};
    uint32_t retry = 20;

    config_contents[0] = HDC2080_INTERRUPT_DRDY;

    while(retry)
    {
        status = hdc2080_i2c_read(config_contents,1);
        if(status != 0)
        {
            return HDC2080_READ_FAIL;
        }

        /* If register value is 0x80, means data is ready */
        if(config_contents[1] == 0x80)
        {
            /* Now ready */
#ifdef ENABLE_DEBUGGING
            Display_printf(dispHandle,0, 0,"Data ready %d",config_contents[1]);
#endif /* ENABLE_DEBUGGING */
            break;
        }

        retry--;
    }

    if(0 == retry)
    {
        Display_printf(dispHandle,0, 0,"Too Many attempts");
        return HDC2080_READ_FAIL;       
    }

    return status; 
}


int8_t hdc2080_get_sensor_data(flash_data_pkt_t *temp_sensor_data)
{
    uint8_t status = HDC2080_SUCCESS;

    hdc2080_ON();

    /* Need to confirm proper Delay */
    /* 10 ticks for 1 micro seconds -> 10000 ticks for 1 ms */
    Task_sleep(100000);

    status = hdc2080_start_measurement();
    if(status)
    {
        hdc2080_OFF();
        return HDC2080_READ_FAIL;
    }

    /* Need to wait at least ~2ms for conversion
     * to finish after measurement starts
     */

    /* Creating Minor delay, Need to check for exact delay for proper result */
    /* 5 miliseconds */
    Task_sleep(100000);

    status = hdc2080_is_data_ready();
    if(status)
    {
        hdc2080_OFF();
        return HDC2080_READ_FAIL;
    }

    status =  hdc2080_read_temperature(
                                (int8_t *)&(temp_sensor_data->temperature_dec),
                                (uint8_t *)&(temp_sensor_data->temp_fraction));
    if(status)
    {
        hdc2080_OFF();
        return HDC2080_READ_FAIL;
    }

    status = hdc2080_read_humidity((uint8_t *)&(temp_sensor_data->humidity));
    if(status)
    {
        hdc2080_OFF();
        return HDC2080_READ_FAIL;
    }

#ifdef ENABLE_DEBUGGING
    Display_printf(dispHandle,0, 0, "Temperature_dec =  %d, Temperature_frac =  %d, humidity = %d%%",
                           temp_sensor_data->temperature_dec,
                           temp_sensor_data->temp_fraction,
                           temp_sensor_data->humidity);
#endif /* ENABLE_DEBUGGING */
    hdc2080_OFF();

    return status;
}



Please let me know if i am doing anyting wrong.
  • Hi Rakesh,

    Your code seems to follow the correct flow, even leaving additional delay for the HDC to convert and startup, but it is possible I am missing something. Are you seeing the "Too many attempts" failure mode? Or are you seeing that the DRDY bit does actually go high but only after a few cycles? 

    Do you have access to the DRDY pin on the HDC2080 in your setup? If so I would recommend writing 0x04 to register 0x0E before you trigger your first measurement, but after the 10ms startup delay. This will set the interrupt pin to pull down when the DRDY bit is high. If you check that pin on an oscope or logic analyzer you should be able to see when the DRDY flag is active. If you can capture SDA and SCL as well that may provide clarity about what is happening.

    Best Regards,
    Brandon Fisher

  • Hi Brandon,

    Thanks for the detail response,

    currently, I am not able to check with oscope but I have debugged little more and found that.

    after 4-5 successful read operation, when I am getting this issue at that time the value in register 0x0f is 0xF6.

    can you please guide me on why I am getting 0xF6 even though my i2c operation is successful but I am getting the wrong value in the 0x0f register.

    what will be the value of register 0x0f if I turn off the hdc2080 and read it back once it is turned ON? I am powering off the HDC2080 using GPIO once I completed reading. 

    I am initializing HDC2080 only once, I observed that if I initialize register 0x0f with value 0x02 and if I turn off HDC2080 using GPIO and if again I read 0x0f register I am getting 0x00.

    I am not resetting HDC2080 anywhere in the code.

  • Dear Rakesh - 

    0x0F being 0x00 is default on power up. The settings are not retained over the power cycle. 

    regarding the non-zero value in 0x0F after power cycle...when operating the IC above 2.3VDC and there are two ways around this register corruption in your system. 

    1. If possible, change the input voltage to the HDC2080 or HDC2010 to 1.8VDC. You could use voltage divider on the GPIO or change the CC2640 based system to run from 1.8VDC using the external regulator mode available on that device, so the GPIO would then be at 1.8VDC.  

    2. If #1 is not possible, then you can, after power up and before configuring the device further (if deviating from default) or sending a 'start conversion' (i.e. 0x01 to 0x0F) - send this custom command string to the HDC2080 or HDC2010 device and this problem will be eliminated. The implication of the usage of this is that the idle current will be ~200uA (vs. 80uA)  after 0x04 is written to 0x45. Since you turning off the part after you measure, this should not impact you greatly, as the sequence is short and the measurements are made and returned quickly, but will be some extra draw you need to know about and perhaps account for in your system.  You could also run this sequence as a trap, after reading non-zero value in 0x0F after power up, so as to not always do this, but only when it occurs. 

    Command Description Register Address R/W Data

    Custom Mode Entry

    (3 writes to I2C address)

    0xF1 W -
    0xE7 W -
    0xFF W -
    Custom Command 0x45 W 0x04
    Custom Mode Exit 0xE1 W -
    Software Reset 0x0E W 0x80

    Custom Mode Entry

    (3 writes to I2C address)

    0xF1 W -
    0xE7 W -
    0xFF W -
    Custom Command 0x45 W 0x04
    Custom Mode Exit 0xE1 W -