Replies: 5 comments 8 replies
-
I couldn’t agree more with your assessment of the usefulness and importance of taking advantage of the sensor FIFO, especially in MicroPython. I reached similar conclusions and followed a similar approach while writing a driver for the BMP390 pressure and temperature sensor. |
Beta Was this translation helpful? Give feedback.
-
To raise visibility on awesome micropython, I'd suggest adding a comment or simple badge ⏩, or even a subsection for drivers that support fifo |
Beta Was this translation helpful? Give feedback.
-
Fully agree, though I do prefer to use a watermark interrupt :) I've raised a PR to add @antirez and @jornamon's drivers to the awesome list - and add the badge as @Josverl suggested. @jonnor we should turn your gist into a 'proper' driver that's mip-installable and then add that. Or perhaps it would be best to add FIFO support to the existing LIS2MDL and LIS3MDL drivers? They look otherwise quite full-featured and well-documented. |
Beta Was this translation helpful? Give feedback.
-
@jonnor I agree with most of this, except for your suggestion of use within a control system feedback loop (e.g. PID controller). A FIFO introduces latency - a time delay which is anathema to control systems. In these applications precise timing and minimal latency arre paramount. There are IMU controllers which support reading in a hard ISR, which provides minimal latency and tight timing. See |
Beta Was this translation helpful? Give feedback.
-
I needed FIFO support for MPU6886, and have implemented that now at https://github.com/jonnor/micropython-mpu6886/ - installable with mip, of course. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone, my name is Jon. I work on machine learning for sensor systems, including condition monitoring of machines (at Soundsensing), and an open-source TinyML library called emlearn.
The use cases we care about often require high quality data and low-power. When using MicroPython in this area, I have noticed one limitation in the ecosystem: The lack of FIFO support in IMU drivers. So here is my attempt at raising this concern, and how we could address it :)
Current state of IMU drivers
Most of the IMU drivers out there today have functions to read the current values of the accelerometer/gyro/magnetometer data. Each call of the function returns a single datapoint in time. Example:
(x, y, z) = get_xyz()
. When one only does a single reading of the data, this works rather OK. For example, to check the current orientation of a rarely moving object, say for asset tracking.However, many applications requires continious sampling of several samples. Examples include tracking a moving object, detect gestures, implement a regulation loop (PID), measure vibrations etc.
Problems with continuous sampling using repeated polling
Here is some example code for illustrating continuous sampling. At a slow 25 Hz and processing 1 second time-windows.
This could for example be human activity detection on a smartwatch, gesture detection, animal activity detection on a LoRa tracker, et.c.
Doing continuous sampling by fetching single samples is less-than-ideal for several reasons:
These problems become particular painful at high sample rates, or in low-power / battery-powered scenarios, or when trying to do multiple things at the same time (concurrency).
These concerns are generally independent of the programming language (more of a system design issue). However - there are a couple of reasons why it can easily be more problematic in MicroPython:
Variable delays in execution time due to garbage collection.
When MicroPython code executes, there will at some point be a need to do some garbage collection. The likelihood increases with how much allocations the code does, but can generally happen at any point in time. One garbage collection run may take many milliseconds, and will cause the data to be sampled at the wrong time. This can mess up the results of many types of analysis - because they rely on regularly sampled data. Most methods from Digital Signal Processing, control theory, or Machine Learning expect regularly sampled data.
Execution time might be too slow for high samplerates.
To read at 1kHz+, code would need to spend under 1 ms per iteration, which can be hard to achieve in MicroPython.
The solution: Use the FIFO buffer of the sensor
Any recent digital MEMS IMU will have a buffer that it can collect measurements into. Typically, this is referred to as a FIFO, since it is a First In First Out type of buffer/queue. For example, the LIS2dh/LIS3dh accelerometers have a 32 samples deep FIFO for its 3 axes. And BMA421 can store up to 1024 bytes, allowing to store 170 samples of tri-axial data.
When enabling FIFO mode, the sensor itself is responsible for timing the sampling. This means that it will be done at the correct time, independently of what our application code is doing. We can then spend time doing other things, or sleep. As long as one reads the FIFO before it overflows, one gets perfectly sampled data - with minimum computational effort.
How to implement
To support this kind of usage, the IMU driver should have:
A) I recommend that the data reading returns the raw bytes.
This enables the application to decide when/if to convert to a physical unit (such as gravity). Sometimes it is useful to just store or process the raw values.
B) Most IMUs also support triggering an interrupt when the FIFO fill level has reached a certain threshold (watermark).
This can be useful to get absolutely the most out of, but is not critical. One can still get most of the benefits still by polling the FIFO level
and triggering readout based on that. It might also be that the interrupt pin is not connected, only I2C/SPI pins, so one should still support usage without interrupts.
Application code example with FIFO
Here is some illustrative code for how such a driver could be used in the same scenario as above.
This code will spend 90-99% of the time in lightsleep, for 10-100x power savings.
It will also work if using high samplerates (1000 Hz+) - will just need to reduce sleep times a bit.
And the same approach will work to collect data from multiple sensors running concurrently.
Call to Action: Use the FIFO!
So next time you are implementing a driver for an IMU, please consider supporting using the FIFO!
It will make the driver much more powerful and useable for a wider range of scenarios,
enabling people to get higher data quality and lower power consumption.
Drivers with FIFO support
Here is an initial start of divers that support FIFO.
Please let us know if you have made, or found more, and we can link them here!
Beta Was this translation helpful? Give feedback.
All reactions