×
Namespaces

Variants
Actions
Revision as of 09:02, 6 August 2012 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Archived:Reducing accelerometer sensor noise on Symbian

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Remove from Archive?: This article has been marked for removal from archive, for the following reasons:
This still looks relevant for current versions.

Article Metadata
Tested with
Devices(s): Nokia N95 8GB
Compatibility
Platform(s): S60 3rd Edition, MR
S60 3rd Edition (initial release)
Platform Security
Signing Required: Self-Signed
Capabilities: None
Article
Keywords: MRRSensorDataListener, TRRSensorInfo, TRRSensorEvent, MRRSensorDataListener::HandleDataEventL()
Created: tapla (18 Apr 2008)
Last edited: hamishwillee (06 Aug 2012)

Contents

Overview

Sometimes the accelerometer sensor produces quite a lot of noise (that is, undesired data). This can be perceived, for example, by putting the device on the table while observing the produced data. The values should stay more or less stable while the device is on the table. However, this is not the case because of the noise.

This code snippet demonstrates how to reduce the noise from the accelerometer sensor. The technique used in this snippet is to create a circular buffer (a.k.a. a ring buffer) and continuously fill it with data produced by the sensor. As a result, "raw" sensor data is not used, but an average value of the buffer contents is used instead. This effectively smooths the values, which is perceived in practice as reduction of the noise.

Registering listeners for the sensors and displaying sensor data are not covered in this snippet. For that, you may want to see Archived:Listening for accelerometer sensor data events on Symbian and Archived:Displaying sensor data on Symbian.

Note.pngNote: In order to use the code, you need to install the sensor plug-in for your SDK.

MMP file

The following libraries are required:

LIBRARY RRSensorApi.lib
LIBRARY gdi.lib

Header file: CSensorDataFilter.h

#ifndef __CSENSORDATAFILTER_H_
#define __CSENSORDATAFILTER_H_
 
#include <e32base.h> // CBase
 
// Size of the data buffer. The smaller the value, the quicker the reaction
// speed to the changes in the sensor data. However, at the same time, the
// amplitude of noise from the sensor is higher.
const TInt KDataBufferSize = 16;
 
class CSensorDataFilter : public CBase
{
public: // Constructors and destructor
/**
* Two-phased constructor.
*/

static CSensorDataFilter* NewL();
 
/**
* Destructor.
*/

~CSensorDataFilter();
 
private: // Private constructors
/**
* Two-phased constructor.
*/

void ConstructL();
 
/**
* Default constructor.
*/

CSensorDataFilter();
 
public: // New functions
/**
* Calculates the average value from the buffer contents after adding
* a new value to it.
* @param aNewValue a new value to add to the buffer
* @return the average value of the buffer contents
*/

TInt FilterSensorData(TInt aNewValue);
 
private: // Data
TInt* iRingBuffer;
TInt* iRingBufferPointer;
};
 
#endif /*__CSENSORDATAFILTER_H_*/

Source file: CSensorDataFilter.cpp

#include "CSensorDataFilter.h"
 
CSensorDataFilter* CSensorDataFilter::NewL()
{
CSensorDataFilter* self = new (ELeave) CSensorDataFilter();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
 
CSensorDataFilter::CSensorDataFilter()
{
// No implementation required
}
 
void CSensorDataFilter::ConstructL()
{
// Allocate a ring buffer to hold the sensor data
iRingBuffer = new (ELeave) TInt[KDataBufferSize];
 
// Clear the buffer
memset(iRingBuffer, '\0', KDataBufferSize * sizeof(TInt));
 
// Set the buffer pointer to the beginning of the buffer
iRingBufferPointer = iRingBuffer;
}
 
CSensorDataFilter::~CSensorDataFilter()
{
delete iRingBuffer;
}
 
TInt CSensorDataFilter::FilterSensorData(TInt aNewValue)
{
// Add the new value to the buffer, at the current position
*iRingBufferPointer = aNewValue;
 
// Move the pointer, circulating it to the beginning if the buffer is full
iRingBufferPointer++;
if (iRingBufferPointer >= (iRingBuffer + (KDataBufferSize - 1)))
{
iRingBufferPointer = iRingBuffer;
}
 
// Calculate the average of the buffer values
TInt sum = 0;
for (TInt i = 0; i < KDataBufferSize; i++)
{
sum = sum + iRingBuffer[i];
}
return (sum / KDataBufferSize);
}

Header file: CMyControl.h

#include <RRSensorApi.h>
 
#include "CSensorDataFilter.h"
// Accelerometer sensor UID
const TInt KAccelerometerSensorUID = 0x10273024;
class CMyControl : public CCoeControl, public MRRSensorDataListener
{
// ...
 
private: // Functions from base classes
/**
* From MRRSensorDataListener.
* Callback function for receiving sensor data events.
*
* @param aSensor identifies the sensor that created the event.
* @param aEvent contains data about created event.
*/

void HandleDataEventL(TRRSensorInfo aSensor, TRRSensorEvent aEvent);
 
private: // Data
CRRSensorApi* iAccelerometerSensor;
TInt iAccSensorDataX;
TInt iAccSensorDataY;
TInt iAccSensorDataZ;
CSensorDataFilter* iSensorDataFilterX;
CSensorDataFilter* iSensorDataFilterY;
CSensorDataFilter* iSensorDataFilterZ;
}

Source file: CMyControl.cpp

#include <RRSensorApi.h>
 
#include "CSensorDataFilter.h"
void CMyControl::ConstructL(const TRect& aRect)
{
// ...
 
// Reset sensor data
iAccSensorDataX = 0;
iAccSensorDataY = 0;
iAccSensorDataZ = 0;
 
// Create sensor data filters
iSensorDataFilterX = CSensorDataFilter::NewL();
iSensorDataFilterY = CSensorDataFilter::NewL();
iSensorDataFilterZ = CSensorDataFilter::NewL();
 
// ...
}
CMyControl::~CMyControl()
{
// ...
 
// Delete sensor data filters
delete iSensorDataFilterX;
delete iSensorDataFilterY;
delete iSensorDataFilterZ;
}
/**
* Gets called whenever a data event occurs.
*/

void CMyControl::HandleDataEventL(TRRSensorInfo aSensor, TRRSensorEvent aEvent)
{
// A data event occurred. Store new values from the accelerometer sensor.
switch (aSensor.iSensorId)
{
case KAccelerometerSensorUID:
{
// Smooth sensor data with some filtering to reduce noise
iAccSensorDataX = iSensorDataFilterX->FilterSensorData(
aEvent.iSensorData1);
iAccSensorDataY = iSensorDataFilterY->FilterSensorData(
aEvent.iSensorData2);
iAccSensorDataZ = iSensorDataFilterZ->FilterSensorData(
aEvent.iSensorData3);
}
break;
default:
break;
}
}

Postconditions

Data received from the accelerometer sensor is run through a filter to reduce noise.

See also

This page was last modified on 6 August 2012, at 09:02.
110 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×