Writing binary data to flash from IMU device - buffering issue causing acquisition loss #16059
-
The buffer for a file opened with default buffering size appears to be 4096 (Micropython on a Pico W clocked at 250mHz, and an MPU6050 over I2C). So, what is the best strategy here? The goal is to |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 9 replies
-
The problem here is that I2C transfers and file writes are both blocking. You haven't told us what MPU6050 driver you're using. If it's this one it is possible to read IMU values in a hard interrupt service routine (ISR). If it's your own driver, you might take a look at the code for an example of a non-allocating I2C read. The interrupt would be triggered by a timer. The ISR could copy the data to a buffer. I would suggest using a two phase buffer. While one buffer is being written to file, the other is being filled by the ISR. With careful design it should be possible to avoid data loss. |
Beta Was this translation helpful? Give feedback.
-
Thank you Peter, BTW you have
|
Beta Was this translation helpful? Give feedback.
-
I have seen modules which state "I2C / SPI" like this which is confusing since the docs state SPI Timing Characterization (MPU-6000 only) in a number of places. |
Beta Was this translation helpful? Give feedback.
-
For example (or amusement) AQ code:
|
Beta Was this translation helpful? Give feedback.
-
and some code to read the bytestring file and convert to values and plot
|
Beta Was this translation helpful? Give feedback.
-
If your usecase is not latency sensitive - which it does not seem to be since you are writing to FLASH - then use the FIFO on the IMU to do data transfers in more efficient blocks of samples. It will greatly reduce the risks of missing samples due to allocations/GC/IO/etc. Ref https://github.com/orgs/micropython/discussions/15512 |
Beta Was this translation helpful? Give feedback.
I believe what you are trying to do is feasible, but you need to read up on memory allocation. The method
readfrom_mem
allocates, butreadfrom_mem_into
does not. As I suggested above, you need a hard ISR with a double buffer. Thebuf
arg would be a segment of one of the buffers, defined with amemoryview
. When one phase of the buffer is full, the ISR would be pointed at the other buffer and the first one written out.These are relatively advanced techniques so be prepared to do some reading, e.g. this official doc and this one.