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

BME280 + nRF52 makefile erro

Hello Nordic, i am trying to interface BME280 with nordic nRF52 and SDK v 12.02 using twi_peripheral but i am unable to do it. here in example they are using ls75b whereas i am using BME280. I extracted the BME drivers in root along with BME280 arduino library but i can´t find a way out. Hoping for some valuable pointers.

Thanks in advance!!

#define MAX_PENDING_TRANSACTIONS    5

#define APP_TIMER_PRESCALER         0
#define APP_TIMER_OP_QUEUE_SIZE     2

// Pin number for indicating communication with sensors.
#ifdef BSP_LED_3
    #define READ_ALL_INDICATOR  BSP_BOARD_LED_3
#else
    #error "Please choose an output pin"
#endif


static app_twi_t m_app_twi = APP_TWI_INSTANCE(0);

static nrf_drv_rtc_t const m_rtc = NRF_DRV_RTC_INSTANCE(0);


// Buffer for data read from sensors.
#define BUFFER_SIZE  11
static uint8_t m_buffer[BUFFER_SIZE];

// Data structures needed for averaging of data read from sensors.
// [max 32, otherwise "int16_t" won't be sufficient to hold the sum
//  of temperature samples]
#define NUMBER_OF_SAMPLES  16
typedef struct
{
    int16_t temp;
    int16_t x;
    int16_t y;
    int16_t z;
} sum_t;
static sum_t m_sum = { 0, 0, 0, 0 };
typedef struct
{
    // [use bit fields to fit whole structure into one 32-bit word]
    int16_t temp : 11;
    int8_t  x    : 6;
    int8_t  y    : 6;
    int8_t  z    : 6;
} sample_t;
static sample_t m_samples[NUMBER_OF_SAMPLES] = { { 0, 0, 0, 0 } };
static uint8_t m_sample_idx = 0;

// Value previously read from MMA7660's Tilt register - used to detect change
// in orientation, shake signaling etc.
static uint8_t m_prev_tilt = 0;

#if defined( __GNUC__ ) && (__LINT__ == 0)
    // This is required if one wants to use floating-point values in 'printf'
    // (by default this feature is not linked together with newlib-nano).
    // Please note, however, that this adds about 13 kB code footprint...
    __ASM(".global _printf_float");
#endif


////////////////////////////////////////////////////////////////////////////////
// Reading of data from sensors - current temperature from bme280 and from
// MMA7660: X, Y, Z and tilt status.
#if (BUFFER_SIZE < 6)
    #error Buffer too small.
#endif
#define GET_ACC_VALUE(axis, reg_data) \
    do { \
        if (MMA7660_DATA_IS_VALID(reg_data)) \
        { \
            axis = MMA7660_GET_ACC(reg_data); \
        } \
    } while (0)

void read_all_cb(ret_code_t result, void * p_user_data)
{
    if (result != NRF_SUCCESS)
    {
        NRF_LOG_INFO("read_all_cb - error: %d\r\n", (int)result);
        return;
    }

    sample_t * p_sample = &m_samples[m_sample_idx];
    m_sum.temp -= p_sample->temp;
    m_sum.x    -= p_sample->x;
    m_sum.y    -= p_sample->y;
    m_sum.z    -= p_sample->z;

    uint8_t temp_hi = m_buffer[0];
    uint8_t temp_lo = m_buffer[1];
    uint8_t x_out   = m_buffer[2];
    uint8_t y_out   = m_buffer[3];
    uint8_t z_out   = m_buffer[4];
    uint8_t tilt    = m_buffer[5];

    p_sample->temp = bme280_GET_TEMPERATURE_VALUE(temp_hi, temp_lo);
    GET_ACC_VALUE(p_sample->x, x_out);
    GET_ACC_VALUE(p_sample->y, y_out);
    GET_ACC_VALUE(p_sample->z, z_out);
    if (!MMA7660_DATA_IS_VALID(tilt))
    {
        tilt = m_prev_tilt;
    }

    m_sum.temp += p_sample->temp;
    m_sum.x    += p_sample->x;
    m_sum.y    += p_sample->y;
    m_sum.z    += p_sample->z;

    ++m_sample_idx;
    if (m_sample_idx >= NUMBER_OF_SAMPLES)
    {
        m_sample_idx = 0;
    }

    // Show current average values every time sample index rolls over (for RTC
    // ticking at 32 Hz and 16 samples it will be every 500 ms) or when tilt
    // status changes.
    if (m_sample_idx == 0 || (m_prev_tilt && m_prev_tilt != tilt))
    {
        char const * orientation;
        switch (MMA7660_GET_ORIENTATION(tilt))
        {
            case MMA7660_ORIENTATION_LEFT:  orientation = "LEFT";  break;
            case MMA7660_ORIENTATION_RIGHT: orientation = "RIGHT"; break;
            case MMA7660_ORIENTATION_DOWN:  orientation = "DOWN";  break;
            case MMA7660_ORIENTATION_UP:    orientation = "UP";    break;
            default:                        orientation = "?";     break;
        }

        NRF_LOG_INFO("Temp: " NRF_LOG_FLOAT_MARKER " | X: %3d, Y: %3d, Z: %3d ",
            NRF_LOG_FLOAT((float)((m_sum.temp * 0.125) / NUMBER_OF_SAMPLES)),
            m_sum.x / NUMBER_OF_SAMPLES,
            m_sum.y / NUMBER_OF_SAMPLES,
            m_sum.z / NUMBER_OF_SAMPLES);

        NRF_LOG_RAW_INFO("| %s%s%s\r\n",
            (uint32_t)orientation,
            (uint32_t)(MMA7660_TAP_DETECTED(tilt)   ? " TAP"   : ""),
            (uint32_t)(MMA7660_SHAKE_DETECTED(tilt) ? " SHAKE" : ""));
        m_prev_tilt = tilt;
    }
}
static void read_all(void)
{
    // Signal on LED that something is going on.
    bsp_board_led_invert(READ_ALL_INDICATOR);

    // [these structures have to be "static" - they cannot be placed on stack
    //  since the transaction is scheduled and these structures most likely
    //  will be referred after this function returns]
    static app_twi_transfer_t const transfers[] =
    {
        bme280_READ_TEMP(&m_buffer[0])
        ,
        MMA7660_READ_XYZ_AND_TILT(&m_buffer[2])
    };
    static app_twi_transaction_t const transaction =
    {
        .callback            = read_all_cb,
        .p_user_data         = NULL,
        .p_transfers         = transfers,
        .number_of_transfers = sizeof(transfers) / sizeof(transfers[0])
    };

    APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));
}

