mikrocontroller.net

Forum: PC-Programmierung Java - RXTX => Wie weiterverarbeiten


Autor: dau45 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich probiere atm Messwerte von meinem AVR mit Java auszuwerten. 
Ich kann zwar einigermaßen in VB, C oder PHP programmieren aber OOP 
liegt mir einfach irgendwie nicht... Will es mir aber nun irgendwie 
beibringen, da ich es für die Schule brauche und Java allgemien sehr 
weit verbreitet ist...

Nun gut... Habe ich mir also die Libary sowie ein Beispielscript von 
http://www.rxtx.org/ runtergeladen und mit Eclipse ausprobiert. Da ich 
nicht alle funktionen benötige, habe ich das Script etwas entkernt.

Raus kam:
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;


public class new2
{
  public new2()
    {
        super();
    }
    
    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
                
                InputStream in = serialPort.getInputStream();
                
                (new Thread(new SerialReader(in))).start();
            }
            
    }
    
    public static class SerialReader implements Runnable 
    {
        InputStream in;
        
        public SerialReader ( InputStream in )
        {
            this.in = in;
        }
        
        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                  System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }    
        }
    }
    public static void main ( String[] args )
    {
        try
        {
            (new new2()).connect("COM3");
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }
  
}

So, dieses Script gibt mir nun meine Messwerte in der Konsole wunderbar 
aus. Ich möchte diese Werte aber weiterverarbeiten.

Ich möchte also irgendwie eine Funktion haben, die mir den aktuellen 
Messwert zurückliefert.

"System.out.print(new String(buffer,0,len));" gibt den aktuellen Wert in 
der Konsole aus, soviel ist mir klar. Also dacht ich mir: Mach ich 
"public void run" zu "public String run" und sage anstelle der Konsolen 
Ausgabe "return new String(buffer,0,len)" aber das funktioniert alles 
nicht wirklich... Wie bekomm ich das hin?

Autor: ozo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, das ist kein Skript, das ist erwachsenes Java.
Einfach nur die Rückgabe von main zu ändern ist sinnfrei.

Spezifiziere doch bitte deine Aussage "Ich möchte diese Werte aber 
weiterverarbeiten"

Willst du ein Program, daß du beispielsweise per Shell aufrufst und das 
dir bei jedem Aufruf einen (oder wegen mir x) gemessenen Wert ausgibt?
Oder willst du die Werte innerhalb von Java weiterverwenden?

Grüsse

Autor: dau45 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte die Werte innerhalb von Java weiterverarbeiten.

Zu diesem Zweck würde ich gerne einfach eine Funktion aufrufen können, 
die mir als Rückgabewert den zuletzt, über UART, empfangenen Wert 
liefert.

Ab da reichen meine Programmierkentnisse (hoffentlich) wieder :-)

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dau45 schrieb:
> "System.out.print(new String(buffer,0,len));" gibt den aktuellen Wert in
> der Konsole aus, soviel ist mir klar. Also dacht ich mir: Mach ich
Also das dir sonderlich viel von dem Klar ist was da passier bezweifel 
ich einfach mal ;)
Und ganz viel in eine Zeile schreiben mag zwar Cool sein, hilft einem am 
Anfang bei der Fehlersuche aber nicht wirklich...
public class SerialTest
{
    private static SerialReader reader;
    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
                
