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

Get X,Y,Z values from LIS3DH using nrf52 development board

Hi!

I am trying to interface LIS3DH module (https://www.adafruit.com/product/2809) with nRF52 DK, SDK 11, via i2c/spi. I tested on Arduino UNO & it gave x,y,z values. So, I decided to write nrf driver for LIS3DH using Adafruit LIS3DH driver(https://github.com/adafruit/Adafruit_LIS3DH/) but I am getting errors like i2c begin & how/what to write to control registers to read data again.

Please suggest me how to write driver or if general LIS3DH driver is available then reply ASAP.

LIS3DH.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <LIS3DH.h>
#include "nrf_drv_twi.h"
#include "nrf_delay.h"
/** Sensor types */
typedef enum
{
SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
SENSOR_TYPE_MAGNETIC_FIELD = (2),
SENSOR_TYPE_ORIENTATION = (3),
SENSOR_TYPE_GYROSCOPE = (4),
SENSOR_TYPE_LIGHT = (5),
SENSOR_TYPE_PRESSURE = (6),
SENSOR_TYPE_PROXIMITY = (8),
SENSOR_TYPE_GRAVITY = (9),
SENSOR_TYPE_LINEAR_ACCELERATION = (10), /**< Acceleration not including gravity */
SENSOR_TYPE_ROTATION_VECTOR = (11),
SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Parents
  • Hello,

    I think you should be able to find a driver for the LIS3DH in a couple of cases here on DevZone. However, we have a driver that is included in a separate SDK. However, this SDK is not open source, but I can give you the driver. See if you can use this one.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /* Copyright (c) 2016 Nordic Semiconductor. All Rights Reserved.
    *
    * The information contained herein is property of Nordic Semiconductor ASA.
    * Terms and conditions of usage are described in detail in NORDIC
    * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
    *
    * Licensees are granted free, non-transferable use of the information. NO
    * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
    * the file.
    *
    */
    #include <string.h>
    #ifndef __ICCARM__
    #include <alloca.h>
    #endif
    #include "nordic_common.h"
    #include "nrf.h"
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    drv_acc_lis3dh.h

     

    Best regards,

    Edvin

  • Please reply with the function to call for X,Y,Z values from main.c ?

  • I don't have any sensor to test this on. Maybe someone else in this forum has done this before, and can help you.

    See if you e.g. can use something from this case:

     

    BR,

    Edvin

  • I may have a setting or two wrong in my project, but it looks like this driver file relies on a few other files (bolded in the #include statements below) that are not in the v15 SDK. Also, is there any example code available that utilizes this driver?


    #ifndef __ICCARM__
    // #include <alloca.h>
    #endif

    #include "nordic_common.h"
    #include "nrf.h"
    #include "nrf_assert.h"
    #include "nrf_error.h"
    #include "nrf_delay.h"
    // #include "app_debug.h"
    #include "app_error.h"
    #include "app_gpiote.h"
    // #include "app_twi.h"

    #include "drv_acc_lis3dh.h"
    // #include "drv_acc.h"

    // #include "resources.h"
    // #include "twi_common.h"
    // #include "sr3_config.h"

  • I did this uncomment & driver code compiled successfully but how I can read X,Y,Z values there's no such function in the driver? 

    I tried calling this function but it's not working:

    lis3dh_read_regs();

Reply
  • I did this uncomment & driver code compiled successfully but how I can read X,Y,Z values there's no such function in the driver? 

    I tried calling this function but it's not working:

    lis3dh_read_regs();

Children
  • I see that the projects where the driver is used, it only uses the LIS3DH to wake up the chip from sleep, so maybe the drivers that you initially found would be a better approach.

     

    Can you please specify what kind of issues you see when you try to use it? You say: " I am getting errors like i2c begin". What do you mean by that?

     

    Best regards,

    Edvin

     

  • So, this (drv_acc_lis3dh.c) will only wake-up LIS3DH. I am not getting any error while compiling your files but I can't find any function to read X,Y,Z values defined in drv_acc_lis3dh.h file:

    typedef struct
    {
    int16_t AXIS_X;
    int16_t AXIS_Y;
    int16_t AXIS_Z;
    } AccAxesRaw_t;

    Is driver incomplete? Please suggest me how to read the registers for LIS3DH data like here below:

    static uint8_t mosiBuf [2];
    static uint8_t misoBuf [2];
    void writeLisReg(uint8_t subAddr, uint8_t value)
    {
    uint32_t err_code;
    while(spi_master_get_state(SPI_MASTER_0) != SPI_MASTER_STATE_IDLE);
    mosiBuf[0] = subAddr & ~0xc0;
    mosiBuf[1] = value;
    err_code = spi_master_send_recv(SPI_MASTER_0, mosiBuf, 2, misoBuf,2);
    APP_ERROR_CHECK(err_code);
    }

    uint8_t readLisReg(uint8_t subAddr)
    {
    uint32_t err_code;
    while(spi_master_get_state(SPI_MASTER_0) != SPI_MASTER_STATE_IDLE);
    mosiBuf[0] = subAddr | 0x80;
    mosiBuf[1] = 0;
    misoBuf[0] = 0x55;
    misoBuf[1] = 0xAA;
    err_code = spi_master_send_recv(SPI_MASTER_0, mosiBuf, 2, misoBuf,2);
    APP_ERROR_CHECK(err_code);
    while(spi_master_get_state(SPI_MASTER_0) != SPI_MASTER_STATE_IDLE);
    return misoBuf[1];
    }

    void init_lis3dh() {
    writeLisReg(LIS3DH_CTRL_REG1, 0x57); //All axes, normal, 100Hz
    writeLisReg(LIS3DH_CTRL_REG2, 0x00); // No HighPass filter
    writeLisReg(LIS3DH_CTRL_REG3, 0x00); // No interrupts
    writeLisReg(LIS3DH_CTRL_REG4, 0x0); // all defaults
    writeLisReg(LIS3DH_CTRL_REG5, 0x0); // all defaults
    writeLisReg(LIS3DH_CTRL_REG6, 0x0); // all defaults
    }

    void readLisData()
    {
    int16_t x,y,z;
    double dx, dy, dz;
    while(readLisReg(LIS3DH_STATUS_REG) & 0x8 == 0 );
    x = readLisReg(LIS3DH_OUT_X_H) * 256 + readLisReg(LIS3DH_OUT_X_L);
    y = readLisReg(LIS3DH_OUT_Y_H) * 256 + readLisReg(LIS3DH_OUT_Y_L);
    z = readLisReg(LIS3DH_OUT_Z_H) * 256 + readLisReg(LIS3DH_OUT_Z_L);
    dx = x/16384.0;
    dy = y/16384.0;
    dz = z/16384.0;
    printf("X: %f; Y: %f; Z: %f; SUM: %f\n\r", dx , dy, dz, sqrt(dx*dx + dy*dy + dz*dz));
    }

    This is SPI example found here: https://github.com/elmot/nRF51822xxAA-LIS3DH/blob/master/main.c but I need data via i2c communication

  • No. This driver does not have a function called "readXYZ()". 

     

    The example that you found on Github. Have you tested it? It seems like this example receives data from the LIS3DH, like you are looking for. I assume you can use the driver that I sent for the readLisReg() and WriteLisReg(). That is, change them to lis3dh_read_regs() and lis3dh_write_regs().

     

    BR,
    Edvin

  • status = lis3dh_read_regs(slave_reg, &contents, 1);

    Shall I call like this?

  • What is your slave_reg 

    First of all, you need to init the lis3dh, using the same method as in the github example. Then I suggest you check out how the lis3dh_read_regs() sets up the app_twi_transfer_t structure, and make sure that you get the same when you call.

     

    Like you see in the init function of the github project that you linked to, you need to write to several registers at the lis3dh to initialize it properly. 

     

    I suggest you start with looking into the TWI (same as I2C) example in the SDK\examples\peripheral\spim and get familiar with I2C. Then you can try to write to the sensor, and see what you get in return.

     

    Best regards,

    Edvin