0

H3LIS331 Not Fast Enough?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

H3LIS331 Not Fast Enough?

by BKroessler on Mon May 17, 2021 8:29 am

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 | TOGGLE FULL SIZE
#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 597 times

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Mon May 17, 2021 8:43 am

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.

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

by BKroessler on Mon May 17, 2021 8:59 am

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?

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Mon May 17, 2021 9:12 am

Code: Select all | TOGGLE FULL SIZE
      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.

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

by BKroessler on Wed May 26, 2021 12:17 pm

adafruit_support_bill wrote:
Code: Select all | TOGGLE FULL SIZE
      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.

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Wed May 26, 2021 12:29 pm

Post the code you have so far.

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

by BKroessler on Wed May 26, 2021 4:09 pm

Code: Select all | TOGGLE FULL SIZE
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.

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Wed May 26, 2021 4:19 pm

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.

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

by BKroessler on Wed May 26, 2021 4:27 pm

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.

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

Re: H3LIS331 Not Fast Enough?

by BKroessler on Tue Jun 01, 2021 12:06 pm

Code: Select all | TOGGLE FULL SIZE
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?

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Tue Jun 01, 2021 12:16 pm

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.

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Re: H3LIS331 Not Fast Enough?

by BKroessler on Wed Jun 02, 2021 8:17 am

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!

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

Re: H3LIS331 Not Fast Enough?

by adafruit_support_bill on Wed Jun 02, 2021 8:24 am

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

adafruit_support_bill
 
Posts: 81566
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.


cron