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.

HDC1080: HDC1080

Part Number: HDC1080

Hi,

we have just started to work with the HDC1080 to get humidity and temperature readings in our sensor nodes. The MCU on the nodes is a Atmel/Microchip Atsam4 and we're using the ASF TWI/I2C library for interfacing with I2C devices.

We are having some problems interfacing with the HDC1080. We can successfully read the Device ID register (OxFF) which returns 0x1050 as per the docs. So, we can assume it's not an hardware problem. To read the Device ID register however, we first have to do an I2C write to the sensor. It doesn't seem to matter what we write, but if we don't write anything we're not able to read the Device ID register. Does this makes sense? From the docs it looks like the register should be readable without any previous commands.

We are not able to read the temperature and humidity registers however. Even if we first issue a write to reg 0x00, a read of the humidity and temperature registers fails. We've tried various delays between the write and the reads, but it doesn't seem to make any difference.

Could the problem be related to the Atmel/Microchip I2C/TWI libraries not being compatible with the sensor interface. We're using the high level functions twi_master_read and twi_master_write. Here is the code for the twi_master_read:

uint32_t twi_master_read(Twi *p_twi, twi_packet_t *p_packet)
{
	uint32_t status;
	uint32_t cnt = p_packet->length;
	uint8_t *buffer = p_packet->buffer;
	uint8_t stop_sent = 0;
	uint32_t timeout = TWI_TIMEOUT;;
	
	/* Check argument */
	if (cnt == 0) {
		return TWI_INVALID_ARGUMENT;
	}

	/* Set read mode, slave address and 3 internal address byte lengths */
	p_twi->TWI_MMR = 0;
	p_twi->TWI_MMR = TWI_MMR_MREAD | TWI_MMR_DADR(p_packet->chip) |
			((p_packet->addr_length << TWI_MMR_IADRSZ_Pos) &
			TWI_MMR_IADRSZ_Msk);

	/* Set internal address for remote chip */
	p_twi->TWI_IADR = 0;
	p_twi->TWI_IADR = twi_mk_addr(p_packet->addr, p_packet->addr_length);

	/* Send a START condition */
	if (cnt == 1) {
		p_twi->TWI_CR = TWI_CR_START | TWI_CR_STOP;
		stop_sent = 1;
	} else {
		p_twi->TWI_CR = TWI_CR_START;
		stop_sent = 0;
	}

	while (cnt > 0) {
		status = p_twi->TWI_SR;
		if (status & TWI_SR_NACK) {
			return TWI_RECEIVE_NACK;
		}

		if (!timeout--) {
			return TWI_ERROR_TIMEOUT;
		}
				
		/* Last byte ? */
		if (cnt == 1  && !stop_sent) {
			p_twi->TWI_CR = TWI_CR_STOP;
			stop_sent = 1;
		}

		if (!(status & TWI_SR_RXRDY)) {
			continue;
		}
		*buffer++ = p_twi->TWI_RHR;

		cnt--;
		timeout = TWI_TIMEOUT;
	}

	while (!(p_twi->TWI_SR & TWI_SR_TXCOMP)) {
	}

	p_twi->TWI_SR;

	return TWI_SUCCESS;
}

Could it be that the functions from the ASF API is to high level for the HDC1080 interface?

Best regards,

Erik

  • Dear Erik - 

    From power up, you can issue 0x00 to 0x80 (if that is your I2C address, this is 8 bit equivalent of 0x40 I2C address for write and should be 0x41 (7 bit) or 0x81 (8 bit)for reads) - if you take a look at the I2C activity you may find the issue right away. 

    To help with that - here is overall logic shot of that, where activity on the right is the command to do measurement and left is reading out the registers, showing the waiting time in between

     

    Here are  the zooms: 

    Sending pointer: 

    Retrieving Data: 

    and here is the entire sequence (use Saleae viewer) in case you want to scroll through it and analyze more. The complete sequence starts with determining date of manufacture, then does temp/%RH measurements at 1 sec intervals. 

    HDC1080_Read out FB_FC_for_DoM_calc_then Read Temp Hum _1sec intervals (2).zip

  • Hi Josh,

    thanks for the quick reply. I'm not a 100% sure I understand though. Do we need to issue an extra command to get the sensor to wake up before we can even read? Isn't it enough to write the address of the Device id register on the I2C bus, and then read the two bytes?

    Best regards,

    Erik

  • Erik - 

    as described in Section 8.5.1.3 of the datasheet, steps 2-4 (page 11) - the measurements are triggered by writing to the pointer 0x00. Reading the DID of the device or any of the other registers is/are separate operation(s).  

  • Yeah, that's what I'm talking about. I need to issue a command on the I2C bus even to be able to read the device id first, which doesn't make any sense. The approach according to the data sheet is that I should

    1. Write the device id reg address on the bus

    2. Read back the bytes of the ID

    This does not work. I have to issue something else on the bus before step 1 for some reason.

    Best regards,

    Erik

  • Erik - 

    Reading the DiD would look like this: 

    you write the pointer to 0xFF, then read two bytes out, no different than the other register reads