You are not logged in.

#1 2009-10-22 09:36:32

Anak
Member
Registered: 2009-10-21
Posts: 3

Investing js0 axis accelerometer.

Hello again community.
I started to configure my notebook accelerometer... Surprise!, When I get to calibrate it, I realize that the axes are reversed. I wonder if there is any way to reverse the axes to work with it properly, because the software does not have that option.
The driver "joydev" what he does, is to emulate the accelerometer as a joystick.

Sorry for my bad english


Thanks

Offline

#2 2009-10-22 13:28:13

hbekel
Member
Registered: 2008-10-04
Posts: 311

Re: Investing js0 axis accelerometer.

I have written a small c program for swaping axes and buttons (I use it myself to swap some buttons around):

jswap.c

/*
jswap 0.1 -- swap joystick buttons or axes

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301, USA.  
*/

#include <sys/ioctl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <linux/joystick.h>

char *device;
unsigned char num_axes = 2;
unsigned char num_buttons = 4;
int version = 0x000800;
char model[128] = "Unknown";

__u16 buttons[KEY_MAX - BTN_MISC + 1];
__u8 axes[ABS_MAX + 1];

void usage(void) {
  puts("Usage: jswap [<spec>,...] device");
  puts("       <spec> = [a|b]:<idx>,<idx>");
}

void print_info(void) {
  int i;
  printf("%s: %d axes, %d buttons (\"%s\")\n", 
     device, num_axes, num_buttons, model);

  printf("buttonmap : [");
  for(i=0; i<num_buttons; i++) {
    if(i == 0) 
      printf("%d", buttons[i]);
    else
      printf(", %d", buttons[i]);
  }
  printf("]\n");

  printf("axismap   : [");
  for(i=0; i<num_axes; i++) {
    if(i == 0) 
      printf("%d", axes[i]);
    else
      printf(", %d", axes[i]);
  }
  printf("]\n");
}

int check_value(int val, int max, char *type, char *type_pl) {
  if(val > max || val < 0) {
    printf("jswap: %d: no such %s. (%s: %d %s (0-%d))\n", 
       val, type, device, max+1, type_pl, max);
    return 1;
  }
  return 0;
}

int swap_axis(int a, int b) {
  int tmp = axes[a];
  axes[a] = axes[b];
  axes[b] = tmp;
  return 0;
}

int swap_button(int a, int b) {
  int tmp = buttons[a];
  buttons[a] = buttons[b];
  buttons[b] = tmp;
  return 0;
}

int main(int argc, char **argv) {

  int fd;

  if (argc == 1) {
    usage();
    exit(1);
  }

  device = argv[argc - 1];

  if ((fd = open(device, O_RDONLY)) < 0) {
    char *fmt = "jswap: can't open joystick device '%s'";
    char msg[strlen(fmt)+strlen(device)];
    sprintf(msg, fmt, device);
    perror(msg);
    exit(1);
  }

  if(ioctl(fd, JSIOCGVERSION, &version)) {
    perror("jswap: error getting driver version");
    exit(1);
  }

  if(ioctl(fd, JSIOCGAXES, &num_axes)) {
    perror("jswap: error getting number of axes");
    exit(1);
  } 

  if(ioctl(fd, JSIOCGBUTTONS, &num_buttons)) {
    perror("jswap: error getting number of axes");
    exit(1);
  } 

  if(ioctl(fd, JSIOCGNAME(128), model) < 0) {
    perror("jswap: error getting joystick name");
    exit(1);
  } 

  if(ioctl(fd, JSIOCGAXMAP, axes)) {
    perror("jswap: error getting axis map");
    exit(1);
  } 
    
  if(ioctl(fd, JSIOCGBTNMAP, buttons)) {
    perror("jswap: error getting button map");
    exit(1);
  } 

  if(argc == 2) {
    print_info();
  }

  if(argc > 2) {
    int i;
    char *swap;
    int a = -1;
    int b = -1;

    for( i=1; i<argc-1; i++) {
      
      swap = argv[i];

      sscanf(swap+2, "%d,", &a);
      sscanf(index(swap, ','), ",%d", &b);

      if(a == -1 || b == -1) {
    usage();
    exit(1);
      }

      if(strstr(swap, "a:") != NULL) {

    if( (check_value(a, num_axes-1, "axis", "axes") |
         check_value(b, num_axes-1, "axis", "axes")) == 0) {        
      swap_axis(a, b);
    } 
    else {
      exit(1);
    }      
      }
      
      if(strstr(swap, "b:") != NULL) {

    if( (check_value(a, num_buttons-1, "button", "buttons") |
         check_value(b, num_buttons-1, "button", "buttons")) == 0) {        
      swap_button(a, b);
    } 
    else {
      exit(1);
    }      
      }
    }
  }

  if(ioctl(fd, JSIOCSAXMAP, axes)) {
    perror("jswap: error setting button map");
    exit(1);
  }

  if(ioctl(fd, JSIOCSBTNMAP, buttons)) {
    perror("jswap: error setting button map");
    exit(1);
  }

  close(fd);
  return 0;
}

Here's how to compile and use it to swap axes 0 and 1:

$ gcc -I/usr/src/linux-$(uname -r)/include -o jswap jswap.c
$./jswap
Usage: jswap [<spec>,...] device
       <spec> = [a|b]:<idx>,<idx>
$ ./jswap /dev/js0
/dev/js0: 2 axes, 4 buttons ("MOSIC      SPEED-LINK Competition Pro ")
buttonmap : [305, 304, 306, 307]
axismap   : [0, 1]
$ ./jswap a:0,1 /dev/js0
$ ./jswap /dev/js0 
/dev/js0: 2 axes, 4 buttons ("MOSIC      SPEED-LINK Competition Pro ")
buttonmap : [305, 304, 306, 307]
axismap   : [1, 0]

to swap axes, you'd use: jswap a:0,1 /dev/js0
to swap buttons one and two: jswap b:0,1 /dev/js0
to swap buttons three and four: jswap b:2,3

So the values given are indices into the arrays shown by jswap /dev/js0 (indices start with 0)

Hope this helps!

Last edited by hbekel (2009-10-22 13:30:46)

Offline

Board footer

Powered by FluxBB