twi sensor i am not getting the data

hi,

i am using nrf52832 devkit and max30208 temp. sensor. i am not getting updated data. iprefer this link for i2c address.(https://os.mbed.com/users/cyberjoey/code/OT07_I2C_GUI_Firmware//file/2e7483c7281b/main.cpp/

source code 

/** @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"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

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

/* Common addresses definition for temperature sensor. */
#define max30208_slave_add 0x50U // (0x50U >> 1)
#define max30208_config 0x01U
#define max30208_read_data 0x08U
#define max30208_temp_setup 0x14U
#define max30208_temp_setup_value 0xC1U

#define LM75B_REG_TEMP 0x00U
#define LM75B_REG_CONF 0x01U
#define LM75B_REG_THYST 0x02U
#define LM75B_REG_TOS 0x03U

#define OT07_FIFO_DATA 0x08U // read temp. data
#define OT07_ADC_SETUP 0x14 // OT07 Temp Seneor Setup (ADC_RES[7:6]) & Convert Temperature [0]
/* Mode for LM75B. */
#define NORMAL_MODE 0U

/* 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);

double Temp_sample;


static void temp_tx_setup(void)
{
m_xfer_done = false;
ret_code_t err_code;
uint8_t reg[2] = {max30208_temp_setup, max30208_temp_setup_value};
err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, sizeof(reg), false);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);

}

static void temp_rx_setup(void)
{
ret_code_t err_code;
m_xfer_done = false;
char data[2];
uint16_t count;
uint8_t reg[1] = {max30208_read_data};
err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, 2, false);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);

err_code = nrf_drv_twi_rx(&m_twi, max30208_read_data, data, 2);
APP_ERROR_CHECK(err_code);
NRF_LOG_INFO("Temperature:data %d ", count);

/**
* @brief Function for setting active mode on MMA7660 accelerometer.
*/
void max30208_setmode(void)
{
ret_code_t err_code;

/* Writing to LM75B_REG_CONF "0" set temperature sensor in NORMAL mode. */
uint8_t reg[2] = {max30208_config, NORMAL_MODE};
err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, sizeof(reg), false);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);

/* Writing to pointer byte. */
/* reg[0] = OT07_ADC_SETUP;
err_code = nrf_drv_twi_tx(&m_twi, LM75B_ADDR, reg, 1, false);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);*/

/* reg[0] = OT07_FIFO_DATA;
m_xfer_done = false;
err_code = nrf_drv_twi_tx(&m_twi, LM75B_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.
*/
__STATIC_INLINE void data_handler(double temp)
{
//NRF_LOG_INFO("Temperature: %lf, int %d Celsius degrees.",temp, (int) temp);
}

/**
* @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)
{
data_handler(Temp_sample);
NRF_LOG_INFO("data sent event");
}
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_lm75b_config = {
.scl = ARDUINO_SCL_PIN,
.sda = ARDUINO_SDA_PIN,
.frequency = NRF_DRV_TWI_FREQ_400K,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH,
.clear_bus_init = false
};

err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_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()
{
temp_tx_setup();


nrf_delay_ms(500);
m_xfer_done = false;
char data[2];
uint16_t count;
ret_code_t err_code;
uint8_t reg[1] = {max30208_read_data};
err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, 2, false);
APP_ERROR_CHECK(err_code);
while (m_xfer_done == false);

err_code = nrf_drv_twi_rx(&m_twi, max30208_read_data, data, 2);
APP_ERROR_CHECK(err_code);
//calculate temperture from data
count = (uint16_t)(data[0]*256 + data[1]);
if (count >= 32768)
{count = 65536 - count;}
Temp_sample = (double)(count * 0.005);
NRF_LOG_INFO("Temperature data: %d , %X ", ,Temp_sample);
}

/**
* @brief Function for main application entry.
*/
int main(void)
{
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("\r\nTWI sensor example started.");

NRF_LOG_FLUSH();
twi_init();
max30208_setmode();

while (true)
{
nrf_delay_ms(500);

do
{
__WFE();
}while (m_xfer_done == false);

read_sensor_data();
NRF_LOG_FLUSH();
}
}