#if (BUFFER_SIZE < 7)
    #error Buffer too small.
#endif
static void read_bme280_registers_cb(ret_code_t result, void * p_user_data)
{
    if (result != NRF_SUCCESS)
    {
        NRF_LOG_INFO("read_bme280_registers_cb - error: %d\r\n", (int)result);
        return;
    }

    NRF_LOG_INFO("bme280:\r\n");
    NRF_LOG_HEXDUMP_INFO(m_buffer, 7);
}
static void read_bme280_registers(void)
{
    // [these structures have to be "static" - they cannot be placed on stack
    //  since the transaction is scheduled and these structures most likely
    //  will be referred after this function returns]
    static app_twi_transfer_t const transfers[] =
    {
        bme280_READ(&bme280_conf_reg_addr,  &m_buffer[0], 1),
        bme280_READ(&bme280_temp_reg_addr,  &m_buffer[1], 2),
        bme280_READ(&bme280_tos_reg_addr,   &m_buffer[3], 2),
        bme280_READ(&bme280_thyst_reg_addr, &m_buffer[5], 2)
    };
    static app_twi_transaction_t const transaction =
    {
        .callback            = read_bme280_registers_cb,
        .p_user_data         = NULL,
        .p_transfers         = transfers,
        .number_of_transfers = sizeof(transfers) / sizeof(transfers[0])
    };

    APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));
}


#if (BUFFER_SIZE < MMA7660_NUMBER_OF_REGISTERS)
    #error Buffer too small.
#endif
static void read_mma7660_registers_cb(ret_code_t result, void * p_user_data)
{
    if (result != NRF_SUCCESS)
    {
        NRF_LOG_INFO("read_mma7660_registers_cb - error: %d\r\n", (int)result);
        return;
    }

    NRF_LOG_INFO("MMA7660:\r\n");
    NRF_LOG_HEXDUMP_INFO(m_buffer, MMA7660_NUMBER_OF_REGISTERS);
}
static void read_mma7660_registers(void)
{
    // [these structures have to be "static" - they cannot be placed on stack
    //  since the transaction is scheduled and these structures most likely
    //  will be referred after this function returns]
    static app_twi_transfer_t const transfers[] =
    {
        MMA7660_READ(&mma7660_xout_reg_addr,
            m_buffer, MMA7660_NUMBER_OF_REGISTERS)
    };
    static app_twi_transaction_t const transaction =
    {
        .callback            = read_mma7660_registers_cb,
        .p_user_data         = NULL,
        .p_transfers         = transfers,
        .number_of_transfers = sizeof(transfers) / sizeof(transfers[0])
    };

    APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));
}


