[RXTX] GPS-Maus (Comport) effizient auslesen

tobi193

Aktives Mitglied
Hallo,

ich habe mir so eine nette kleine GPS-Maus gekauft, die mit dem mitgelieferten Treiber über einen virtuellen Com-Port ausgelesen werden kann. Das klappt auch soweit ganz gut mit folgendem Quelltext:
Java:
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.TooManyListenersException;

public class GPS implements SerialPortEventListener{

	private CommPortIdentifier serialPortId;
	private Enumeration enumComm;
	private SerialPort serialPort;

        private final int baudrate = 4800;
        private final String portName = "COM7";
        private BufferedReader br;

	public GPS(){

            if(openSerialPort()){
                try{
                    serialPort.addEventListener(this);
                    serialPort.notifyOnDataAvailable(true);
                }catch(TooManyListenersException ex){}
            }
	}

        public static void main(String[] args){
            new GPS();
        }

	public boolean openSerialPort(){
            boolean foundPort = false;
            enumComm = CommPortIdentifier.getPortIdentifiers();
            while(enumComm.hasMoreElements()) {
                    serialPortId = (CommPortIdentifier) enumComm.nextElement();
                    if(portName.contentEquals(serialPortId.getName())) {
                            foundPort = true;
                            break;
                    }
            }
            if(!foundPort)
                    return false;

            try{

                serialPort = (SerialPort) serialPortId.open(this.getClass().getName(),2000);
                serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                br = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
            }catch(Exception e){
                return false;
            }
            return true;
	}

        public void serialEvent(SerialPortEvent event){
            switch (event.getEventType()){
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY: break;
            case SerialPortEvent.DATA_AVAILABLE:
                try{
                    System.out.println(br.readLine());
                }catch(IOException ex){}
                break;
            }
        }
}

Das dumme ist, in der Konstellation werden recht immense 50% Systemlast beansprucht. Das auf einem flotten DualCore.
Ich habe auch die folgende Methode ausprobiert:

Java:
String line;
while((line = br.readLine()) != null){
  System.out.println(line);
}

Mit oder ohne kurzem schlafenlagen, es kommt aufs gleiche hinaus. Ledeglich lange Wartezeiten schaffen Abhilfe, dann wird aber der Empfang verzerrt bzw. setzt in bestimmten Intervallen aus, das ist also keine gute Lösung.

Wie kann ich also das ganze effizient auslesen ?

Gruß tobi
 
Ich habe nun noch weiter herumprobiert und zunächst Wartezeiten eingebaut. Das führte dann aber nach längerem ausführen zu einem Stau und damit GPS Positionen aus der Vergangenheit.
Daher warte ich einfach alle 10 Sekunden nur 25ms. Damit hat man einen Kompromiss der so aussieht:
Java:
        public void run(){
            try{
                log.println("<gpx version=\"1.1\" creator=\"My Software\">");
                log.println("<rte>");
                String s = "";
                while(true){
                    int c = inputStream.read();
                    if(c != 10){
                        s += (char) c;
                    }else{
                        if(s.startsWith("$GPGGA")){
                            try{
                                String[] split = s.split(",");
                                GeoPosition gp = new GeoPosition(convertLat(split[2], split[3]), convertLon(split[4], split[5]));
                                for(GPSListener gl : listener){
                                    gl.neuePosition(gp);
                                }
                                log.println("<rtept lat=\"" + gp.getLatitude() + "\" lon=\"" + gp.getLongitude() + "\"></rtept>");
                                time++;
                                if(time < 10){
                                   Thread.sleep(1000);
                                }else{
                                    Thread.sleep(25);
                                    time = 0;
                                }
                            }catch(Exception e){}
                        }
                        s = "";
                    }
                }
            }catch(Exception e){
                System.err.println("GPS auslesen Fehler: " + e.getMessage());
            }
        }

Dummerweise habe ich beim Test gerade eben draußen feststellen müssen, dass hin und wieder einige Punkte an der selben Stelle liegen, obwohl ich gelaufen bin. Daher gab es Unterbrechungen und einen "Messpunktehaufen" von bis zu rund 50 Stück.
Liegt das einfach am Empfang oder kann das irgendwie auch mit dem Auslesen zu tun haben ?

Gruß
 
Lass doch mal den Eventhandler weg und nutze nur dein BufferedReader#readline. Das DataAvailable braucht dich da ja nicht interessieren.
notifyOnDataAvailable dann natürlich auch false.
 
Zuletzt bearbeitet:
Hallo ich bin noch absoluter JAVA Anfänger und würde ebenfalls gern eine GPS Maus auslsen ,

ich habe mir den Quelltext kopiert und eingefügt (eclipse oberfläche)

Wenn ich das Programm starten möchte bekomme ich immer die Fehlermeldung , dass ich die rxtx API nicht richtig eingefügt habe , zumindest deute ich das daraus ;D

java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver
Exception in thread "main" java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at gnu.io.CommPortIdentifier.<clinit>(CommPortIdentifier.java:83)
at GPS.openSerialPort(GPS.java:40)
at GPS.<init>(GPS.java:26)
at GPS.main(GPS.java:35)

Was mache ich falsch ? Ich habe über > Properties > Build Path die RXTXcomm.jar zu meinem Projekt hizugefügt aber es funktioniert nicht . ???:L
 
Hm so nach dem da ist rxtxserial eine dll die gesucht und nicht gefunden wird.

und ohne jetzt genau jeden Link zu lesen hier dürftest du herausfinden wie du die dll einbinden musst.
 

Zurück
Oben