"Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
att2
Beiträge: 15
Registriert: So 20. Nov 2016, 11:17

"Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von att2 »

Hi,

Ich habe da gerade einen interessanten Sensor vor mir, er heisst "JoyWarrior 56FR1" und ist ein 6-Achsen-Bewegungssensor. Er wird, so das Datenblatt, abgefragt wie ein Joystick, aber nicht ganz, er kann noch mehr: Man kann ihm verschiedene Abtastfrequenzen mitteilen oder auch, ob er z.B. Filterfunktionen verwenden will.
Ich möchte die Messwerte dieses Sensors abgreifen und in eine CSV-Datei schreiben. Gut, ich will ihm auch sagen, in welchem Mode er arbeiten soll.
Das ganze soll plattformübergreifend auf Windows und Raspberry Pi funktionieren.
Natürlich habe ich schon gegoogelt, und naja dabei kommt raus, also wenn sie den Joystick plattformübergreifend verwenden wollen, haben sie die Optionen "Allegro-Library", "SDL-Library" oder (bissl mehr Arbeit) "libusb".
Wie seht ihr das? Gib's da noch weitere Möglichkeiten, die mir die Arbeit vereinfachen würden?
Hat jemand schon genau diesen Sensor unter Linux programmiert und wenn ja, wie geht das?

att2
Beiträge: 15
Registriert: So 20. Nov 2016, 11:17

Re: "Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von att2 »

Naja also mittlerweile habe ich eine relativ kleine "joystick.c" Datei gefunden, die den Joystick unter Linux abfragt.
Frage: Wie geht das gleiche unter Freepascal/Lazarus für Raspi ?

/**
* Author: Jason White
*
* Description:
* Reads joystick/gamepad events and displays them.
*
* Compile:
* gcc joystick.c -o joystick
*
* Run:
* ./joystick [/dev/input/jsX]
*
* See also:
* https://www.kernel.org/doc/Documentatio ... ck-api.txt
*/
#include <fcntl.h>
#include <stdio.h>
#include <linux/joystick.h>


/**
* Reads a joystick event from the joystick device.
*
* Returns 0 on success. Otherwise -1 is returned.
*/
int read_event(int fd, struct js_event *event)
{
ssize_t bytes;

bytes = read(fd, event, sizeof(*event));

if (bytes == sizeof(*event))
return 0;

/* Error, could not read full event. */
return -1;
}

/**
* Returns the number of axes on the controller or 0 if an error occurs.
*/
size_t get_axis_count(int fd)
{
__u8 axes;

if (ioctl(fd, JSIOCGAXES, &axes) == -1)
return 0;

return axes;
}

/**
* Returns the number of buttons on the controller or 0 if an error occurs.
*/
size_t get_button_count(int fd)
{
__u8 buttons;
if (ioctl(fd, JSIOCGBUTTONS, &buttons) == -1)
return 0;

return buttons;
}

/**
* Current state of an axis.
*/
struct axis_state {
short x, y;
};

/**
* Keeps track of the current axis state.
*
* NOTE: This function assumes that axes are numbered starting from 0, and that
* the X axis is an even number, and the Y axis is an odd number. However, this
* is usually a safe assumption.
*
* Returns the axis that the event indicated.
*/
size_t get_axis_state(struct js_event *event, struct axis_state axes[3])
{
size_t axis = event->number / 2;

if (axis < 3)
{
if (event->number % 2 == 0)
axes[axis].x = event->value;
else
axes[axis].y = event->value;
}

return axis;
}

