Accelerometers
(Tidy up introduction and styling) |
|||
Line 74: | Line 74: | ||
f.close() | f.close() | ||
return coords | return coords | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | == Smoothed C interface == | ||
+ | |||
+ | This is a C function which returns smooth values from the accelerometer. | ||
+ | Designed for applications running at >=25fps (otherwise it lags) | ||
+ | |||
+ | (GPL code extracted from libliqbase: liqaccel.c) | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | static int ocnt=0; | ||
+ | static int oax=0; | ||
+ | static int oay=0; | ||
+ | static int oaz=0; | ||
+ | |||
+ | static const char *accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord"; | ||
+ | |||
+ | int liqaccel_read(int *ax,int *ay,int *az) | ||
+ | { | ||
+ | FILE *fd; | ||
+ | int rs; | ||
+ | fd = fopen(accel_filename, "r"); | ||
+ | if(fd==NULL){ liqapp_log("liqaccel, cannot open for reading"); return -1;} | ||
+ | rs=fscanf((FILE*) fd,"%i %i %i",ax,ay,az); | ||
+ | fclose(fd); | ||
+ | if(rs != 3){ liqapp_log("liqaccel, cannot read information"); return -2;} | ||
+ | int bx=*ax; | ||
+ | int by=*ay; | ||
+ | int bz=*az; | ||
+ | if(ocnt>0) | ||
+ | { | ||
+ | *ax=oax+(bx-oax)*0.1; | ||
+ | *ay=oay+(by-oay)*0.1; | ||
+ | *az=oaz+(bz-oaz)*0.1; | ||
+ | } | ||
+ | oax=*ax; | ||
+ | oay=*ay; | ||
+ | oaz=*az; | ||
+ | ocnt++; | ||
+ | return 0; | ||
+ | } | ||
</pre> | </pre> | ||
Revision as of 18:01, 29 August 2009
Fremantle provides an accelerometer API. Currently[1] there are two interfaces available:
- D-Bus
- sysfs
See also the related thread at talk.maemo.org.
Contents |
D-Bus
Thomas Thurman (marnanel) has put together a simple demo of an application using accelerometers using the D-Bus interface. You can find sources and .deb up at http://people.collabora.co.uk/~tthurman/sandcastle/
sysfs
Another way is to use the sysfs file information:
/sys/class/i2c-adapter/i2c-3/3-001d/coord
When reading that file you get 3 values X, Y and Z (provided on one line, separated by white space). Values are in mG (milli G). 1000 = 1 G
Position | X | Y | Z |
---|---|---|---|
Lying on table (back down) | 0 | 0 | -1000 |
Lying on table (face down) | 0 | 0 | 1000 |
Sitting on table (bottom edge down) | 0 | -1000 | 0 |
Sitting on table (right edge down) | -1000 | 0 | 0 |
Sitting on table (left edge down) | 1000 | 0 | 0 |
Bottom right corner down (approx.) | -500 | -500 | 0 |
These are theoretical values. In real life your mileage will vary.
Using the data
The X and Y values can be used to calculate[2] the roll (that is, clockwise rotation) using the atan2 function (note the inverted sign of y):
angle_in_radians = atan2(x, -y)
Similar, Y and Z can be used to calculate the pitch.
Python
Using the sysfs interface:
def get_rotation(): f = open("/sys/class/i2c-adapter/i2c-3/3-001d/coord", 'r' ) coords = [int(w) for w in f.readline().split()] f.close() return coords
Smoothed C interface
This is a C function which returns smooth values from the accelerometer. Designed for applications running at >=25fps (otherwise it lags)
(GPL code extracted from libliqbase: liqaccel.c)
static int ocnt=0; static int oax=0; static int oay=0; static int oaz=0; static const char *accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord"; int liqaccel_read(int *ax,int *ay,int *az) { FILE *fd; int rs; fd = fopen(accel_filename, "r"); if(fd==NULL){ liqapp_log("liqaccel, cannot open for reading"); return -1;} rs=fscanf((FILE*) fd,"%i %i %i",ax,ay,az); fclose(fd); if(rs != 3){ liqapp_log("liqaccel, cannot read information"); return -2;} int bx=*ax; int by=*ay; int bz=*az; if(ocnt>0) { *ax=oax+(bx-oax)*0.1; *ay=oay+(by-oay)*0.1; *az=oaz+(bz-oaz)*0.1; } oax=*ax; oay=*ay; oaz=*az; ocnt++; return 0; }
References
- ↑ #4724 Lack of official documentation on how to use the accelerometer
- ↑ Tom Pycke, Accelerometer to pitch and roll