This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Triggering measurement with I2C on HDC2080 from Texas Instrument

SDK : 12.3.0

IDE : Segger Embedded Studio V3.40

Softdevice : S130

Platform : Windows 8.1 64 bits

Hardware : PCA10028 (nRF51DK) v1.2.2

Setup : nRF51DK + HDC2080 from TI

             Sensor            |           nRF51DK

          Pin 1 (SDA)   -------->       P0.30

          Pin 2 (GND)  -------->       GND

          Pin 3 (ADDR) ------->       GND

          Pin 4 (/INT)    ------->        Not connected

          Pin 5 (VDD)   ------->        VDD

          Pin 6 (SCL)    ------->        P0.07

Hi dear Nordic community,

I'm completely new to Nordic systems so please excuse me if something seems evident for you.

So, I'm working with HDC2080 Temp/Hum sensor from Texas Instrument and nRF51DK. At this stage, I'm trying to communicate with this sensor over I2C to get temperature and humidity reading.

Basically, there are 2 ways of triggering a measurement on this sensor : 

1- Manually by sending a command (0x01) over I2C in (0x0F) register

2- Enabling the bit field AMM[6:4] in (0x0E) register to trigger measurement over a periodic timing (i.e 1 sample every 2 minutes)

For my part, i'm using the first method. Up until now, everything is fine for me as I tested it with an Arduino Nano and it outputs what I need from it. 

The problem I have is with the coding of the software for the nRF51DK. Here is the code : 

/**
 * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, 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.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
 * 
 */

/** @file
 * @defgroup tw_sensor_example main.c
 * @{
 * @ingroup nrf_twi_example
 * @brief TWI Sensor Example main file.
 *
 * This file contains the source code for a sample application using TWI.
 *
 */

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"

#define NRF_LOG_MODULE_NAME "APP"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"

/* TWI instance ID. */
#define TWI_INSTANCE_ID     0

/* Common addresses definition for HDC2080 sensor. */
#define HDC2080_ADDR              0x40U

#define HDC2080_REG_TEMP_LOW      0x00U
#define HDC2080_REG_TEMP_HIGH     0x01U
#define HDC2080_REG_HUM_LOW       0x02U
#define HDC2080_REG_HUM_HIGH      0x03U
#define HDC2080_REG_CONF          0x0FU

/* Mode for HDC2080. */
#define MEAS_TRIG 1U

/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

/* Buffer for byte read from HDC2080 sensor - 8 bit register- (temp_low,temp_high,hum_low,hum_high). */
static uint8_t m_sample[4] = {0,0,0,0};

/* Buffer for the real temp calculation - 16 bits once concatenated - */
static uint16_t temp = 0;
/* Buffer for the real hum calculation - 16 bits once concatenated - */
static uint16_t hum = 0;

/* Buffer for the calculated value of temp*/
static float temp_calc = 0;
/* Buffer for the calculated value of hum*/
static float hum_calc = 0;

/**
 * @brief Function for triggering measurement on HDC2080.
 */
void HDC2080_trigger_measurement(void)
{
    ret_code_t err_code;

    /* Writing to HDC2080_REG_CONF "1" to trigger measurements. */
    uint8_t reg[2] = {HDC2080_REG_CONF,MEAS_TRIG};
    err_code = nrf_drv_twi_tx(&m_twi, HDC2080_ADDR, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_INFO("\r\nMulti-read enable\r\n");
    while (m_xfer_done == false);
   


    /* Writing to pointer byte. */
    reg[0] = HDC2080_REG_TEMP_LOW;
    m_xfer_done = false;
    NRF_LOG_INFO("\r\nTemp\r\n");
    err_code = nrf_drv_twi_tx(&m_twi, HDC2080_ADDR, reg, 1, false);
    APP_ERROR_CHECK(err_code);
    while (m_xfer_done == false);
   
}

/**
 * @brief Function for handling data from temperature sensor.
 *
 * @param[in] temp   Temperature in Celsius degrees read from sensor.
 * @param[in] hum    Humidity in % read from sensor.
 */
__STATIC_INLINE void data_handler(float temp, float hum)
{
    NRF_LOG_INFO("Temperature: \r" NRF_LOG_FLOAT_MARKER " Celsius\r\n", NRF_LOG_FLOAT(temp));
    NRF_LOG_INFO("Humidity: \r" NRF_LOG_FLOAT_MARKER " %%\r\n", NRF_LOG_FLOAT(hum));
}

/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                /* Temperature conversion formula given in HDC2080 Datasheet - page 18 */
                temp = (uint8_t)m_sample[1] << 8 | m_sample[0];
                temp_calc = (float)(temp) * 165 / 65536 - 40;
                /* Humidity conversion formula given in HDC2080 Datasheet - page 18 */
                hum = (uint8_t)m_sample[3] << 8 | m_sample[2];
                hum_calc = (float)(hum)/(65536) * 100;
                /* Passing temp and hum to data_handler */
                data_handler(temp_calc, hum_calc);
            }
            m_xfer_done = true;

            /* not sure about this part if it is ok or not */
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
            {
                m_xfer_done = true;
            }
            break;
            
        default:
            break;
    }
}

/**
 * @brief UART initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_HDC2080_config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       /* I'm using IRQ priority low because i want to use this code with S130 Softdevice in the future */
       .interrupt_priority = APP_IRQ_PRIORITY_LOW,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_HDC2080_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}

/**
 * @brief Function for reading data from temperature sensor.
 */
static void read_sensor_data()
{
    ret_code_t err_code;
  
    /* Read 4 bytes starting from the specified address */
    /* Start reading from HDC2080_REG_TEMP_LOW through HDC2080_REG_HUM_HIGH */
    /* This is working because on the terminal I can see temp and hum values */
    err_code = nrf_drv_twi_rx(&m_twi, HDC2080_ADDR, m_sample, sizeof(m_sample));
    APP_ERROR_CHECK(err_code);
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_INFO("\r\nTWI sensor example\r\n");
    NRF_LOG_FLUSH();
    twi_init();
    /* this is where i'm having trouble */
    /* if this function sits here, it triggers only one reading since we're out of the while loop */
    /* and then when read_sensor_data is called, it always sends the same measurement since this is */
    /* what the sensor saved in his registers the first time HDC2080_trigger_measurement was called */
    HDC2080_trigger_measurement();
    
    
    while (true)
    {
        /* But if i put HDC2080_trigger_measurement function here, it gives one reading on the output */ 
        /* and then the program ends saying "Fatal error" ?!?!?! */
        do
        {
          __WFE();
        }while (m_xfer_done == false);

       read_sensor_data();
       NRF_LOG_FLUSH();
       nrf_delay_ms(1000);
    }
}

/** @} */

If you take a look at the HDC2080_trigger_measurement() function in the main, this is where i'm having trouble. Actually, the way it sits in the main only triggers one measurement and when read_sensor_data() function is called, it always output the same value even if I put my finger on the sensor. So, what it tells me is that the sensor is always outputing the values it recorded when the first measurement was triggered.

So, being wise, I tried to do the same as in my Arduino scheme -> put the HDC2080_trigger_measurement() function inside the "while loop" thinking that a new trigger will be produce every time the loop is refreshed, but with great surprise, it only triggers one measurement again and the program ends saying "fatal error" ?!?!?!

 

What do you guys think the problem is ? Maybe I'm off with something and I can't seem to find what it is exactly.

Thank you all for your support

Related