понедельник, 10 октября 2011 г.

Linux и Joystick (SL-6632)

При программировании под Linux (openSUSE) у меня возникла проблема с джойстиком SpeedLink-6632 - кроссплатформерная библиотека SDL совершенно не хотела нормально определять движение рукоятки - изменение и по оси X, и по оси Y, и даже по оси Z трактовались ею неправильно - как изменение одной только оси X. Причем изменения по осям Y и Z могли появляться,например, при нажатии какой-либо из кнопок (вроде бы какая между ними связь?)). Однако,грубые ошибки в коде исключались - тот же код, той же библиотеки, но под Windows XP работал относительно стабильно (хотя и там были погрешности - начальное положение координаты X могло определиться на 1000 больше).
Поэтому в голову пришла идея - использовать стандартные функции open,read и close и читать значения без SDL.


Вот что из этого получилось. Оказалось, что читать из устройства нужно не в массив байтов, а специальную структуру -  js_event. Функция read при этом читает только тогда, когда происходит какое-либо событие - нажатие кнопки, поворот рукояти и.т.д.
Структура в свою очередь состоит из:
struct js_event {
 __u32 time;
 __s16 value;
 __u8 type;
 __u8 number;
};


Самым главным для нас тут будут переменные value, type и number.
  1. type - определяет тип события. При этом у меня:
    • type=1 - изменилось состояние какой-либо из кнопок.
    • type=2 - изменилось состояние какой-либо из осей.
  2. number - номер кнопки или оси. У меня:
    • Для кнопок - number указывает номер изменённой кнопки (ВАЖНО! счет идет с нуля)
    • Для осей - number=0 - ось X, number=1 - ось Y, number=2 - ось Z
  3. value - значение. Для кнопок - 0 или 1, для осей - число от -32767 до 32767.


Ну и собственно простейший код:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <linux/joystick.h> // В этой библиотеке найдем полезную структуру js_event


void read_joystick()
{
  int fd; // Файловый дескриптор
  js_event data_read; // Структура для работы с джойстиком
  fd = open("/dev/input/js0", O_RDONLY);//Открываем файл
  if (fd!=-1)
  {
   while(1)
   {
     read (fd, &data_read, sizeof(struct js_event)); // Читаем данные. Если события не происходят - программа ожидает их
     switch(data_read.type) // Выбираем по типу
     {
     case 1: // Изменена кнопка
      printf(" button = %d, value = %d \n",data_read.number+1,data_read.value);
     break;
     case 2: // Изменена ось
      switch(data_read.number)
      {
      case 0: // ось Х
       printf("X = %d \n",data_read.value);
      break;
      case 1: // ось Y
       printf("Y = %d \n",data_read.value);
      break;
      case 2: // ось Z
       printf("Z = %d \n",data_read.value);
      break;
      }
     break;
     }
   }
  }
  close(fd);
}


* This source code was highlighted with Source Code Highlighter.

Комментариев нет:

Отправить комментарий