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.

LPSTK-CC1352R: HDC2080 returns zero only with i2ctmp example

Part Number: LPSTK-CC1352R
Other Parts Discussed in Thread: HDC2080, TMP116,

Dear experts,

i have tried to read the temperature and humidity value from HDC2080 using i2ctmp example but i am getting 0 only. i have shared my code with syscfg file for your reference please check and point out the mistakes i made.

i2ctmp.c
/*
 * Copyright (c) 2018-2022, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 *  ======== i2ctmp.c ========
 */
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/display/Display.h>

/* Driver configuration */
#include "ti_drivers_config.h"

//#include <ti/sail/hdc2010/hdc2010.h>

#define TASKSTACKSIZE 640

/* Temperature result registers */
#define TMP11X_RESULT_REG 0x0000

/* I2C slave addresses */
#define TMP11X_BASSENSORS_ADDR 0x40
#define TMP116_LAUNCHPAD_ADDR  0x41

/* Number of supported sensor iterations */
#define TMP_COUNT 2

/*
 * Data structure containing currently supported I2C TMP sensors.
 * Sensors are ordered by descending preference.
 */
static const struct
{
    uint8_t address;
    uint8_t resultReg;
    char *id;
} sensors[TMP_COUNT] = {{TMP11X_BASSENSORS_ADDR, TMP11X_RESULT_REG, "11X"},
                        {TMP116_LAUNCHPAD_ADDR, TMP11X_RESULT_REG, "116"}};

static uint8_t slaveAddress;
static Display_Handle display;

static void i2cErrorHandler(I2C_Transaction *transaction, Display_Handle display);

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    uint16_t sample;
    int16_t temperature;
    uint8_t txBuffer[1];
    uint8_t rxBuffer[2];
    int8_t i;
    I2C_Handle i2c;
    I2C_Params i2cParams;
    I2C_Transaction i2cTransaction;

    /* Call driver init functions */
    Display_init();
    GPIO_init();
    I2C_init();

    /* Configure the LED and if applicable, the TMP_EN pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
#ifdef CONFIG_GPIO_TMP_EN
    GPIO_setConfig(CONFIG_GPIO_TMP_EN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    /* Allow the sensor to power on */
    sleep(1);
#endif

    /* Open the UART display for output */
    display = Display_open(Display_Type_UART, NULL);
    if (display == NULL)
    {
        while (1) {}
    }

    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    Display_printf(display, 0, 0, "Starting the i2ctmp example\n");

    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_100kHz;
    i2c               = I2C_open(CONFIG_I2C_TMP, &i2cParams);
    if (i2c == NULL)
    {
        Display_printf(display, 0, 0, "Error Initializing I2C\n");
        while (1) {}
    }
    else
    {
        Display_printf(display, 0, 0, "I2C Initialized!\n");
    }

    /* Common I2C transaction setup */
    i2cTransaction.writeBuf   = txBuffer;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf    = rxBuffer;
    i2cTransaction.readCount  = 0;

    /*
     * Determine which I2C sensors are present by querying known I2C
     * slave addresses.
     */
    for (i = TMP_COUNT - 1; i >= 0; i--)
    {
        i2cTransaction.slaveAddress = sensors[i].address;
        txBuffer[0]                 = sensors[i].resultReg;

        if (I2C_transfer(i2c, &i2cTransaction))
        {
            slaveAddress = sensors[i].address;
            Display_printf(display,
                           0,
                           0,
                           "Detected TMP%s sensor with slave"
                           " address 0x%x",
                           sensors[i].id,
                           sensors[i].address);
        }
        else
        {
            i2cErrorHandler(&i2cTransaction, display);
        }
    }

    /* If we never assigned a slave address */
    if (slaveAddress == 0)
    {
        Display_printf(display, 0, 0, "Failed to detect a sensor!");
        I2C_close(i2c);
        while (1) {}
    }

    Display_printf(display, 0, 0, "\nUsing last known sensor for samples.");
    i2cTransaction.slaveAddress = slaveAddress;

    /* Take 20 samples and print them out onto the console */
    i2cTransaction.readCount = 4;
    for (sample = 0; sample < 20; sample++)
    {
        if (I2C_transfer(i2c, &i2cTransaction))
        {
            /*
             * Extract degrees C from the received data;
             * see TMP sensor datasheet
             */
            temperature = rxBuffer[0] ;
            Display_printf(display, 0, 0, "Sample %d ",temperature);
            temperature = (temperature << 8) | (rxBuffer[1]);


            //temperature *= 0.0078125;
            float f =temperature;
            f = ((f * 165.0f) / 65536.0f) - 40.0f;

            int16_t humidity = rxBuffer[2];
            humidity = (humidity << 8) | rxBuffer[3];
            float H = humidity;
            H = (H/65536.0) * 100.0;

            Display_printf(display, 0, 0, "Sample %u: %0.2f (C), %0.2f ", sample, f,H);
        }
        else
        {
            i2cErrorHandler(&i2cTransaction, display);
        }

        /* Sleep for 1 second */
        sleep(1);
    }

    I2C_close(i2c);
    Display_printf(display, 0, 0, "I2C closed!");

    return (NULL);
}