/** @} */

  • Hi Pavan,

    Not very easy to see the issue by just looking at the driver usage code. The issue is related to the sensor's spec and the timings. I would recommend you to get the oscilloscope or the logic analyzer output on the TWI pins connected to the sensor and match the spec to see if there are any differences in the timings on how the sensor expects to be driven.

  • Hi,

    it's really hard to read the code you posted, pleas use "insert code" menu. What strikes the eye:

    - I2C address is expected as 7 bits without "W" bit (as I understand, 0x50 >> 1 in your case)
    - did you connect sensor's GPIO pins to ground, to get proper I2C address?
    - try lower speed (100k) first
    - you have defined one-byte command (max30208_read_data) but writing two bytes
    - you're not waiting for m_xfer_done after rx operation in read_sensor_data()

  • Hi Dmitry,

    as u suggested, I did changes in my code. and I also preferred  max30208 code from here

    (https://os.mbed.com/users/cyberjoey/code/OT07_I2C_GUI_Firmware//file/2e7483c7281b/main.cpp/)

    the code is working without convert temp. function. but data is not updating. we need to use that function to update temp.

    please look into this.

    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrf_delay.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    /* TWI instance ID. */
    #define TWI_INSTANCE_ID     0
    
    /* Common addresses definition for temperature sensor. */
    #define max30208_slave_add         0x50U // (0x50U >> 1)
    #define max30208_config            0x01U
    #define max30208_read_data         0x08U
    #define max30208_temp_setup        0x14U
    #define max30208_temp_setup_value  0xC1U
    
    #define LM75B_REG_TEMP      0x00U
    #define LM75B_REG_CONF      0x01U
    #define LM75B_REG_THYST     0x02U
    #define LM75B_REG_TOS       0x03U
    
    //#define OT07_FIFO_DATA      0x08U   // read temp. data
    //#define OT07_ADC_SETUP      0x14    // OT07 Temp Seneor Setup (ADC_RES[7:6]) & Convert Temperature [0]
    /* Mode for LM75B. */
    #define NORMAL_MODE 0U
    
    /* 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);
    
    double Temp_sample;
    
    #define OT07_STATUS         0x00    // OT07 status regiter
    #define OT07_INT_EN         0x01    // OT07 Interrupt Enable
    #define OT07_FIFO_W         0x04    // OT07 FIFO Write Pointer
    #define OT07_FIFO_R         0x05    // OT07 FIFO Read Pointer
    #define OT07_FIFO_OF        0x06    // OT07 FIFO Overflow Counter
    #define OT07_FIFO_COUNT     0x07    // OT07 FIFO Data Count
    #define OT07_FIFO_DATA      0x08    // OT07 FIFO Data
    #define OT07_FIFO_CNFG1     0x09    // OT07 FIFO Configuration 1 (FIFO_A_FULL)
    #define OT07_FIFO_CNFG2     0x0A    // OT07 FIFO Configuration 2
    #define OT07_SYS            0x0C    // OT07 System Configuration
    #define OT07_ALARM_HIGH_MSB 0x10    // OT07 Alarm High MSB
    #define OT07_ALARM_HIGH_LSB 0x11    // OT07 Alarm High LSB
    #define OT07_ALARM_LOW_MSB  0x12    // OT07 Alarm Low MSB
    #define OT07_ALARM_LOW_LSB  0x13    // OT07 Alarm LOW LSB
    #define OT07_ADC_SETUP      0x14    // OT07 Temp Seneor Setup (ADC_RES[7:6]) & Convert Temperature [0]
    #define OT07_GPIO_SETUP     0x20    // OT07 GPIO Setup,  sets GPIO modes
    #define OT07_GPIO_CTRL      0x21    // OT07 GPIO control
    #define OT07_ROM_ID         0x31    // OT07 ROM_ID address of LSB?
    
    
    void OT07_write_register(char I2C_add, char reg_add, char byte){
        char data[2];
        ret_code_t err_code;
        data[0] = reg_add;
        data[1] = byte;
        err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, data, 2, false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
        NRF_LOG_INFO("wr[%02X %02X]\r\n", data[0], data[1]);
        
    }
    
    void OT07_read_register(char I2C_add, char reg_add, char *bytes, int n){
        ret_code_t err_code;
         err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, &reg_add, 1, 1);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false); 
    
        err_code = nrf_drv_twi_rx(&m_twi, max30208_slave_add, bytes, n);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
        
    }
    
    
    void convert_temperature(char I2C_add){   // set convert bit to start conversion
    
        char data[2];  
        
        //read ADC_SETUP register 0x14
        OT07_read_register(I2C_add, OT07_ADC_SETUP,data,1);       
    
        //mask convert register value with 0x01 and write back register 0x14      
        OT07_write_register(I2C_add, OT07_ADC_SETUP, data[0]|0x01);
    }
    
    
    /**
     * @brief Function for setting active mode on MMA7660 accelerometer.
     */
    void max30208_setmode(void)
    {
        ret_code_t err_code;
    
        /* Writing to LM75B_REG_CONF "0" set temperature sensor in NORMAL mode. */
        uint8_t reg[2] = {max30208_config, NORMAL_MODE};
        err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, sizeof(reg), 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.
     */
    __STATIC_INLINE void data_handler(double temp)
    {
        NRF_LOG_INFO("Temperature: int %d Celsius degrees.",temp);
    }
    
    /**
     * @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)
                {
                    data_handler(Temp_sample);
                    NRF_LOG_INFO("data sent event");
                }
                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_lm75b_config = {
           .scl                = ARDUINO_SCL_PIN,
           .sda                = ARDUINO_SDA_PIN,
           .frequency          = NRF_DRV_TWI_FREQ_400K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        err_code = nrf_drv_twi_init(&m_twi, &twi_lm75b_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()
    {
        m_xfer_done = false;
        char data[2];
        uint16_t count;
        ret_code_t err_code;
        uint8_t reg[1] = {max30208_read_data};
        err_code = nrf_drv_twi_tx(&m_twi, max30208_slave_add, reg, 1, false);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
       
        err_code = nrf_drv_twi_rx(&m_twi, max30208_slave_add, data, 2);
        APP_ERROR_CHECK(err_code);
        while (m_xfer_done == false);
        //calculate temperture from data     
        count = (uint16_t)(data[0]*256 + data[1]);
        if (count >= 32768)
        {count = 65536 - count;} 
        Temp_sample = (double)(count * 0.005); 
        NRF_LOG_INFO("Temperature data: debug  %d ", Temp_sample);
    }  
        
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        NRF_LOG_INFO("\r\nTWI sensor example started.");
    
        NRF_LOG_FLUSH();
        twi_init();
         max30208_setmode();
    
        while (true)
        {
            nrf_delay_ms(500);
    
            do
            {
                __WFE();
            }while (m_xfer_done == false);
            convert_temperature(max30208_slave_add);
            nrf_delay_ms(20);
            read_sensor_data();
            NRF_LOG_FLUSH();
        }
    }
    
    

Related