diff --git a/.gitea/graph-16g-filter.png b/.gitea/graph-16g-filter.png deleted file mode 100644 index 09a223b..0000000 Binary files a/.gitea/graph-16g-filter.png and /dev/null differ diff --git a/.gitea/graph-16g.png b/.gitea/graph-16g.png deleted file mode 100644 index f026fa3..0000000 Binary files a/.gitea/graph-16g.png and /dev/null differ diff --git a/.gitea/graph-2g-filter.png b/.gitea/graph-2g-filter.png deleted file mode 100644 index f7b6e3e..0000000 Binary files a/.gitea/graph-2g-filter.png and /dev/null differ diff --git a/.gitea/graph-2g.png b/.gitea/graph-2g.png deleted file mode 100644 index e877b1c..0000000 Binary files a/.gitea/graph-2g.png and /dev/null differ diff --git a/.gitea/graph-4g-filter.png b/.gitea/graph-4g-filter.png deleted file mode 100644 index c29b57a..0000000 Binary files a/.gitea/graph-4g-filter.png and /dev/null differ diff --git a/.gitea/graph-4g.png b/.gitea/graph-4g.png deleted file mode 100644 index c066c1f..0000000 Binary files a/.gitea/graph-4g.png and /dev/null differ diff --git a/.gitea/graph-8g-filter.png b/.gitea/graph-8g-filter.png deleted file mode 100644 index 2637530..0000000 Binary files a/.gitea/graph-8g-filter.png and /dev/null differ diff --git a/.gitea/graph-8g.png b/.gitea/graph-8g.png deleted file mode 100644 index 58211ea..0000000 Binary files a/.gitea/graph-8g.png and /dev/null differ diff --git a/README.md b/README.md index e5d332c..e1340af 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # LIS3DH -A C89 driver for the 3-axis accelerometer LIS3DH by ST. Supports both i2c and SPI. +A C89 driver for the 3-axis accelerometer LIS3DH. Supports both i2c and SPI. > ### Features > - FIFO of varying watermark level, up to 32 -> - HP filter +> - HP filter (4 c/o freq) > - 2G, 4G, 8G and 16G > - All power modes > - Interrupt generation (soon) @@ -12,66 +12,314 @@ A C89 driver for the 3-axis accelerometer LIS3DH by ST. Supports both i2c and SP > - Single and double click detection (soon) > - 4D/6D orientation detection (soon) -FIFO output example - -``` -$ ./lis3dh -x: 0.5320, y: -0.8800, z: -0.0600 mag: 1.0301 -x: 0.5440, y: -0.8680, z: -0.0760 mag: 1.0272 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0760 mag: 1.0306 -x: 0.5440, y: -0.8720, z: -0.0720 mag: 1.0303 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0720 mag: 1.0392 -x: 0.5480, y: -0.8800, z: -0.0800 mag: 1.0398 -x: 0.5480, y: -0.8960, z: -0.0960 mag: 1.0547 -``` - > ### Notes > FIFO is always and only 10-bit -### Noise at 2G -![DC noise at 2G](.gitea/graph-2g.png) +## Usage +Simple example: +```c +#define _GNU_SOURCE +#include /* usleep() */ +#include +#include "lis3dh.h" +#include "i2c.h" -![DC noise at 2G](.gitea/graph-2g-filter.png) -### Noise at 4G -![DC noise at 4G](.gitea/graph-4g.png) +int main() { + + lis3dh_t lis; -![DC noise at 2G](.gitea/graph-4g-filter.png) -### Noise at 8G -![DC noise at 8G](.gitea/graph-8g.png) + lis.dev.init = i2c_init; + lis.dev.read = i2c_read; + lis.dev.write = i2c_write; + lis.dev.sleep = usleep; + lis.dev.deinit = i2c_deinit; -![DC noise at 2G](.gitea/graph-8g-filter.png) -### Noise at 16G -![DC noise at 16G](.gitea/graph-16g.png) + if (lis3dh_init(&lis)) { + /* error handling */ + } -![DC noise at 2G](.gitea/graph-16g-filter.png) + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; -## Using i2c on STM32 + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll(&lis)) { + /* error handling */ + } + + if (lis3dh_read(&lis)) { + /* error handling */ + } + + printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); + + if (lis3dh_deinit(&lis)) { + /* error handling */ + } + + return 0; +} +``` +The output should be something similar to this: +``` +$ ./lis3dh +x: 0.540000, y: -0.882000, z: -0.100000 +``` +poll() and read() can be indefinitely looped for a constant data stream, like this: +```c +#define _GNU_SOURCE +#include +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + 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; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + for(i=0; i<10; i++) { + + if (lis3dh_poll(&lis)) { + /* error handling */ + } + + if (lis3dh_read(&lis)) { + /* error handling */ + } + + printf("x: %f, y: %f, z: %f\n", lis.acc.x, lis.acc.y, lis.acc.z); + } + + if (lis3dh_deinit(&lis)) { + /* error handling */ + } + + return 0; +} +``` +Output: +``` +$ ./lis3dh +x: 0.534000, y: -0.882000, z: -0.102000 +x: 0.538000, y: -0.866000, z: -0.136000 +x: 0.518000, y: -0.846000, z: -0.100000 +x: 0.518000, y: -0.840000, z: -0.098000 +x: 0.542000, y: -0.876000, z: -0.098000 +x: 0.518000, y: -0.834000, z: -0.146000 +x: 0.512000, y: -0.854000, z: -0.106000 +x: 0.574000, y: -0.870000, z: -0.122000 +x: 0.518000, y: -0.846000, z: -0.098000 +x: 0.516000, y: -0.852000, z: -0.112000 +``` +## Using FIFO +Instead of polling for every single [x y z] set, a FIFO with programmable capacity ("watermark") can be used like such: + +It should be noted that all FIFO readings use 10-bit resolution regardless of the mode. The watermark level can also be adjusted to a value [0-32] inclusive by modifying the `lis.cfg.fifo.fth` property before calling configure(). +```c +#define _GNU_SOURCE +#include +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data data; + 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; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll_fifo(&lis)) { + /* error handling */ + } + + if (lis3dh_read_fifo(&lis, &data)) { + /* error handling */ + } + + /* read out fifo buffer data */ + for(i=0; i +#include +#include "lis3dh.h" +#include "i2c.h" + +int main() { + + lis3dh_t lis; + struct lis3dh_fifo_data data; + 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; + + if (lis3dh_init(&lis)) { + /* error handling */ + } + + lis.cfg.mode = LIS3DH_MODE_HR; + lis.cfg.range = LIS3DH_FS_4G; + lis.cfg.rate = LIS3DH_ODR_100_HZ; + lis.cfg.fifo.mode = LIS3DH_FIFO_MODE_NORMAL; + lis.cfg.filter.mode = LIS3DH_FILTER_MODE_AUTORESET; + lis.cfg.filter.cutoff = LIS3DH_FILTER_CUTOFF_8; + + if (lis3dh_configure(&lis)) { + /* error handling */ + } + + if (lis3dh_poll_fifo(&lis)) { + /* error handling */ + } + + if (lis3dh_read_fifo(&lis, &data)) { + /* error handling */ + } + + /* read out fifo buffer data */ + for(i=0; i