                InputStream in = serialPort.getInputStream();
                reader = new SerialReader(in);
                (new Thread(reader)).start();
            }
            
    }
    
    public static class SerialReader implements Runnable 
    {
        InputStream in;
        int last = 0;
        
        public SerialReader ( InputStream in )
        {
            this.in = in;
        }
        
        public void run ()
        {
            try
            {
                while(true) {
                    int read = in.read();
                    if(read > -1) {
                        last = read;
                    }
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }    
        }
        
        public int getLastValue() {
            return last;
        }
    }
    public static void main ( String[] args )
    {
        try
        {
            SerialTest test = new SerialTest();
            test.connect("COM3:");
            while(true) {
                int wert = reader.getLastValue();
                System.out.println("Aktueller Wert: "+wert);
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }
  
}
Das gibt dir die möglichkeit den aktuellen Wert auszulesen.. aber 
vorsicht: Bist du zu langsam gehen Werte verloren und du kannst nicht 
feststellen wann ein neuer Wert eintrifft. Wenn du sowieso zeichenweise 
Arbeiten willst, läßt sich das ganze einfacher machen:
public class SerialTest
{
    public static InputStream connect (String portName) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
        InputStream in = null;
        if ( commPort instanceof SerialPort ) {
            SerialPort serialPort = (SerialPort) commPort;
            serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
            in = serialPort.getInputStream();
        } else {
            throw new IOException(portName+ " ist kein Comport!");
        }
        return in;
    }

    public static void main ( String[] args )
    {
        try
        {
            SerialTest test = new SerialTest();
            InputStream in = test.connect("COM3:");
            while(true) {
                //Ein Zeichen von der Seriellen Schnittstelle lesen
                int wert = in.read();
                if(wert > -1) {
                    System.out.println("Neuer Wert:\n"+
                        "\tDezimal: "+wert+"\n"+
                        "\tZeichen: "+(char)wert+"\n"+
                        "\tHex: "+Integer.toHexString(wert)
                    );
                }
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }
  
}

Autor: Daniel F. (df311)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, ganz von anfang:

jede klasse, die runnable implementiert oder von thread abgeleitet ist, 
ist ein thread. jeder thread hat eine funktion "public void run()", die 
die eigentliche arbeit des threads erledigt. wenn die signatur von "run" 
geändert wird, funktioniert auch der thread nicht mehr.
in deinem fall liest der thread von der seriellen schnittstelle, bis die 
funtion "read" des inputstreams -1 zurückliefert (frag mich bitte nicht, 
unter welchen umständen das passiert -> doku).

wenn du die daten außerhalb des threads weiterverabeiten möchtest, musst 
du einen weg finden, diese nach außen weiterzugeben: stichworte 
(ring)pufferung, aktive weitergabe durch den thread, wait/notify, 
observer oder ähnliche techniken, wobei die ersten zwei die einfachsten 
lösungen sind.

der langen rede kurzer sinn:
du musst entweder in der run-methode eine andere funktion (in einem 
anderen thread) aufrufen, die die daten weiterverarbeitet, oder die 
daten im SerialReader buffern, bis sie von einem anderen thread 
verarbeitet werden.

Autor: dau45 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube, die Sache zu verstehen, wird für den Anfang ne Nnummer zu 
hard... Von daher schonmal danke @ Läubi für deine Mühe!

Dein erstes Programm liefert mit leider die Fehlermeldung
gnu.io.NoSuchPortException
  at gnu.io.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:218)
  at SerialTest.connect(SerialTest.java:14)
  at SerialTest.main(SerialTest.java:65)

Wenn ich aus "test.connect("COM3:")" "test.connect("COM3")" mache, läuft 
das Programm zumindest. Liefert jedoch immer den Dezimalwert "10", egal 
welchen Wert der AVR sendet.


Das 2. Programm liefert immer folgende Fehlermeldung:


[Code]
Exception in thread "main" java.lang.Error: Unresolved compilation 
problem:
  Cannot use this in a static context

  at SerialTest.connect(SerialTest.java:14)
  at SerialTest.main(SerialTest.java:31)
[Code]

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dau45 schrieb:
> Wenn ich aus "test.connect("COM3:")" "test.connect("COM3")" mache, läuft
Hab jezt nicht geschaut wie man den Comport angeben muß ohne : ist wohl 
korrekt.

> Das 2. Programm liefert immer folgende Fehlermeldung:
import java.io.*;
import gnu.io.*;

public class SerialTest {
    public InputStream connect (String portName) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        CommPort commPort = portIdentifier.open("Der Port gehört mir!", 2000);
        InputStream in = null;
        if ( commPort instanceof SerialPort ) {
            SerialPort serialPort = (SerialPort) commPort;
            serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
            in = serialPort.getInputStream();
        } else {
            throw new IOException(portName+ " ist kein Comport!");
        }
        return in;
    }

    public static void main ( String[] args )
    {
        try
        {
            SerialTest test = new SerialTest();
            InputStream in = test.connect("COM1");
            while(true) {
                //Ein Zeichen von der Seriellen Schnittstelle lesen
                int wert = in.read();
                if(wert > -1) {
                    System.out.println("Neuer Wert:\n"+
                        "\tDezimal: "+wert+"\n"+
                        "\tZeichen: "+(char)wert+"\n"+
                        "\tHex: "+Integer.toHexString(wert)
                    );
                }
            }
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }
    }
}
Hier mal was kompilierbares, hatte das mehr als ANREGUNG geschrieben 
das du siehst wie es prinzipiell funktioniert und habe es vorher nicht 
kompiliert... Du sollstest auf jedenfall versuchen zu verstehen warum 
das so gemacht wurde... Lektüre z.B.:
http://openbook.galileocomputing.de/javainsel8/

Autor: dau45 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin Läubi,

danke nochmals aber leider funktioniert das immernoch nicht. Es lässt 
sich zwar kompilieren aber liefert (wie dein erster Code) völlig falsche 
Werte... Der Mikrocontroller sendet z.B. aktuelle immer die momentane 
Temperatur (atm ca. 25). Der von mir gepostete Code und ein 
Terminalprogramm liefern da auch den richtigen Wert.

Dein erstes programmm hat immer 10 geliefert und dein zweites immer die 
Zahlenfolge 50, 53, 13, 10 und dann von vorn. Baud-Rate, Stop- / Data- 
sowie Paritätsbits sind richtig eingestellt. Genauso wie der Com-Port.

Ich werde später sicherlich probieren, das ganze zu verstehen aber für 
den Anfang in Java is das etwas schwer... Deshalb wollte ich mich 
erstweinmal der Verarbeitung der Werte witmen.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, dann schnappst du dir jezt eine ASCII Tabelle und schlägst mal 
nach was diese vier Zahlen als Zeichen darstellen, vieleicht dämmert es 
dir ja dann... Eigentlich hatte ich genau deshalb die Ausgabe in 
DEZ/ASC/HEX gemacht oder gibt er dir da dreimal das gleiche?

Und wie willst du Werte verarbeiten wenn du schon Probleme hast ein 
Zeichen zu empfangen und es dann richtig zu interpretieren? Das Wird 
schiefgehen und ein paar einfache Programme zum Einsteig (z.B. aus dem 
geposteten Tutorial) kosten auch nicht mehr Zeit als bei jeder neuen 
Hürde hier zu warten bis dir jemand antwortet.

Autor: dau45 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, ich sollte mal Kaffee kochen gehen...

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dau45 schrieb:
> Ach, ich sollte mal Kaffee kochen gehen...

:)

Naja hoffe geholfen zu haben :P

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.