Hallo!
Im Rahmen meiner Studienarbeit bin ich auf diese Seite gestoßen. Unter anderem soll ich für ein (autonom fahrendes) Elektro-Modellauto eine Odometrie mit Hilfe von Lasermaussensoren implementieren. Da ich dafür so ca. 3cm Bodenfreiheit brauche, habe ich mich für die GeneralKeys Lasermaus mit 1200 dpi entschieden, nachdem ich diesen Forenbeitrag gelesen habe. Hab mir dann gleichzeitig noch die GeneralKeys Lasermaus mit 1600 dpi mitbestellt zum Vergleich. Ich habe dann festgestellt, dass die 1600er einen geringeren Abstand zum Boden ermöglicht als die 1200er. Wenn man aber die Laserdiode aus der Plastikoptik herausnimmt und sie in ungefähr dem gleichen Winkel wie zuvor neben den optischen Sensor hält, erreicht man einen Abstand bis zu ca. 10cm (bei mir jedenfalls). Unten seht Ihr, wie ich die Laserdiode dann mit Heißkleber befestigt habe (anderes Mausmodell, nicht irritieren lassen, aber gleicher Sensorchip). Damit ist Bodenfreiheit kein Problem mehr.
Mein Problem ist ein ganz anderes. Meine Hauptaufgabe ist es, mit Hilfe der Lasermaus die Geschwindigkeit des Fahrzeugs zu messen. Dazu lese ich mit einem C-Programm die Mausevents über USB unter Linux (Debian-Distribution, Problem tritt aber auch unter Ubuntu auf) aus. Das funktioniert auch soweit sehr gut. Allerdings liegt die maximale Geschwindigkeit, die ich momentan berechnen kann, bei ca. 24 cm/s.
Hier das Originalprogramm, mit dem ich die Mausevents auslese(von http://www.frogmouth.net):[/img]
Code:
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <asm/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <linux/input.h>
int main (int argc, char **argv) {
int fd = -1; /* the file descriptor for the device */
int yalv; /* loop counter */
size_t read_bytes; /* how many bytes were read */
struct input_event ev[64]; /* the events (up to 64 at once) */
/* read() requires a file descriptor, so we check for one, and then open it */
if (argc != 2) {
fprintf(stderr, "usage: %s event-device - probably /dev/input/evdev0\n", argv[0]);
exit(1);
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror("evdev open");
exit(1);
}
while (1)
{
read_bytes = read(fd, ev, sizeof(struct input_event) * 64);
if (read_bytes < (int) sizeof(struct input_event)) {
perror("evtest: short read");
exit (1);
}
for (yalv = 0; yalv < (int) (read_bytes / sizeof(struct input_event)); yalv++)
{
printf("Event: time %ld.%06ld, type %d, code %d, value %d\n",
ev[yalv].time.tv_sec, ev[yalv].time.tv_usec, ev[yalv].type,
ev[yalv].code, ev[yalv].value);
}
}
close(fd);
exit(0);
}
Interessant ist für mich momentan der Wert ev[yalv].value. Dieser Wert gibt das Bewegungsinkrement von einem Mausevent relativ zum vorigen Mausevant an. Der Wertebereich geht von -127 bis +127. Wenn man die Maus mit der Hand bewegt, muss man sich schon etwas anstrengen, um in diesen Bereich zu kommen, da man zwar hohe Beschleunigungen erreicht, aber keine hohen Geschwindikeiten, da man die Maus schnell wieder in die andere Richtung bewegt. Am Modellfahrzeug angebracht, erreicht man sehr schnell den Bereich der Sättigung. Daher ändere ich die Abtastrate über sudo modprobe -r usbhid ,danach modprobe usbhid mousepoll=8. Mousepoll kann die Werte 10, 8, 4, 2 oder 1 Annehmen (10 Standartwert), was einer Abtastrate von 100Hz, 125Hz, 250 Hz 500 Hz und 1000Hz entspricht (http://gentoo-wiki.com/TIP_Change_mouse_hz).
Je höher die Abtastrate, desto kleiner der ev[yalv].value-Wert, da für die gleiche Strecke der Untergrund öfter abgetastet wird. Man kann das Fahrzeug z.B. mit mousepoll=8 etwas schneller bewegen als mit dem Standartwert 10, ohne dass man in die Sättigung kommt. Das Hauptproblem ist, dass ich ab mousepoll=4 gar nicht bis in die Sättigung komme, sondern einen maximalen Wert von 106 (bei mousepoll=4) erhalte. Wenn ich das Fahrzeug noch etwas schneller schiebe, kommen willkürliche Werte wie -1 1, 2, -2 und ähnliches heraus. Bei mousepoll=2 liegt die Grenze bei etwa 60 für den Wert von ev[yalv].value.
Ein Gedanke von mir war, dass die doch recht billige Maus kein USB 2.0 beherrscht und somit die Beschränkung zu erklären sei. Das Problem tritt aber auch bei Mäusen mit USB 2.0 auf, die eine höhere Übertragungsrate und auch eine höhere Abfragerate haben.
Meine Frage ist daher, ob es irgendeine Möglichkeit gibt, diese Beschränkung zu umgehen oder die Mauswerte komplett anders auszulesen, so dass ich höhere Geschwindigkeiten als 24cm/s messen kann. Denn die USB2.0-fähige Maus, die ich getestet habe soll laut Hersteller eine Übertragungsrate bis zu 1000Hz sowie eine Bewegungsgeschwindigkeit von 128 cm/s schaffen.
Außerdem lässt sich bei ihr die Auflösung zwischen 400dpi, 800 dpi, 1600 dpi und 2000 dpi an der Maus selbst umschalten. Bei allen Werten bleibt mein Problem bestehen.
Achja, ich war auch mit meinem Notebook in ein paar elektronik- und PC-Läden und hab etliche Mäuse mit dem Programm ausprobiert, alle mit dem selben Ergebnis.
Fällt Euch dazu irgend etwas ein? Ich wäre in jedem Fall über Antworten sehr dankbar
MfG
Christian
Lesezeichen