/*
 *  ======== i2cErrorHandler ========
 */
static void i2cErrorHandler(I2C_Transaction *transaction, Display_Handle display)
{
    switch (transaction->status)
    {
        case I2C_STATUS_TIMEOUT:
            Display_printf(display, 0, 0, "I2C transaction timed out!");
            break;
        case I2C_STATUS_CLOCK_TIMEOUT:
            Display_printf(display, 0, 0, "I2C serial clock line timed out!");
            break;
        case I2C_STATUS_ADDR_NACK:
            Display_printf(display,
                           0,
                           0,
                           "I2C slave address 0x%x not"
                           " acknowledged!",
                           transaction->slaveAddress);
            break;
        case I2C_STATUS_DATA_NACK:
            Display_printf(display, 0, 0, "I2C data byte not acknowledged!");
            break;
        case I2C_STATUS_ARB_LOST:
            Display_printf(display, 0, 0, "I2C arbitration to another master!");
            break;
        case I2C_STATUS_INCOMPLETE:
            Display_printf(display, 0, 0, "I2C transaction returned before completion!");
            break;
        case I2C_STATUS_BUS_BUSY:
            Display_printf(display, 0, 0, "I2C bus is already in use!");
            break;
        case I2C_STATUS_CANCEL:
            Display_printf(display, 0, 0, "I2C transaction cancelled!");
            break;
        case I2C_STATUS_INVALID_TRANS:
            Display_printf(display, 0, 0, "I2C transaction invalid!");
            break;
        case I2C_STATUS_ERROR:
            Display_printf(display, 0, 0, "I2C generic error!");
            break;
        default:
            Display_printf(display, 0, 0, "I2C undefined error case!");
            break;
    }
}

regards

