Compare commits

..

2 Commits

Author SHA1 Message Date
898a0f7ee2 Filter example + README 2024-01-07 18:11:24 +00:00
f5e6e346cf update filter mode 2024-01-07 17:54:56 +00:00
11 changed files with 172 additions and 22 deletions

View File

@ -75,7 +75,7 @@ int main() {
lis.cfg.int1.latch = 1;
/* set up a HP filter to ignore constant earth acceleration */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.ia1 = 1; /* enable filter for INT1 generator */

View File

@ -75,7 +75,7 @@ int main() {
lis.cfg.int1.latch = 1;
/* set up a HP filter to ignore constant earth acceleration */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.ia1 = 1; /* enable filter for INT1 generator */

View File

@ -76,7 +76,7 @@ int main() {
lis.cfg.int1.latch = 1;
/* set up a HP filter to ignore constant earth acceleration */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.ia1 = 1; /* enable filter for INT1 generator */

View File

@ -76,7 +76,7 @@ int main() {
lis.cfg.int1.latch = 1;
/* set up a HP filter to ignore constant earth acceleration */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.ia1 = 1; /* enable filter for INT1 generator */

View File

@ -1,5 +1,6 @@
# lis3dh/example
## Operating mode
The LIS3DH has 3 operating modes.
| mode | symbol | description |
|------|---------|------------|
@ -7,6 +8,7 @@ The LIS3DH has 3 operating modes.
| Normal | `LIS3DH_MODE_NORMAL` | "Normal" mode. 10-bit acc. reading resolution. |
| HR | `LIS3DH_MODE_HR` | High-resolution mode. 12-bit acc. reading resolution. |
## ODR
There are serveral `ODR` (internal data/sample rate) options, but some may only be used in a specific operating mode.
| ODR | mode | symbol |
|-----|------|--------|
@ -21,6 +23,18 @@ There are serveral `ODR` (internal data/sample rate) options, but some may only
| 1600 Hz | LP | `LIS3DH_ODR_LP_1600_HZ` |
| 5376 Hz | LP | `LIS3DH_ODR_LP_5376_HZ` |
## Filter
The LIS3DH can apply its built-in high-pass filter to samples [regular reading, FIFO reading] and some specific user-functions. It has 3 different modes.
| mode | symbol | description |
|------|--------|-------------|
| Normal | `LIS3DH_FILTER_MODE_NORMAL` | Use `lis3dh_reference()` to set the filter to the current accel field, without having to wait for it to settle at/near it. |
| Autoreset | `LIS3DH_FILTER_MODE_AUTORESET` | Same as `normal` but this mode also automatically resets itself upon an interrupt(*). |
| REFERENCE | `LIS3DH_FILTER_MODE_REFERENCE` | Output data is calculated as the difference between `cfg.reference` and the measured acceleration. |
\* INT by the generator which the filter is programmed to apply itself to.
See files: `filter-normal.c`, and `filter-reference.c`.
### file: simple.c
Basic example of how to use this device

View File

@ -52,7 +52,7 @@ int main() {
lis.cfg.range = LIS3DH_FS_2G;
lis.cfg.rate = LIS3DH_ODR_400_HZ; /* minimum recommended ODR */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.click = 1; /* enable filtering for CLICK function */

63
example/filter-normal.c Normal file
View File

@ -0,0 +1,63 @@
#define _GNU_SOURCE
#include <unistd.h> /* usleep() */
#include <stdio.h>
#include "lis3dh.h"
#include "i2c.h"
int main() {
lis3dh_t lis;
lis.dev.init = i2c_init;
lis.dev.read = i2c_read;
lis.dev.write = i2c_write;
lis.dev.sleep = usleep;
lis.dev.deinit = i2c_deinit;
/* 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_HR;
lis.cfg.range = LIS3DH_FS_2G;
lis.cfg.rate = LIS3DH_ODR_100_HZ;
/* normal mode */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
/* 3dB cutoff freq (~ ODR) */
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
/* write config to device */
if (lis3dh_configure(&lis)) {
/* error handling */
}
/* read REFERENCE to set filter to current accel field */
if (lis3dh_reference(&lis)) {
/* error handling */
}
for ( ;; ) {
/* read an [x y z] accel set. Filter is applied */
if (lis3dh_read(&lis)) {
/* error handling */
}
printf("x: %4.d, y: %4.d, z: %4.d\n", lis.acc.x, lis.acc.y, lis.acc.z);
usleep(5000); /* 5 ms */
}
/* deinitalise struct */
if (lis3dh_deinit(&lis)) {
/* error handling */
}
return 0;
}

View File

@ -0,0 +1,73 @@
#define _GNU_SOURCE
#include <unistd.h> /* usleep() */
#include <stdio.h>
#include "lis3dh.h"
#include "i2c.h"
int main() {
lis3dh_t lis;
lis.dev.init = i2c_init;
lis.dev.read = i2c_read;
lis.dev.write = i2c_write;
lis.dev.sleep = usleep;
lis.dev.deinit = i2c_deinit;
/* 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_HR;
lis.cfg.range = LIS3DH_FS_2G;
lis.cfg.rate = LIS3DH_ODR_100_HZ;
/* normal mode */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_REFERENCE;
/* 3dB cutoff freq (~ ODR) */
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
/* Output [x y z] data is calculated as the difference between the
* measured acceleration and the value stored in REFERENCE.
* signed 7-bit int, 1 LSb value depends on FS.
* FS_2G: ~ 16mg per 1 LSb
* FS_4G: ~ 31mg per 1 LSb
* FS_8G: ~ 63mg per 1 LSb
* FS_16G: ~127mg per 1 LSb */
/* @ 2G,
* To have the output data be referenced to 0.8g:
* => 800 mg / 16 mg = 50 */
/* to reference -0.8g simply put -50 */
lis.cfg.reference = 50;
/* write config to device */
if (lis3dh_configure(&lis)) {
/* error handling */
}
/* Do not read REFERENCE */
for ( ;; ) {
/* read an [x y z] accel set. Filter is applied */
if (lis3dh_read(&lis)) {
/* error handling */
}
printf("x: %4.d, y: %4.d, z: %4.d\n", lis.acc.x, lis.acc.y, lis.acc.z);
usleep(5000); /* 5 ms */
}
/* deinitalise struct */
if (lis3dh_deinit(&lis)) {
/* error handling */
}
return 0;
}

View File

@ -76,7 +76,7 @@ int main() {
lis.cfg.int1.latch = 1;
/* set up a HP filter to ignore constant earth acceleration */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.ia1 = 1; /* enable filter for INT1 generator */

View File

@ -39,7 +39,7 @@ int main() {
lis.cfg.mode = LIS3DH_MODE_HR;
lis.cfg.range = LIS3DH_FS_2G;
lis.cfg.rate = LIS3DH_ODR_400_HZ; /* minimum recommended ODR */
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL_REF;
lis.cfg.filter.mode = LIS3DH_FILTER_MODE_NORMAL;
lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8;
lis.cfg.filter.click = 1; /* enable filtering for CLICK function */

View File

@ -36,6 +36,7 @@
#define LIS3DH_STATUS_ZOR(c) (!!(c & 0x40)) /* Z-axis data has overrun (been overwritten) */
#define LIS3DH_STATUS_ZYXOR(c) (!!(c & 0x80)) /* {Z,Y,X}-axis data has overrun (been overwritten) */
/* rates */
/* all power modes */
#define LIS3DH_ODR_POWEROFF 0x00
@ -52,17 +53,20 @@
#define LIS3DH_ODR_LP_1600_HZ 0x08
#define LIS3DH_ODR_LP_5376_HZ 0x09
/* range/sens */
#define LIS3DH_FS_2G 0x00 /* Full-scale sensing range: ± 2G */
#define LIS3DH_FS_4G 0x01 /* Full-scale sensing range: ± 4G */
#define LIS3DH_FS_8G 0x02 /* Full-scale sensing range: ± 8G */
#define LIS3DH_FS_16G 0x03 /* Full-scale sensing range: ± 16G */
/* operating modes */
#define LIS3DH_MODE_HR 0x00 /* High resolution: 12-bit */
#define LIS3DH_MODE_LP 0x01 /* Low-power: 8-bit */
#define LIS3DH_MODE_NORMAL 0x02 /* Normal: 10-bit */
/* FIFO modes */
/* FIFO is not operational, and the buffer is reset. Must be used for switching FIFO modes */
#define LIS3DH_FIFO_MODE_BYPASS 0x00
@ -77,11 +81,7 @@
#define LIS3DH_FIFO_TRIG_INT1 0x00
#define LIS3DH_FIFO_TRIG_INT2 0x01
/* filter modes */
/* Normal mode
* but reset by reading REFERENCE, instantly removes the DC component
*/
#define LIS3DH_FILTER_MODE_NORMAL_REF 0x00
/* Reference mode
* Output [x y z] data is calculated as the difference between the
* measured acceleration and the value stored in REFERENCE.
@ -89,31 +89,31 @@
* FS_2G: ~ 16mg per 1 LSb
* FS_4G: ~ 31mg per 1 LSb
* FS_8G: ~ 63mg per 1 LSb
* FS_16G: ~127mg per 1 LSb
* */
* FS_16G: ~127mg per 1 LSb */
#define LIS3DH_FILTER_MODE_REFERENCE 0x01
/* Normal mode
* Probably the same as LIS3DH_FILTER_MODE_NORMAL_REF
*/
* Probably the same as 0x00 */
#define LIS3DH_FILTER_MODE_NORMAL 0x02
/* Autoreset mode
* The filter is automatically reset upon configured interrupt event.
* It can be reset at any time by reading REFERENCE.
*/
* It can be reset at any time by reading REFERENCE. */
#define LIS3DH_FILTER_MODE_AUTORESET 0x03
/* filter cutoff */
/* unfortunately, there is only a table for low-power mode,
and the actual cutoff-frequency depends on the ODR.
Naming scheme after ODR@400Hz
AN3308 > section 4.3.1.1 */
* and the actual cutoff-frequency depends on the ODR.
* Naming scheme after ODR@400Hz
* AN3308 > section 4.3.1.1 */
#define LIS3DH_FILTER_CUTOFF_8 0x00 /* highest freq */
#define LIS3DH_FILTER_CUTOFF_4 0x01
#define LIS3DH_FILTER_CUTOFF_2 0x02
#define LIS3DH_FILTER_CUTOFF_1 0x03 /* lowest freq */
/* Note: IA{1,2} is interrupt activity {1,2} or interrupt generators */
/* 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 */
struct lis3dh_device {
int (*init)(void);