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

nrf52 TWI communication with LIS3DH

Hi,
I've been recently working on trying to stablish an i2c (twi) communication between my nrf52 Dev kit and a LIS3DH located in a STEVAL-IDI-003V2 board.

In this post https://devzone.nordicsemi.com/f/nordic-q-a/34710/lis2dh12-driver-issue-in-nrf-sdk-v15-0 @lhochstetter shared a successful code (thank you!).

/**
 * Copyright (c) 2015 - 2018, 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"


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

#include "lis2dh12.h"

#include "nrf_twi_mngr.h"

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

#define MAX_PENDING_TRANSACTIONS    33

#define LIS2DH12_MIN_QUEUE_SIZE     32

NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

NRF_TWI_SENSOR_DEF(m_nrf_twi_sensor, &m_nrf_twi_mngr, LIS2DH12_MIN_QUEUE_SIZE);

LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);

static uint8_t m_sample = 0;

void print_identity(ret_code_t r, void *p_register_data)
{
    NRF_LOG_INFO("Identity: %d", *((uint8_t *)p_register_data));
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    uint32_t err;

    nrf_drv_twi_config_t const config = {
       .scl                = 27,
       .sda                = 26,
       .frequency          = NRF_DRV_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
       .clear_bus_init     = false
    };


    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("TWI sensor example started.");
    NRF_LOG_FLUSH();

    err = nrf_twi_mngr_init(&m_nrf_twi_mngr, &config);
    APP_ERROR_CHECK(err);

    err = nrf_twi_sensor_init(&m_nrf_twi_sensor);
    APP_ERROR_CHECK(err);

    err = lis2dh12_init(&m_lis2dh12);
    APP_ERROR_CHECK(err);

    NRF_LOG_INFO("Here.");
    NRF_LOG_FLUSH();
    APP_ERROR_CHECK(err);

    while (true)
    {
        nrf_delay_ms(500);
        err = lis2dh12_who_am_i_read(&m_lis2dh12, print_identity, &m_sample);
        APP_ERROR_CHECK(err);
        NRF_LOG_FLUSH();
    }
}

/** @} */

Right now, for me the code compiles without any errors and when loaded to the board, I get

<info> app: Identity: 0

on a PuTTY terminal.

I guess I should see the value 33, as it is the default value stored on the 0x0F WHO_AM_I register of the sensor. Am I right?
Using a osciloscope I see that the communication sequence is: [ Start - 0x19 WR - NAK - Stop ]. The 0x19 register is the first register the master writes to. In lis2dh12.h there appears 

#define LIS2DH12_BASE_ADDRESS_LOW 0x18U 
#define LIS2DH12_BASE_ADDRESS_HIGH 0x19U

Looking at both lis2dh12 and lis3dh datasheets the registers are almost the same, and I know the 0x19U is the default address configured in the lis3dh driver. Looking at the sequence, 0x19 WR seems logical. The thing is I am not getting a response from the sensor, therefore it's no surprise to see the "Identity: 0" message on PuTTY.

I am using the lis2dh12 library but the lis3dh sensor. This may seem a problem but I can't see why it wouldn't work, as the registers that I am addressing are the same I would be addressing if I was using a lis2dh12 sensor. 

Previously I tested another STEVAL-IDI003V2 sensor and I got some weird values from the sensor, but there was an existing communication between the board and the sensor. I haven't changed the wiring.

Do you think I've made a mistake using the lis2dh12 library? If so, why? Is there anything else I can check/do to solve my problem? May the sensor be damaged? 

Thank you in advance,

LFanals

  • After a bit of testing I discovered that instead of

    LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_HIGH);

    I should have 

    LIS2DH12_INSTANCE_DEF(m_lis2dh12, &m_nrf_twi_sensor, LIS2DH12_BASE_ADDRESS_LOW);

    As the lis2dh12 or lis3dh datasheets explain on the I2C operation, the adress are 7 bits long and the LSB can either be 1 or 0 depending on how is a pin connected, making the address value equal 19 or 18. In my case, 18 was the right choice. 

    I apologize for the noobie mistake I've made, and I'm gonna keep updating the progress I make.

    LFanals

  • Glad to hear you figured out the issue yourself! Slight smile

    -Øyvind

  • Hi,

    can you please explain how do you got this project to work? I've copied your code in main.c of the twi_sensor example, included all *.h header files in projects properties and added the *.c files in projects explorer. After saving and reloading the project I got this errors:


        Output/Release/Exe/twi_sensor_pca10040.elf section `.nrf_queue' will not fit in region `UNPLACED_SECTIONS'
        region `UNPLACED_SECTIONS' overflowed by 20 bytes
        Output/twi_sensor_pca10040 Release/Obj/nrf_twi_sensor.o: in function `nrf_twi_sensor_reg_read':
        undefined reference to `nrf_twi_mngr_schedule'
        Output/twi_sensor_pca10040 Release/Obj/nrf_twi_sensor.o: in function `nrf_twi_sensor_write':
        undefined reference to `nrf_twi_mngr_schedule'
        Output/twi_sensor_pca10040 Release/Obj/main.o: in function `main':
        undefined reference to `nrf_twi_mngr_init'
    Build failed

    Thank you in advance,

    Hannes

  • Hi Seihan,

    The first error suggests me that there is a problem with memory allocation. 

    Now some questions arise:

    - Are you using some kind of BLE communication, or is SoftDevide needed? If so I would suggest to manually allocate enough space. There are some threads that explain it better than me. Right now my configuration of a code that uses BLE looks like this. I am using Segger, in case you use Keil or other softwares menus change but you can configure it as well.

    Then, in Segger at least, you should see some bars as these

    If your project is huge you may need more memory than the quantity you have available, yet I don't thing it's the case.

    - If you aren't using SoftDevice or what I've previously said doesn't work, try to copy paste my code and include all the libraries needed. It worked for me this way, and I don't remember configurating memory space.

    I'm not sure that solves your problem, but I hope it works.

  • Thank you for your help.

    Finally I solved it by using GCC. The problem with undefined references was somewhere inside the sdk_config.h, I copied one from the twi_master example. The UNPLACED SECTIONS error was only inside SES.

Related