LIS3DH accelrometer data rate

Hi everyone,

First time posting.
I have been using arduino for a few years but now it seems that I am stuck for good.
For this project I use a Nano and the LIS3DH (SPI wiring).
I get the acceleromteter values (x,y,z) by serial print. Baudrate used 2.000.000.
I also transmit the data to another nano using nrf 24, where I also get the values printed to another pc by serial print. That works too.

LIS3DH is capable of 5kHz datarate if low power is enabled.

My problem is that I do get only 250sps besides having set the datarate of LIS3DH to 5kHz.
I want to measure 1kHz frequency which requires at least 2kHz.

I guess that serial print is the probably the problem since it is not fast enough.

What I have tried:

  • Writing to LIS3DH registers. Not sure if successfully.
  • Switched to STM32, ESP32, ESP8266 without any success. All I get is 250sps instead of 5000sps.
  • Read the LIS3DH datasheet again and again.
  • Erased any delays and useless code.
  • Searched and tried everything found on the internet.

I would be happy by only gettinng 2000sps.

Also I have tried storing the measurements to an array and send them afterwards but "memory is not enough" as IDE states while compiling. (Fails to compile).

The code used below is from the library examples with some changes:

I would really appreciate any help or suggestions if someone has experienced the same.

TX Code:

void setup() {
  Serial.begin(2000000);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_2MBPS);
  radio.stopListening();
  LIS.begin(SPI, 10); //CSN
  LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
  LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
  LIS.setHighSolution(true); //High solution enable
  LIS.setPowerMode(POWER_MODE_LOW);
}

void loop() {
  float dataToSend[3];
  dataToSend[0] = LIS.getAccelerationX();
  dataToSend[1] = LIS.getAccelerationY();
  dataToSend[2] = LIS.getAccelerationZ();
  radio.write(&dataToSend, sizeof(dataToSend));

 // Serial.print(x);
 // Serial.print(" ");
// Serial.print(y);
 // Serial.print(" ");
 // Serial.println(z);
  // Serial.println("-");
}

receiver code:


#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8); // CE, CSN
const byte address[6] = "00001";

void setup() {
  Serial.begin(2000000);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_2MBPS);
  radio.startListening();
}

void loop() {

 if (radio.available()) {
 float dataToRcv[3];
 radio.read(&dataToRcv, sizeof(dataToRcv));
 Serial.print(dataToRcv[0]);
 Serial.print(",");
 Serial.print(dataToRcv[1]);
 Serial.print(",");
 Serial.println(dataToRcv[2]);
  }
}

Always study the data sheet carefully. Check the library code, and read out the control registers to see how the accelerometer is actually configured.

It appears that it is not possible to combine high resolution and 5 KHz data rate.

Capture

Hi jremington,

Thank you for noticing that!!
That's indeed true.

On the other hand I have tried all possible "combinations" with no joy!

I have started to realise that the problem is the serial print.

Again thank you for the kind reply.

The library apparently allows you to set impossible configurations, and very likely, is not correctly coded.

To understand what is actually happening, you either need to understand what the library code is doing, or read out the control registers.

The first step in maximizing the overall data transfer rate is to verify that you can simply read out sensible data at the maximum rate. Drop the radio and serial printing, and focus on that effort.

Ok I will focus on that.
A few days ago I tried reading and writing to registers (which I am not familiar with....) and then I quited.
I studied a few other codes and tried to relate them to their library and datasheet in order to figure out how to read and understand what I have to do.

Anyway, thank you so much!
I hope I will figure it out since it's been almost a month trying whatever i can.

By the way, if you want informed help, always post ALL the code and give links to the relevant sources and modules.

I have no idea what LIS3DH device library you are using. Otherwise I would take a look at it.

I have tried a lot of libraries but I chose the LIS3DHTR since I found it easier and the outputs where calibrated out of the box.

LIS3DHTR.h (12.2 KB)

TX CODE:

#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS; 
#include<SPI.h>
#define WIRE Wire
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";

void setup() {
  Serial.begin(2000000);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_2MBPS);
  radio.stopListening();
  LIS.begin(SPI, 10); //CSN

  //  LIS.setFullScaleRange(LIS3DHTR_RANGE_2G);
  //  LIS.setFullScaleRange(LIS3DHTR_RANGE_4G);
   //LIS.setFullScaleRange(LIS3DHTR_RANGE_8G);
  LIS.setFullScaleRange(LIS3DHTR_RANGE_16G);
  //LIS.setOutputDataRate(LIS3DHTR_DATARATE_1_6KH);
 LIS.setOutputDataRate(LIS3DHTR_DATARATE_5KHZ);
  //LIS.setOutputDataRate(LIS3DHTR_DATARATE_400HZ);
  //LIS.setHighSolution(true); //High solution enable

  LIS.setPowerMode(POWER_MODE_LOW);
}
void loop() {
  
  float dataToSend[3];
  dataToSend[0] = LIS.getAccelerationX();
  dataToSend[1] = LIS.getAccelerationY();
  dataToSend[2] = LIS.getAccelerationZ();
  radio.write(&dataToSend, sizeof(dataToSend));

 // Serial.print(x);
 // Serial.print(" ");
// Serial.print(y);
 // Serial.print(" ");
 // Serial.println(z);
 
}

Is this where you found the library? There are others with the same name.

Yes that is right!!
That is the exact same library file by file

That library is a bit of a mess. It clearly does allow you to independently set conflicting device configurations.

The only straightforward operation to retrieve the acceleration data is as floats, which wastes time and doubles the number of data bytes you need to transmit.

The individual data for each axis are 16 bit integers, and nothing is gained by converting them to four byte floats.

I have thought to convert the floats to bits if that makes any sense in regard to transmission speed since I read the data to another pc using a nano.

Besides the number of data I receive is the same both via rf24 and locally to the same pc that the accel is connected via usb.

So I guess the problem is not in the rf24.

I just also noticed that by using usb 3 I get a lot more data with serial print (about 4677) than via usb 2.

The accel is set to 5khz so about 1/5 of what I am supposed to.

Maybe I should start thinking of a faster way to receive data by serial.

I have also tried using at her libs like adafruit with no or worse results.

Since you have more experience on this maybe you have any other considerations.

Thanks again for your support.

Sorry, I can't make much sense of your last post.

I'll repeat: the very first thing you need to do is to verify that it is even possible to read data from the device at 5 kHz, as three 16 bit integers, without sending those data anywhere.

I'm absolutely sure that it is, but possibly not with that device library.

Do you any suggestions on converting data to another format which will allow me to receive them faster?

I already did. Collect the raw, integer data, and send those.

Crystal clear!
Thank you.
I will see what I can do.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.