Skip to content

Commit dc0eb9b

Browse files
committed
doc: More FIFO notes
1 parent 02aeaf5 commit dc0eb9b

File tree

2 files changed

+69
-21
lines changed

2 files changed

+69
-21
lines changed

doc/fifo_imu.md

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,48 @@ So here is my attempt at raising this concern, and how we could address it :)
1616

1717
Most of the IMU drivers out there today have functions to read the current values
1818
of the accelerometer/gyro/magnetometer data.
19-
20-
EXAMPLE CODE
19+
Each call of the function returns a single datapoint in time.
20+
Example: `(x, y, z) = get_xyz()`.
2121

2222
When one only does a single readings of the data, this works rather OK.
2323
For example to check the current orientation of a rarely moving object, say for asset tracking.
2424

25-
However when doing continious sampling, doing this by looping over.
26-
27-
Such continious sampling is needed for example when one tracks a moving object,
28-
detect gestures, implement a regulation loop (PID), measure vibrations etc.
25+
However many applications requires continious sampling of several samples.
26+
Examples includ tracking a moving object, detect gestures,
27+
implement a regulation loop (PID), measure vibrations etc.
2928

3029
## Problems with continious sampling using repeated polling
3130

32-
This is less-than-ideal for several reasons:
31+
Here is example code for continious sampling,
32+
at a slow 25 Hz and processing 1 second time-windows.
33+
This could for example be human activity detection on a smartwatch,
34+
gesture detection for a "magic wand",
35+
animal activity detection on a LoRa tracker, et.c.
36+
37+
```
38+
SAMPLERATE = 25
39+
THRESHOLD = 25
40+
sensor = SomeIMU(i2c=machine.I2C(...))
41+
samples = []
42+
while True:
43+
t = time.ticks_ms()
44+
xyz = sensor.get_xyz()
45+
samples.append(xyz)
46+
47+
if len(samples) == THRESHOLD:
48+
process_samples(samples)
49+
samples = []
50+
51+
# Try compensate for execution time causing variation in data sampling time
52+
# But - if more than 1/SAMPLERATE (4ms for 25 Hz) - will miss the entire timestep...
53+
time_spent = time.ticks_diff(time.ticks_ms(), t)
54+
55+
# Very little benefit from lightsleep on very short durations
56+
wait_time = max(1000/SAMPLERATE - time_spent, 0)
57+
time.sleep_ms(wait_time)
58+
```
59+
60+
Doing continious sampling by fetching single samples is less-than-ideal for several reasons:
3361

3462
1. Any variation/delay in time of reading causes uneven sampling of data. Jitter/noise.
3563
2. Application processor must be constantly running. High power consumption.
@@ -47,8 +75,8 @@ When MicroPython code executes, there will at some point be a need to do some ga
4775
The likelihood increases with how much allocations the code does,
4876
but can generally happen at any point in time.
4977
One garbage collection run may take many milliseconds, and will cause the data to be sampled at the wrong time.
50-
This can mess up the results of most types of analysis,
51-
be it Digital Signal Processing, control theory, or Machine Learning - because they rely on regularly sampled data.
78+
This can mess up the results of many types of analysis - because they rely on regularly sampled data.
79+
Most methods from Digital Signal Processing, control theory, or Machine Learning.
5280

5381
2. Execution time might be too slow for high samplerates.
5482
To read at 1kHz+, code would need to spend under 1 ms per iteration,
@@ -89,28 +117,30 @@ so one should still support usage without interrupts.
89117

90118
## Application pseudo code
91119

92-
Here is some illustrative code for how such a driver could be used
93-
to implement low-power continious data analysis of short time-windows of IMU data.
94-
This could for example be human activity detection on a smartwatch,
95-
gesture detection for a "magic wand",
96-
animal activity detection on a LoRa tracker, et.c.
120+
Here is some illustrative code for how such a driver could be used in the same scenario as above.
121+
97122

98123
```
99124
SAMPLERATE = 25
100-
THRESHOLD = 25
125+
THRESHOLD = 25 # NOTE: Should be max 75% of IMU FIFO capacity
101126
imu = SuperIMU2k(i2c=machine.I2C(...), odr=SAMPLERATE)
102127
103128
while True:
104129
level = imu.get_fifo_level()
105130
if level < THRESHOLD:
106131
samples = imu.read_fifo_data(THRESHOLD)
107132
108-
# should take 100 ms or less. Otherwise compensate the sleep time
133+
# Can take up to 100 ms without needing to compensate sleep time
134+
# Or up to 1000ms if one does the compensation
109135
process_samples(samples)
110136
111-
machine.lightsleep(900)
137+
machine.lightsleep(100)
112138
```
113139

140+
This code will spend 90-99% of the time in lightsleep, for 10-100x power savings.
141+
It will also just work if using high samplerates (1000 Hz+).
142+
And the same approach will work to collect data from multiple sensors at the same time.
143+
114144
## Call to Action: Use the FIFO!
115145

116146
So next time you are implementing a driver for an IMU, please consider supporting using the FIFO!

doc/micropython-tinyml-status.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ How ready is MicroPython for use in a TinyML setting.
66

77
## Efficient data processing
88

9-
Good! Integer only code can be made quite fast with @micropython.native/viper
9+
Good! Support for fixed buffers, using `array.array`.
1010

11-
Missing documentation about using array.array
11+
!Missing documentation about using array.array.
1212
With or without @micropython.native
1313

14-
Floating point code cannot be optimized with @micropython.native
14+
? Not easy to write allocation free code in Python for buffers/arrays.
15+
Slicing is
16+
17+
Native machine code emitters with @micropython.native/viper
18+
Good! Integer only code can be made quite fast with
19+
Limitation. Floating point code cannot be optimized with @micropython.native
20+
1521

1622
## Interoperability
1723

@@ -21,7 +27,8 @@ Ref notes on [multi_dimensional_arrays](multi_dimensional_arrays.md).
2127
## Drivers
2228

2329
Almost no accelerometer/IMU drivers implement FIFO based-readout.
24-
Causes poor sampling accuracy / high jitter.
30+
Causes poor sampling accuracy / high jitter / limited samplerate / high power consumption.
31+
Details in notes.
2532

2633
PDM microphones are not supported, on any port?
2734
ESP32, RP2040, STM32, NRF52.
@@ -30,6 +37,17 @@ ESP32, RP2040, STM32, NRF52.
3037

3138
Good support for WiFi based commmunication on ESP32.
3239

40+
Not good! Low-power BLE support.
41+
42+
ESP32 no support for sleep with Bluetooth.
43+
https://github.com/micropython/micropython/pull/8318
44+
45+
NRF52 BLE support not so good?
46+
https://github.com/micropython/micropython/issues/9851
47+
https://github.com/micropython/micropython/pull/8318
48+
49+
LoRa?
50+
Zigbee?
3351

3452
## Preprocessing
3553

0 commit comments

Comments
 (0)