Miner-Improvements / Level-Lifting-Hardware

The software running on the wearable devices, targeting the ESP32-WROOM-32E and BNO085 IMU.
1 stars 0 forks source link

Device outputs intermittent IMU readouts #10

Closed demcdonald2000 closed 1 year ago

demcdonald2000 commented 1 year ago

Overview and Hypotheses

The IMU data (yaw, pitch, roll, and XYZ formatted output) is only appearing on the serial monitor port in batches. In between these batches many "Not read" statements are output. This at first seemed like an issue with the hardware, but after trading hardware around and experimenting, I am beginning to suspect the issue may be stemming from software. We are retrieving the IMU data through the RVC interface, which is presumably retrieving the data asap. Some early hypotheses on what might actually be happening are:

  1. The data is not actually being retrieved at a consistent rate, but rather at the same intermittent rate that it is being output to the serial port
    1. The IMU is sending the data intermittently at the rate seen on the serial port
    2. A combination of both

sample_intermittent_serial_output.txt

image

demcdonald2000 commented 1 year ago

Making slow progress on this issue. I've experimented with it enough to recognize some trends and repetition in the patterns. My current hypothesis is that we aren't retrieving the data fast enough and are experiencing buffer overflow on the RX port. Each UART RVC packet is 19 bytes and the RX buffer is 256 bytes, so as soon as we get behind ~13 frames we'd start missing. From the BNO085 datasheet I've determined the UART RVC is transmitting samples at a frequency of 100Hz. This rate doesn't seem to be able to be adjusted if we want to continue using UART RVC, but is more flexible if we use I2C or SPI. The three potential solutions that I've been thinking about revolve around fixing the timing: either match the 100Hz rate the data is being sent at, slow down the rate on the BNO085 (I2C or SPI needed I think), or flush the buffer every time we read (don't let it fill up).

To note: I'm not 100% confident on how RX buffer overflow works on the ESP32. I've assumed that once the buffer is full, any incoming data gets dropped until there is room again.

For now, I'll be taking a break and revisiting this issue when I have time. Been working on this most of the afternoon and some distance may reveal a better solution.

demcdonald2000 commented 1 year ago

Was able to get IMU values to update fast enough to be able to see the characteristic values change in real-time from EFR Connect phone application. This was made possible by editing the Adafruit_BNO08x_RVC.cpp file to sit and read bytes from the RX buffer until a byte matching the first header byte (0xAA) was found. Following the hypothesis of buffer overflow due to slow read speeds, this theoretically is clearing out the partial frames left behind by buffer overflow.

This is not an ideal solution. It may stop working shortly. But for now, it's something.

Some notes:

demcdonald2000 commented 1 year ago

Extending the idea that the rx buffer was overflowing, the code was simplified to reduce timing overhead. This ensured the rx buffer was being checked at least as fast as the data was coming in (100Hz, or every 10ms). To simplify the codes, println() statements were either removed or replaced with write() statements (println was introducing significant overhead on the order of 10-15ms). With this, the code was running plenty fast, so a delay was added to better match the incoming data rate. After these modifications, there were very few "not reads", enough that it was deemed that missing one data point every few seconds was not an immediate concern.

In order to make the code more extensible, it was determined a timer-triggered ISR should be used going forward to indicate when to read from the IMU.