Accelerometer Data

Neil Brown neilb at suse.de
Mon Mar 23 23:24:09 CET 2009


On Monday March 23, michael-tansella at gmx.de wrote:
> > In the latest andy-tracking it reports the more correct 'ABS' events.
> > So now it does report zeros.  However it doesn't report an axis if there
> > has been no change.
> 
> Is it correct that there are now two changes for developers. The first one is 
> that the EVENT type has changed from EV_REL (0x02) to EV_ABS (0x03). This 
> would mean in the python sample code of the wiki the change would be:
> 
> from:
> 
> if type == 2:
> 	if code == 0:
> 		x = value
> 	if code == 1:
> 		y = value
> 	if code == 2:
> 		z = value
> 
> to:
> 
> if type == 3:
> 	if code == 0:
> 		x = value
> 	if code == 1:
> 		y = value
> 	if code == 2:
> 		z = value

Or
  if type == 2 or type == 3:
          ...

then it would work on both old and new kernels.

> 
> The second change is that if no new (y,x, or z) value is reported the old one 
> should be taken.

Correct.  The code you have given does this already, providing that x,
y, and z persist between calls to that code.

> 
> >If you want to simply get "the current values"
> > there is an ioctl : EVIOCGABS I think.
> 
> I think that is what most developers want. It would be great if someone could 
> show  a small sample code how this works.

In C it is simply:

#include <linux/input.h>
.
.
.
  struct input_absinfo abs;

  ioctl(fd, EVIOCGABS(ABS_X), &abs); x = abs.value;
  ioctl(fd, EVIOCGABS(ABS_Y), &abs); y = abs.value;
  ioctl(fd, EVIOCGABS(ABS_Z), &abs); z = abs.value;


In python it is a little harder because you need to make your
own EVIOCABS()
Something like...
------------------------------------------------------------

import fcntl, struct

_IOC_WRITE = 1
_IOC_READ = 2

_IOC_NRBITS = 8
_IOC_TYPEBITS = 8
_IOC_SIZEBITS = 14
_IOC_DIRBITS = 2

_IOC_NRSHIFT = 0
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS

def _IOC(dir, type, nr, size):
	return ( (dir << _IOC_DIRSHIFT) |
		 (ord(type) << _IOC_TYPESHIFT) |
		 (nr << _IOC_NRSHIFT) |
		 (size << _IOC_SIZESHIFT))

def EVIOCGABS(abs):
	return _IOC(_IOC_READ, 'E', 0x40 + abs, 5*4)

ABS_X = 0
ABS_Y = 1
ABS_Z = 2

def get_abs(fd, code):
	buf = struct.pack('iiiii', 0, 0, 0, 0, 0)
	abs = fcntl.ioctl(fd, EVIOCGABS(code), buf)
	(val,min,max,fuzz,flat) = struct.unpack('iiiii', abs)
	return val

fd = open("/dev/input/event2")
x,y,z = get_abs(fd, ABS_X), get_abs(fd, ABS_Y), get_abs(fd, ABS_Z)

print x,y,z

------------------------------------------------------------

which could, of course, be cleaned up and put in a class or two.

NeilBrown




More information about the community mailing list