Accelerometer triggers multiple times at the same time after some minutes running

Viewed 627

I have developed a mobile app with Flutter. I am reading the acceleration data with the flutter_sensors package and every time the stream gets triggered and outputs new acceleration data I take the elapsed milliseconds with the Stopwatch class and store and plot both the acceleration data and the corresponding timestamps.

accelerationZ = [12.79, 9.93, 8.43, 15.96, …, 5.13, 9.61, 12.81] in m/s^2
time = [145922, 145923, 145952, 145960, …, 147900, 147913, 147936] in ms since start

After some minutes something strange happens.

This is how the acceleration over time graph looks right after starting the sensors:

Acceleration over time right after starting the sensor - 1

This is how it looks after around 4 minutes:

Acceleration over time after around 4min - 2

This plot shows the time in milliseconds between every time the stream got triggered and gave me new data (the difference between the elapsed milliseconds time[i+1]-time[i]). In orange the normal state (picture 1). In blue the broke state after some minutes (picture 2).

time between every timestamp

When every thing is fine (orange line) there is new data coming every 5 to 15ms.

But after some minutes (blue line) the stream gets triggered multiple times at the same time (the difference in time and therefore the graph at this point are zero) and then makes a break for around 70ms (the spikes in the graph) before again getting triggered multiple times.

This corresponds to the graph shown in picture 2. There you can also see these jumps in time and multiple values at the same time.

My questions are: What could cause that? And how do I fix that?

I am happy to hear any suggestions for general improvements (for example for the title). Thank you very much for your help. If need more information to help me please let me know! I am desperate.

This is the code listening for events:

void startSensors() async {
    accelstream = await SensorManager().sensorUpdates(
      sensorId: Sensors.ACCELEROMETER,
      interval: Duration(milliseconds: 10),
    );

    stopWatch.start();

    accelstream.listen((SensorEvent event) {
      setState(
        () {
          Vector3 accel = Vector3(event.data[0], event.data[1], event.data[2]);
          newData(accel.z, stopWatch.elapsedMilliseconds)
        },
      );
    });
}

Some of my discoveries: The state develops over time. Right after starting the app the sampling rate is in average 100Hz (every 10ms) (orange in the graph). It's not that the stream triggers constantly every 10ms. Instead sometimes the accelerometer "takes" (idk what the right terms are I apologize) 15ms and then maybe the next time only 5ms. Over time the differences grow. For example after 30s the streams triggers between 2ms and 18ms but still averages at 10ms (100Hz). The longer the sensor runs the bigger the gap gets (e.g. 0ms and 60ms). Another thing I discovered is that over time the operating system (ig) drops the sampling rate from initial 100Hz to 20Hz.

1 Answers

You should not be attempting to determine the timing yourself (using the stopwatch). The event data contains a timestamp of when the event occurred. You need to use that instead as there can be some latency (depending on what else is going on).

Just store the timestamp of the last event, then compute the delta when the new event comes in.

Related