self test
This commit is contained in:
parent
898a0f7ee2
commit
7466b91fe3
@ -35,9 +35,6 @@ The LIS3DH can apply its built-in high-pass filter to samples [regular reading,
|
||||
|
||||
See files: `filter-normal.c`, and `filter-reference.c`.
|
||||
|
||||
### file: simple.c
|
||||
Basic example of how to use this device
|
||||
|
||||
# FIFO
|
||||
Instead of polling for every single [x y z] set, a FIFO with programmable capacity ("watermark") can be used, and then dumped into memory once full.
|
||||
|
||||
@ -59,6 +56,10 @@ Note: FIFO will not trigger a watermark interrupt (`pin1.wtm`) if the FIFO size
|
||||
|
||||
Note: to sample data faster than 200 Hz, it is necessary to use the regular data polling functionality using `lis3dh_read()` with the appropriate configuration. See files `simple.c` and `fast.c` for examples.
|
||||
|
||||
### file: self-test.c
|
||||
|
||||
Run a device self-test to see if the device is within spec. Mine apparently isn't. (must be at-rest during test).
|
||||
|
||||
### file: single-click.c
|
||||
|
||||
Set up single-click detection (no latching interrupt possible)
|
||||
|
103
example/self-test.c
Normal file
103
example/self-test.c
Normal file
@ -0,0 +1,103 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h> /* usleep() */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lis3dh.h"
|
||||
#include "i2c.h"
|
||||
|
||||
/* table 4 of datasheet */
|
||||
#define ST_MIN 17
|
||||
#define ST_MAX 360
|
||||
|
||||
/* AN3308 suggests 5 */
|
||||
#define ITERATIONS 5
|
||||
|
||||
int main() {
|
||||
|
||||
lis3dh_t lis;
|
||||
int32_t x_nost, y_nost, z_nost; /* store avg of measurements before self-test */
|
||||
int32_t x_st, y_st, z_st; /* store avg of self-test measurements */
|
||||
int32_t xd, yd, zd; /* differences */
|
||||
int i;
|
||||
|
||||
lis.dev.init = i2c_init;
|
||||
lis.dev.read = i2c_read;
|
||||
lis.dev.write = i2c_write;
|
||||
lis.dev.sleep = usleep;
|
||||
lis.dev.deinit = i2c_deinit;
|
||||
|
||||
x_nost = y_nost = z_nost = 0;
|
||||
x_st = y_st = z_st = 0;
|
||||
xd = yd = zd = 0;
|
||||
|
||||
/* initialise LIS3DH struct */
|
||||
if (lis3dh_init(&lis)) {
|
||||
/* error handling */
|
||||
}
|
||||
|
||||
/* reset device just in case */
|
||||
if (lis3dh_reset(&lis)) {
|
||||
/* error handling */
|
||||
}
|
||||
|
||||
lis.cfg.mode = LIS3DH_MODE_NORMAL;
|
||||
lis.cfg.range = LIS3DH_FS_2G;
|
||||
lis.cfg.rate = LIS3DH_ODR_50_HZ;
|
||||
|
||||
lis3dh_configure(&lis);
|
||||
|
||||
/* discard first couple of samples as datasheet suggests they are wrong/noisy */
|
||||
for(i=0; i<15; i++) lis3dh_read(&lis);
|
||||
|
||||
for(i=0; i<ITERATIONS; i++) {
|
||||
lis3dh_read(&lis);
|
||||
x_nost += lis.acc.x;
|
||||
y_nost += lis.acc.y;
|
||||
z_nost += lis.acc.z;
|
||||
}
|
||||
|
||||
x_nost /= ITERATIONS;
|
||||
y_nost /= ITERATIONS;
|
||||
z_nost /= ITERATIONS;
|
||||
|
||||
lis.cfg.self_test = LIS3DH_SELF_TEST_0;
|
||||
|
||||
lis3dh_configure(&lis);
|
||||
|
||||
/* discard first couple of samples as datasheet suggests they are wrong/noisy */
|
||||
for(i=0; i<15; i++) lis3dh_read(&lis);
|
||||
|
||||
|
||||
for(i=0; i<ITERATIONS; i++) {
|
||||
lis3dh_read(&lis);
|
||||
x_st += lis.acc.x;
|
||||
y_st += lis.acc.y;
|
||||
z_st += lis.acc.z;
|
||||
}
|
||||
|
||||
x_st /= ITERATIONS;
|
||||
y_st /= ITERATIONS;
|
||||
z_st /= ITERATIONS;
|
||||
|
||||
xd = abs(x_st - x_nost);
|
||||
yd = abs(y_st - y_nost);
|
||||
zd = abs(z_st - z_nost);
|
||||
|
||||
printf("variance min=%d, max=%d\n", ST_MIN, ST_MAX);
|
||||
printf("xd=%d yd=%d zd=%d\n", xd, yd, zd);
|
||||
|
||||
if ((ST_MIN <= xd && xd <= ST_MAX) && (ST_MIN <= yd && yd <= ST_MAX) && (ST_MIN <= zd && zd <= ST_MAX)) {
|
||||
puts("Pass");
|
||||
} else {
|
||||
puts("Fail");
|
||||
}
|
||||
|
||||
lis3dh_reset(&lis);
|
||||
|
||||
/* deinitalise struct */
|
||||
if (lis3dh_deinit(&lis)) {
|
||||
/* error handling */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
5
lis3dh.c
5
lis3dh.c
@ -57,7 +57,7 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
||||
ctrl_reg1 = (lis3dh->cfg.rate << 4) | 0x07;
|
||||
ctrl_reg2 = 0;
|
||||
ctrl_reg3 = 0;
|
||||
ctrl_reg4 = (lis3dh->cfg.range << 4);
|
||||
ctrl_reg4 = (lis3dh->cfg.range << 4) | (lis3dh->cfg.spi3w & 1);
|
||||
ctrl_reg5 = 0;
|
||||
ctrl_reg6 = 0;
|
||||
fifo_ctrl_reg = 0;
|
||||
@ -74,6 +74,9 @@ int lis3dh_configure(lis3dh_t *lis3dh) {
|
||||
ctrl_reg0 = 0;
|
||||
temp_cfg_reg = 0;
|
||||
|
||||
/* set self-test bits */
|
||||
ctrl_reg4 |= (lis3dh->cfg.self_test & 0x03) << 1;
|
||||
|
||||
/* determine whether to enable ADC or TEMP sensor */
|
||||
temp_cfg_reg |= (lis3dh->cfg.en_adc & 1) << 7;
|
||||
temp_cfg_reg |= (lis3dh->cfg.en_temp & 1) << 6;
|
||||
|
8
lis3dh.h
8
lis3dh.h
@ -112,6 +112,10 @@
|
||||
#define LIS3DH_FILTER_CUTOFF_2 0x02
|
||||
#define LIS3DH_FILTER_CUTOFF_1 0x03 /* lowest freq */
|
||||
|
||||
/* Positive and negative axis self-test */
|
||||
#define LIS3DH_SELF_TEST_0 0x01
|
||||
#define LIS3DH_SELF_TEST_1 0x02
|
||||
|
||||
|
||||
/* Note: IA{1,2} is interrupt activity {1,2} or interrupt generators */
|
||||
/* user provided functions, init and deinit can be set to NULL and won't be used */
|
||||
@ -226,6 +230,8 @@ struct lis3dh_config {
|
||||
* - time_window
|
||||
* - time_latency
|
||||
* used in CLICK)
|
||||
*
|
||||
* this is the "1[LSb]" in act_dur calc
|
||||
*/
|
||||
uint8_t int1_dur; /* 7-bit INT 1 duration value */
|
||||
uint8_t int2_dur; /* 7-bit INT 2 duration value */
|
||||
@ -242,6 +248,8 @@ struct lis3dh_config {
|
||||
uint8_t sdo_pullup; /* Use pull-up on SDO. default 0 use */
|
||||
uint8_t en_adc; /* enable ADC */
|
||||
uint8_t en_temp; /* enable temp sensor on ADC 3 */
|
||||
uint8_t spi3w; /* set to 1 to enable 3-way SPI, default 0 */
|
||||
uint8_t self_test; /* set self-test mode */
|
||||
|
||||
uint8_t reference; /* HP filter reference */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user