H3LIS331 Not Fast Enough?

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

H3LIS331 Not Fast Enough?

Post by BKroessler »

I recently built a Drop Test rig for a project I am working on, and have been having a bit of a hard time benchmarking it with the H3LIS331. Currently I have it set up to only test in the Z-dimension; it starts recording for 1500ms when I push a button, drop the anvil, and it usually stops recording once the anvil stops bouncing.

I've noticed that two tests with the exact same parameters have a huge difference of about 100g, which is well beyond the margin of error. Since I am testing a limited amount of prototypes, I can't afford to have bad data on any of them. The chart of results is attached; ideally the red and the yellow lines should be equal in height.

Below is my code.

Code: Select all

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_H3LIS331.h>
#include <Adafruit_Sensor.h>

// Used for software SPI
#define H3LIS331_SCK 13
#define H3LIS331_MISO 12
#define H3LIS331_MOSI 11
// Used for hardware & software SPI
#define H3LIS331_CS 10


Adafruit_H3LIS331 lis = Adafruit_H3LIS331();

const int buttonPin = 13;     // the number of the pushbutton pin
const int ledVin = 10;
const int ledPin = 9;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  Serial.begin(230400);
  while (!Serial) delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("H3LIS331 test!");

  //  if (!lis.begin_SPI(H3LIS331_CS)) {
  //  if (!lis.begin_SPI(H3LIS331_CS, H3LIS331_SCK, H3LIS331_MISO, H3LIS331_MOSI)) {
  if (! lis.begin_I2C()) {   // change this to 0x19 for alternative i2c address
    Serial.println("Couldnt start");
    while (1) yield();
  }
  Serial.println("H3LIS331 found!");

  lis.setRange(H3LIS331_RANGE_400_G);   // 100, 200, or 400 G!
  Serial.print("Range set to: ");
  switch (lis.getRange()) {
    case H3LIS331_RANGE_100_G: Serial.println("100 g"); break;
    case H3LIS331_RANGE_200_G: Serial.println("200 g"); break;
    case H3LIS331_RANGE_400_G: Serial.println("400 g"); break;
  }
  lis.setDataRate(LIS331_DATARATE_1000_HZ);
  Serial.print("Data rate set to: ");
  switch (lis.getDataRate()) {

    case LIS331_DATARATE_POWERDOWN: Serial.println("Powered Down"); break;
    case LIS331_DATARATE_50_HZ: Serial.println("50 Hz"); break;
    case LIS331_DATARATE_100_HZ: Serial.println("100 Hz"); break;
    case LIS331_DATARATE_400_HZ: Serial.println("400 Hz"); break;
    case LIS331_DATARATE_1000_HZ: Serial.println("1000 Hz"); break;
    case LIS331_DATARATE_LOWPOWER_0_5_HZ: Serial.println("0.5 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_1_HZ: Serial.println("1 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_2_HZ: Serial.println("2 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_5_HZ: Serial.println("5 Hz Low Power"); break;
    case LIS331_DATARATE_LOWPOWER_10_HZ: Serial.println("10 Hz Low Power"); break;

      pinMode(ledPin, OUTPUT);
      pinMode(buttonPin, INPUT);
      pinMode(ledVin, OUTPUT);
      digitalWrite(ledVin, HIGH);
  }
}


void loop() {
  buttonState = digitalRead(buttonPin);
  unsigned long start_time = millis();

  if (buttonState == LOW) {
    Serial.println("testStart");
    int lastmillis = 0;
    int i = 0;
    lastmillis = millis();

      do{
      digitalWrite(ledPin, HIGH);
      sensors_event_t event;
      lis.getEvent(&event);
      //Serial.print(i); Serial.print(","); Serial.print("\t");
      Serial.println(event.acceleration.z / SENSORS_GRAVITY_STANDARD);
    }
        while ((millis() - start_time) < 1500); {

    // 1500ms have passed
    
      Serial.println("COMPLETE");
      digitalWrite(ledPin, LOW);
      delay(1000);
    }
    //delay(0);
  }
}
Attachments
dp1u2_dropTestResults.png
dp1u2_dropTestResults.png (34.27 KiB) Viewed 756 times

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

I'd start by removing all non-essential code from your sampling loop. Collect the data to an array in memory and print it out when you are done.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

adafruit_support_bill wrote:I'd start by removing all non-essential code from your sampling loop. Collect the data to an array in memory and print it out when you are done.
That makes sense. Outside of Serial.print what else could be removed from the sampling loop?

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

Code: Select all

      do{
      digitalWrite(ledPin, HIGH);
      sensors_event_t event;
      lis.getEvent(&event);
      //Serial.print(i); Serial.print(","); Serial.print("\t");
      Serial.println(event.acceleration.z / SENSORS_GRAVITY_STANDARD);
    }
The digitalWrite to turn the LED on does not need to be repeated. Move it before the loop.
You also don't need to re-construct the sensors_event every time. I'd move the declaration outside the loop as well.
If you declare an array of events external to the loop, then you can just call getEvent with an increasing index into that array.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

adafruit_support_bill wrote:

Code: Select all

      do{
      digitalWrite(ledPin, HIGH);
      sensors_event_t event;
      lis.getEvent(&event);
      //Serial.print(i); Serial.print(","); Serial.print("\t");
      Serial.println(event.acceleration.z / SENSORS_GRAVITY_STANDARD);
    }
The digitalWrite to turn the LED on does not need to be repeated. Move it before the loop.
You also don't need to re-construct the sensors_event every time. I'd move the declaration outside the loop as well.
If you declare an array of events external to the loop, then you can just call getEvent with an increasing index into that array.
Moved everything I could out of the do loop, still only getting about half as many readings as I require. Moving both the sensors_event and declaration gives me three times the amount of readings I need, but only reads the Accelerometer at the instant the button was pressed, so every reading is the same.

Will attempt the array method.

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

Post the code you have so far.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

Code: Select all

void loop() {
  buttonState = digitalRead(buttonPin);
  unsigned long start_time = millis();



  if (buttonState == LOW) {
    Serial.println("testStart");
    int lastmillis = 0;

    lastmillis = millis();

    sensors_event_t event;

    do {
      lis.getEvent(&event);   //need this to actually read the sensor
      Serial.println(event.acceleration.z / SENSORS_GRAVITY_STANDARD);
    delay(1);
    }

    while ((millis() - start_time) < 1500); {

      // 1500ms have passed


    }
    Serial.println("COMPLETE");
    delay(1000);
  }
}
I also tried skipping the divide by gravity standard but that didn't help, and I took the LED out as it had died and didn't really help the testing procedure.

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

You are still printing the data via the serial port from within the do/while loop. Collect the data to an array in memory and print it out when you are done.

You also have a delay(1); statement within your do/while loop. That only slow things down more.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

adafruit_support_bill wrote:You are still printing the data via the serial port from within the do/while loop. Collect the data to an array in memory and print it out when you are done.

You also have a delay(1); statement within your do/while loop. That only slow things down more.
Ah yes, meant to delete that, just wanted to see what it would do. Will give the array a go.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

Code: Select all

void loop() {
  buttonState = digitalRead(buttonPin);
  int i = 0;

  if (buttonState == LOW) {
    Serial.println("testStart");
    sensors_event_t event;

    for (i = 0; i < dC; i++) { //dataCount 1500 points
      lis.getEvent (&event);
      Z[zI] = {event.acceleration.z / SENSORS_GRAVITY_STANDARD}; 
      zI++; 
    }


    if (zI > dC) { //reset the array index
      zI = 0;
    }

    int i = 0;
    for (int i = 0; i < dC; i++)
    {
      Serial.println(Z[i]);
    }
    Serial.println("testComplete");
    zI = 0;
    i = 0;
    delay(1000);
  }
}
Okay, after spending the afternoon fighting with arrays I *think* I have solved it. It records then spits out 1500 readings, just as I required. As to how accurate it is I will have to continue to test, but this will help get me closer to the goal.

Am I missing anything?

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

That looks like it should work. You could probably improve speed a little bit more by saving just the raw value and performing the division as you print out the results.

User avatar
BKroessler
 
Posts: 8
Joined: Mon May 17, 2021 8:22 am

Re: H3LIS331 Not Fast Enough?

Post by BKroessler »

adafruit_support_bill wrote:That looks like it should work. You could probably improve speed a little bit more by saving just the raw value and performing the division as you print out the results.
Did four tests and each impact has 5-6 datapoints, just where I need it! Will still need to benchmark a bit more to make sure everything's working as it should, as the final test broke my test helmet.

Thank you for your assistance. This was a great learning experience!

User avatar
adafruit_support_bill
 
Posts: 88092
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

Post by adafruit_support_bill »

Good to hear that worked for you. Thanks for the follow-up.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”