From 898a0f7ee2c8ed313f7dac1007615dcb5094968d Mon Sep 17 00:00:00 2001 From: William Clark Date: Sun, 7 Jan 2024 18:11:24 +0000 Subject: [PATCH] Filter example + README --- example/README.md | 14 ++++++++ example/filter-normal.c | 63 ++++++++++++++++++++++++++++++++ example/filter-reference.c | 73 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 example/filter-normal.c create mode 100644 example/filter-reference.c diff --git a/example/README.md b/example/README.md index 11d7c8f..a8aec4b 100644 --- a/example/README.md +++ b/example/README.md @@ -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 diff --git a/example/filter-normal.c b/example/filter-normal.c new file mode 100644 index 0000000..f1bbaaa --- /dev/null +++ b/example/filter-normal.c @@ -0,0 +1,63 @@ +#define _GNU_SOURCE +#include /* usleep() */ +#include +#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; +} \ No newline at end of file diff --git a/example/filter-reference.c b/example/filter-reference.c new file mode 100644 index 0000000..fdd7e17 --- /dev/null +++ b/example/filter-reference.c @@ -0,0 +1,73 @@ +#define _GNU_SOURCE +#include /* usleep() */ +#include +#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; +} \ No newline at end of file