int main(int argc, char *argv[])
{
const char *device;
int js;
struct js_event event;
struct axis_state axes[3] = {0};
size_t axis;

if (argc > 1)
device = argv[1];
else
device = "/dev/input/js0";

js = open(device, O_RDONLY);

if (js == -1)
perror("Could not open joystick");

/* This loop will exit if the controller is unplugged. */
while (read_event(js, &event) == 0)
{
switch (event.type)
{
case JS_EVENT_BUTTON:
printf("Button %u %s\n", event.number, event.value ? "pressed" : "released");
break;
case JS_EVENT_AXIS:
axis = get_axis_state(&event, axes);
if (axis < 3)
printf("Axis %u at (%6d, %6d)\n", axis, axes[axis].x, axes[axis].y);
break;
default:
/* Ignore init events. */
break;
}
}

close(js);
return 0;
}


Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: "Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von Mathias »

Müsste machbar sein.

Code: Alles auswählen

bytes = read(fd, event, sizeof(*event));

In Pascal sieht das in etwa so aus:

Code: Alles auswählen

bytes := fpread(fd, event, sizeof(event));


ioctl muss durch fpioctl ersetzt werden und open durch fpopen.

Die Funktionen befinden sich in der Unit BaseUnix.

Ich hoffe dir hilft dies weiter.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

att2
Beiträge: 15
Registriert: So 20. Nov 2016, 11:17

Re: "Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von att2 »

Okay, also die Geschichte ist die:
Das obrige C-Programm ist zwar nett, aber leider nicht korrekt. Der Sensor hat wirklich 6 Achsenwerte und liefert auch 6 Achsenwerte aus. Der C-Code von oben liefert nur von DREI Achsen die Werte, und vergisst dazu noch auf die Zeit in ms.

Die allerkorrektesten Daten kriege ich unter Linux in einer Kommandozeile mit:

cat /dev/input/js0 | hexdump -C


Dann sieht man: Die ersten 4 bytes sind die milisekunden, die nächsten 2 bytes sind der Messwert, dann folgt byte "02" (fix) und das letzte byte ist die Achse 0-5. Also:
a) qword time (32bit)
b) int messwert (16 bit signed)
c) const byte 02
d) byte achse (werte 0-5).

Extrafrage: Wie übersetze ich diese primitive Eingabezeile mit dem cat Befehl in einen Pascal-Code? Sorry, blöde frage, aber das normale FileOpen hat bei mir einfach nix getan. Bitte daher um Hinweise, wie ich der Gerätedatei /dev/input/js0 einen byte-strom von Daten entlocken kann (gern auch 8 bytes auf einmal). DANKE!!!!

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: "Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von Warf »

Erstmal würde ich dir grundsätzlich empfehlen dafür eine Bibliothek zu verwenden, z.B. die SDL. Das liegt daran das die SDL fast alle Controller Typen kennt, sowie unter fast jedem Betriebsystem läuft. Wenn du jetzt aber nur diesen einen Joystick brauchst und nur unter Linux arbeiten musst kannst du es problemlos auch selbst implementieren:

Code: Alles auswählen

type
  TJoyStickData = packed record
    Time: Cardinal;
    Value: SmallInt;
    Filler: Byte;
    Axis: Byte;
  end;
 
...
var
  joyfd: File of TJoyStickData;
  data: TJoyStickData;
 
...
 
  AssignFile(joyfd, '/dev/input/js0'); // Immer js0???
  try
    Reset(joyfd);
    Read(joyfd, data);
    if data.Filler <> 2 then ERROR oder so
    Mach irgendwas mit data
  finally
    CloseFile(joyfd);
  end;
 
...


PS: wenn du einen C source findest den du nicht übersetzen kannst, kannst du das ganze auch einfach zu nem Object File kompilieren (gcc -o filename.c) und den dann in Pascal gegenlinken und dann die Funktionen aus dem C code aufrufen (mit nem wrapper): Schau mal hier

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: "Joystick"-Sensor Joywarrior 56FR1-WP abfragen

Beitrag von sstvmaster »

Hi att2,

auf der Seite: https://www.elefine.jp/SHOP/JW56FR1-WP.html habe ich eine exe für Windows gefunden und Sourcen: https://codemercs.com/downloads/joywarr ... R1_win.zip
Vielleicht ist ja was dabei, Maik
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Antworten