1
\$\begingroup\$

I want to use my HIH6030 humidity and temperature sensor with my STM32F4 board, but I have the following problem:

I turn my board on and start debugging. The first time when I try to read out it's ok. It seems I got good values, but next time I read data from the sensor I get exactly the same values as before. All the times I get the same values, until I restart my board.

I can't see what could be the problem. I hope you guys can help me.

My code:

#define HIH_ADDRESS 0x27

typedef struct {
    double temperature;
    double humidity;
} HIH_readout;

void initI2C() {
    __HAL_RCC_I2C2_CLK_ENABLE();
    hi2c2.Instance = I2C2;
    hi2c2.Init.ClockSpeed = 400000;
    hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c2.Init.OwnAddress1 = 0;
    hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c2.Init.OwnAddress2 = 0;
    hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c2) != HAL_OK)
    {
        initStatus = ERROR_I2C_INIT;
    }
}

int HIH_read(HIH_readout* buffer) {
    uint8_t data[4];
    uint16_t temp_humidity;
    uint16_t temp_temperature;

    if(HAL_I2C_Master_Receive(&hi2c2, HIH_ADDRESS << 1,data, 4, 10) != HAL_OK){
        buffer->humidity = 0;
        buffer->temperature = 0;
        return HIH_FAIL;
    }
    uint8_t status = (data[0] & (uint8_t)0xC0U);
    //Masking MSB (status) bits
    temp_humidity = ((data[0] & ((uint8_t)0x3FU)) << 8) | data[1];
    //Masking LSB (don't care) bits
    temp_temperature = (data[2] << 8) | (data[3] & ((uint8_t)0xFCU));
    //The last two bits -> don't care
    temp_temperature = temp_temperature >> 2;

    //SCALE AND CAST
    buffer->humidity = (double)(temp_humidity * 100 / (pow(2,14) - 1));
    buffer->temperature = (double)(temp_temperature / (pow(2, 14) - 1) * 165 - 40);

    return HIH_OK;

}

When my main begins I call HAL_Init(); initI2C(); and after in while(1), I call HIH_read; I used Cubemx to generate initialzation code, so hopefully it works well.

\$\endgroup\$
  • \$\begingroup\$ The sensors transmits the Most Significant Byte or Least Significant Byte first in its response? \$\endgroup\$ – Bence Kaulics May 8 '17 at 11:52
  • \$\begingroup\$ @BenceKaulics According to this: sensing.honeywell.com/… The MSB is transmitted first. \$\endgroup\$ – prodx May 8 '17 at 13:13
  • 2
    \$\begingroup\$ I think that the MR, measurement request command is missing. It is actually an I2C write command with no payload. You only send I2C read commands. \$\endgroup\$ – Bence Kaulics May 8 '17 at 13:35
  • \$\begingroup\$ Without that the data output register won't be updated. And always check the status bits as those tell you if the valid data has been fetched or not. \$\endgroup\$ – Bence Kaulics May 8 '17 at 13:51
3
\$\begingroup\$

Just by looking at those lines of code, I think the error might occur in your casting code:

//SCALE AND CAST
buffer->humidity = (double)(temp_humidity * 100 / (pow(2,14) - 1));
buffer->temperature = (double)(temp_temperature / (pow(2, 14) - 1) * 165 - 40);

As you do it, the values get casted after the scaling calculations are done, right before saving. This means the calculations are still done as integers. So as the humidity and temperature probably only vary a little bit, you lose these changes right there.

To execute a calculation as double, at least one operand has to be a double value. Try it like this:

//SCALE AND CAST
buffer->humidity = ((double)temp_humidity * 100 / (pow(2,14) - 1));
buffer->temperature = ((double)temp_temperature / (pow(2, 14) - 1) * 165 - 40);

I hope this works for you

\$\endgroup\$
  • \$\begingroup\$ Unfortunately it didn't help me, but I appreciate. Today I checked the two status bits that I don't use. I could see that the sensor switch to command mode after the first reading and i don't know why. Now I send the 0x80 command (escape command mode) before every reading, so it works now and I can do measurements, but I still don't know why it goes to command mode. \$\endgroup\$ – prodx May 8 '17 at 10:10
  • \$\begingroup\$ @prodx A remark if your microcontroller does have a FPU (Floating Point Unit) you should not use doubles but floats instead. \$\endgroup\$ – Bence Kaulics May 8 '17 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.