////////////////////////////////////////////////////////////////////////////////
// Buttons handling (by means of BSP).
//
static void bsp_event_handler(bsp_event_t event)
{
    // Each time the button 1 or 4 is pushed we start a transaction reading
    // values of all registers from bme280 or MMA7660 respectively.
    switch (event)
    {
    case BSP_EVENT_KEY_0: // Button 1 pushed.
        read_bme280_registers();
        break;

    case BSP_EVENT_KEY_3: // Button 4 pushed.
        read_mma7660_registers();
        break;

    default:
        break;
    }
}
static void bsp_config(void)
{
    uint32_t err_code;

    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);

    err_code = bsp_init(BSP_INIT_BUTTONS,
                        APP_TIMER_TICKS(100, APP_TIMER_PRESCALER),
                        bsp_event_handler);
    APP_ERROR_CHECK(err_code);
}

// TWI (with transaction manager) initialization.
static void twi_config(void)
{
    uint32_t err_code;

    nrf_drv_twi_config_t const config = {
       .scl                = ARDUINO_SCL_PIN,
       .sda                = ARDUINO_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
       .clear_bus_init     = false
    };

    APP_TWI_INIT(&m_app_twi, &config, MAX_PENDING_TRANSACTIONS, err_code);
    APP_ERROR_CHECK(err_code);
}


// RTC tick events generation.
static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
{
    if (int_type == NRF_DRV_RTC_INT_TICK)
    {
        // On each RTC tick (their frequency is set in "nrf_drv_config.h")
        // we read data from our sensors.
        read_all();
    }
}
static void rtc_config(void)
{
    uint32_t err_code;

    // Initialize RTC instance with default configuration.
    nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
    config.prescaler = RTC_FREQ_TO_PRESCALER(32); //Set RTC frequency to 32Hz
    err_code = nrf_drv_rtc_init(&m_rtc, &config, rtc_handler);
    APP_ERROR_CHECK(err_code);

    // Enable tick event and interrupt.
    nrf_drv_rtc_tick_enable(&m_rtc, true);

    // Power on RTC instance.
    nrf_drv_rtc_enable(&m_rtc);
}


static void lfclk_config(void)
{
    uint32_t err_code;

    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);
}


int main(void)
{
    bsp_board_leds_init();

    // Start internal LFCLK XTAL oscillator - it is needed by BSP to handle
    // buttons with the use of APP_TIMER and for "read_all" ticks generation
    // (by RTC).
    lfclk_config();

    bsp_config();

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_INFO("TWI master example\r\n");
    NRF_LOG_FLUSH();
    twi_config();

    // Initialize sensors.
    APP_ERROR_CHECK(app_twi_perform(&m_app_twi, bme280_init_transfers,
        bme280_INIT_TRANSFER_COUNT, NULL));
    APP_ERROR_CHECK(app_twi_perform(&m_app_twi, mma7660_init_transfers,
        MMA7660_INIT_TRANSFER_COUNT, NULL));

    rtc_config();

    while (true)
    {
        __WFI();
        NRF_LOG_FLUSH();
    }
  • Hi g.joshi,

    I can see that the code was for MMA7660. I don't think it would be related to your BME280. I saw that someone asked about it here. You also need to look into the datasheet of the BME280 to see how it work and what kind of TWI command you need to send to it to understand the Arduino library when you porting it to the nRF52

  • i followed the project and made this code but i am not getting the reading. 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 temperature sensor. */ #define BME280_ADDR (0x76)

    #define BME280_REG_TEMP 0xF7 #define BME280_REG_CONF 0xF5 #define BME280_REG_THYST 0xF3 #define BME280_REG_TOS 0xFE

    /* Mode for BME280. */ #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);

    /* Buffer for samples read from temperature sensor. */ static uint8_t m_sample;

    /**

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

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

      /* Writing to pointer byte. */ reg[0] = BME280_REG_TEMP; m_xfer_done = false; err_code = nrf_drv_twi_tx(&m_twi, BME280_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(uint8_t temp) { NRF_LOG_INFO("Temperature: %d Celsius degrees.\r\n", 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(m_sample); } 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_BME280_config = { .scl = ARDUINO_SCL_PIN, .sda = ARDUINO_SDA_PIN, .frequency = NRF_TWI_FREQ_400K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH, .clear_bus_init = false };

      err_code = nrf_drv_twi_init(&m_twi, &twi_BME280_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;

      /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */ ret_code_t err_code = nrf_drv_twi_rx(&m_twi, BME280_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(); BME280_set_mode();

      while (true) { nrf_delay_ms(500);

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

      } }

    /** @} */

  • We can't help if you simply say it doesn't work and post your code. Please try to find the issue , or at least describe the issue clearly and give us the question. We can give you leads, suggestions, but can't do the job for you.

  • @Hung Bui Sorry for that but i couldn´t find much examples to interface external sensors with nordic board. Well i ´ll try to be more specific next time. Thanks again.

Related