Surya

  • i2ctmp example is for TMP sensor. If you use HDC2080, I suppose you need to revise the source code to make it work.

  • Hi

    Thanks for the reply, yes i know that then i have changed the device address and other settings. i don't know what i missed. i have shared the serial log for the reference.

    Starting the i2ctmp example

    I2C Initialized!

    Detected TMP116 sensor with slave address 0x41
    I2C slave address 0x40 not acknowledged!

    Using last known sensor for samples.
    Sample 0: -40.0000 (C), 0.0000
    Sample 1: -40.0000 (C), 0.0000
    Sample 2: -40.0000 (C), 0.0000
    Sample 3: -40.0000 (C), 0.0000
    Sample 4: -40.0000 (C), 0.0000
    Sample 5: -40.0000 (C), 0.0000
    Sample 6: -40.0000 (C), 0.0000
    Sample 7: -40.0000 (C), 0.0000
    Sample 8: -40.0000 (C), 0.0000
    Sample 9: -40.0000 (C), 0.0000
    Sample 10: -40.0000 (C), 0.0000
    Sample 11: -40.0000 (C), 0.0000
    Sample 12: -40.0000 (C), 0.0000
    Sample 13: -40.0000 (C), 0.0000
    Sample 14: -40.0000 (C), 0.0000
    Sample 15: -40.0000 (C), 0.0000
    Sample 16: -40.0000 (C), 0.0000
    Sample 17: -40.0000 (C), 0.0000
    Sample 18: -40.0000 (C), 0.0000
    Sample 19: -40.0000 (C), 0.0000
    I2C closed!

    regards

    Surya.

  • I tried the link i received deviceID and manufacturer ID but still temp and humidity is zero, please check my code and serial log.

    for (sample = 0; sample < 5; sample++)
    {
    txBuffer[0] =0x00;
    i2cTransaction.slaveAddress=0x41;//HDC_ADDR;
    i2cTransaction.writeCount = 0;
    i2cTransaction.readBuf = rxBuffer;
    i2cTransaction.readCount = 4;
    if (I2C_transfer(i2c, &i2cTransaction))
    {
    /*
    * Extract degrees C from the received data;
    * see TMP sensor datasheet
    */
    temperature = rxBuffer[0] ;
    temperature = (temperature << 8) | (rxBuffer[1]);
    Display_printf(display, 0, 0, "\n DATA OK: 0x%x 0x%x", rxBuffer[0], rxBuffer[1]);


    //temperature *= 0.0078125;
    float f =temperature;
    f = ((f * 165.0f) / 65536.0f) - 40.0f;

    int16_t humidity = rxBuffer[2];
    humidity = (humidity << 8) | rxBuffer[3];
    float H = humidity;
    H = (H/65536.0) * 100.0;

    Display_printf(display, 0, 0, "Sample %u: %0.2f (C), %0.2f ", sample, f,H);
    }
    else
    {
    i2cErrorHandler(&i2cTransaction, display);
    }

    SERIAL LOG!!!!!!!!

    Starting the i2ctmp example

    I2C Initialized!


    Manufacture ID: 4954

    Device ID: d07
    Detected TMP2080 sensor with slave address 0x41
    I2C slave address 0x40 not acknowledged!

    Using last known sensor for samples.

    DATA OK: 0x0 0x0
    Sample 0: -40.0000 (C), 0.0000

    DATA OK: 0x0 0x0
    Sample 1: -40.0000 (C), 0.0000

    DATA OK: 0x0 0x0
    Sample 2: -40.0000 (C), 0.0000

    DATA OK: 0x0 0x0
    Sample 3: -40.0000 (C), 0.0000

    DATA OK: 0x0 0x0
    Sample 4: -40.0000 (C), 0.0000
    I2C closed!

    regards

    Surya

  • please share logic analyzer plots of what is going on on the I2C bus. Then someone with knowledge about the HDC2080 can verify if you are communicating correctly with the sensor.

    Siri

  • Hi Siri,

    i have attached my DSO- Hantek DSO5102P output for your reference, Currently i am working with CC1352-Sensor tag module and inbuilt HDC Sensor only.

    Blue is CLK

    Yellow is DATA

    regards

    Surya

  • Auto Measurement Mode (AMM) is disabled by default. The RH and Temperature registers are also zero at reset. You must select an AMM in the Configuration Register, or trigger individual measurements in the Measurement Configuration Register.

    From HDC2080.c dev.ti.com/.../index.html

    /*
     *  ======== HDC2080_read ========
     *  Read temperature and humidity registers
     */
    void HDC2080_read(HDC2080_Handle sensor, uint32_t result[])
    {
        uint8_t txBuf[2];
        uint8_t rxBuf[4] = {0};
    
        /* If AMM is disabled trigger conversion */
        if (!(sensor->config & HDC2080_CONFIG_AMM_MASK)) {
            /* Reset AMM to start measurement */
            txBuf[0] = HDC2080_MEAS_CONFIG;
            txBuf[1] = sensor->measConfig | HDC2080_MEAS_CONFIG_MEAS_TRIG_START;
            mcu_i2cTransfer(sensor->busId, sensor->devAddr, txBuf, 2, NULL, 0);
    
            /* Wait for conversion to complete */
            mcu_msWait(sensor->convWaitHum);
        }
    
        /* Read registers, LOW and HIGH bytes */
        txBuf[0] = HDC2080_TEMP_LOW;
        mcu_i2cTransfer(sensor->busId, sensor->devAddr, txBuf, 1, rxBuf, 4);
    
        result[0] = (uint16_t)rxBuf[1] << 8 | rxBuf[0];
        result[1] = (uint16_t)rxBuf[3] << 8 | rxBuf[2];
    }

    ren

  • Hi

    Thanks for the reply, in this below line i can't find the sensor->measConfig value, please help to find the value and i have modified the code as per your suggestion please check and let me know this is ok or not....

    txBuf[1] = sensor->measConfig | HDC2080_MEAS_CONFIG_MEAS_TRIG_START;

    //#define HDC2080_MEAS_CONFIG 0x0FU
    //#define HDC2080_MEAS_CONFIG_MEAS_TRIG_START 0x01U
    
    txBuffer[0] =0x0F;
    txBuffer[1] =0x01;
    i2cTransaction.slaveAddress=0x41;//HDC_ADDR;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf = rxBuffer;
    i2cTransaction.readCount = 0;
    if (I2C_transfer(i2c, &i2cTransaction))
    {
        Display_printf(display, 0, 0, "RESET_AMM_OK");
    }
    
    txBuffer[0] =0x00;
    i2cTransaction.slaveAddress=0x41;//HDC_ADDR;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readBuf = rxBuffer;
    i2cTransaction.readCount = 4;
    if (I2C_transfer(i2c, &i2cTransaction))
    {
    /*
    * Extract degrees C from the received data;
    * see TMP sensor datasheet
    */
    temperature = rxBuffer[0] ;
    temperature = (temperature << 8) | (rxBuffer[1]);
    Display_printf(display, 0, 0, "\n DATA OK: 0x%x 0x%x", rxBuffer[0], rxBuffer[1]);
    
    
    //temperature *= 0.0078125;
    float f =temperature;
    f = ((f * 165.0f) / 65536.0f) - 40.0f;
    
    int16_t humidity = rxBuffer[2];
    humidity = (humidity << 8) | rxBuffer[3];
    float H = humidity;
    H = (H/65536.0) * 100.0;
    
    Display_printf(display, 0, 0, "Sample %u: %0.2f (C), %0.2f ", sample, f,H);
    }
    regards
    Surya
  • The full driver source code is available at the link I provided. This is only a snippet showing the read operation with delay needed.

    https://dev.ti.com/sysconfig/index.html?product=ascstudio&module=/ti/sensors/humiditysensor/HDC2080

    thanks,

    ren

  • Make sure you write bit 0 (MEAS_TRIG ) as 1 in Address 0x0F Measurement Configuration every time before you read measurement. I test it on my LPSTK-CC1352R and I can read temperature and humidity measurement successfully  from HDC2080 without problem.

  • Hi 

    Can you please share the config and read code part???

  • Hi

    Thanks for the link i will check and let you know the result...

    regards

    Surya

  • Hi Every one,

    Thank you all your support,

    i got the value from the HDC2080, 

    regards

    Surya