Buffering Sensor Data

Working with sensors on devices can often lead to large amounts of data coming to you really fast. For example the TMotionSensor’s OnDataChange event fires 100 times a second on my Nexus 5. When I was building my level app for Google Glass the level bar was bouncing all over the place because of the sensitivity and sample rate.

My first thought was to only take every 10th sample, but I wasn’t happy with that either because the specific sample it pulled could be the one when there was a jitter.

Example: 1,2,1,1,2,1,2,3,1,3,12,2,3,1

If I just looked at sample 1 and 11 then I would see a lot of movement, but in reality it was relatively stable most of the time.

What I ended up doing was buffering the data and taking an average. I just created a generic TList of the appropriate type, and during the OnDataChange event I would simply store the sample data. When it came time to update the display I took an average sample, which I found gave a much smoother and more representational display.

Although it was still possible the line could jump erratically if I really moved a lot. So I decided to use an animation for the movement. This keeps the line movement smooth, even if there is a lot of movement (it interpolates the positions between the current line position and the new position). I used a TFloatAnimation and set the StartFromCurrent property to true.

When the animation is finished I set the StopValue to the the average of the values, then enable again. It is important to always clear the sample values after taking an average. Otherwise the movement will continue to get slower and slower as it becomes more and more stable (averaging a large enough sample of numbers results in a smaller range of results.)

I was really pleased with how smooth things looked with a 0.1 second duration on the animation. With 100 samples a second, this translates into each animation covering the average of 10 samples. The built in animations made it really easy, and the final display looked great.

I’ll include the source code with the downloads from the Making the Connection: Programming Devices and Gadgets with RAD Studio webinar coming up next week!

RAD-in-Action Webinar Making the Connection: Programming Devices and Gadgets with RAD Studio Wednesday, January 22, 2014

This entry was posted in Android, iOS, Mobile, webinar. Bookmark the permalink.

3 Responses to Buffering Sensor Data

  1. Pingback: Cocosistemas.com. Diego Muñoz. Informático Freelance. » Blog Archive » Navegaciones semana 13/01/2014 – 19/01/2014

  2. Kevin G. McCoy says:

    Although it might not apply to slightly jittery data – if you have sensor data with occasional large noise bursts and need to get a true “average” ignoring the bursts, there is a trick I use sometimes: Fill a list or array with successive samples, then sort them by value. Pick the “geometric center” value in the list – that is the average sample without taking into account dropouts or noise bursts.

    The algorithm self-levels because the outlier sensor data points are always at the extreme ends of the array.

    A simple average would be skewed by bursts and dropouts – especially if there are few samples and populated by large noise bursts.

  3. Ahmadian says:

    Hi Jim
    I have a successful effort on Linux:
    http://forum.lazarus.freepascal.org/index.php/topic,24389.0.html

Leave a Reply