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


von dau45 (Gast)


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:
1
import gnu.io.CommPort;
2
import gnu.io.CommPortIdentifier;
3
import gnu.io.SerialPort;
4
5
import java.io.IOException;
6
import java.io.InputStream;
7
8
9
public class new2
10
{
11
  public new2()
12
    {
13
        super();
14
    }
15
    
16
    void connect ( String portName ) throws Exception
17
    {
18
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
19
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
20
            
21
            if ( commPort instanceof SerialPort )
22
            {
23
                SerialPort serialPort = (SerialPort) commPort;
24
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
25
                
26
                InputStream in = serialPort.getInputStream();
27
                
28
                (new Thread(new SerialReader(in))).start();
29
            }
30
            
31
    }
32
    
33
    public static class SerialReader implements Runnable 
34
    {
35
        InputStream in;
36
        
37
        public SerialReader ( InputStream in )
38
        {
39
            this.in = in;
40
        }
41
        
42
        public void run ()
43
        {
44
            byte[] buffer = new byte[1024];
45
            int len = -1;
46
            try
47
            {
48
                while ( ( len = this.in.read(buffer)) > -1 )
49
                {
50
                  System.out.print(new String(buffer,0,len));
51
                }
52
            }
53
            catch ( IOException e )
54
            {
55
                e.printStackTrace();
56
            }    
57
        }
58
    }
59
    public static void main ( String[] args )
60
    {
61
        try
62
        {
63
            (new new2()).connect("COM3");
64
        }
65
        catch ( Exception e )
66
        {
67
            e.printStackTrace();
68
        }
69
    }
70
  
71
}

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?

von ozo (Gast)


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

von dau45 (Gast)


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 :-)

von Läubi .. (laeubi) Benutzerseite


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...
1
public class SerialTest
2
{
3
    private static SerialReader reader;
4
    void connect ( String portName ) throws Exception
5
    {
6
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
7
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
8
            
9
            if ( commPort instanceof SerialPort )
10
            {
11
                SerialPort serialPort = (SerialPort) commPort;
12
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
13
                
14
                InputStream in = serialPort.getInputStream();
15
                reader = new SerialReader(in);
16
                (new Thread(reader)).start();
17
            }
18
            
19
    }
20
    
21
    public static class SerialReader implements Runnable 
22
    {
23
        InputStream in;
24
        int last = 0;
25
        
26
        public SerialReader ( InputStream in )
27
        {
28
            this.in = in;
29
        }
30
        
31
        public void run ()
32
        {
33
            try
34
            {
35
                while(true) {
36
                    int read = in.read();
37
                    if(read > -1) {
38
                        last = read;
39
                    }
40
                }
41
            }
42
            catch ( IOException e )
43
            {
44
                e.printStackTrace();
45
            }    
46
        }
47
        
48
        public int getLastValue() {
49
            return last;
50
        }
51
    }
52
    public static void main ( String[] args )
53
    {
54
        try
55
        {
56
            SerialTest test = new SerialTest();
57
            test.connect("COM3:");
58
            while(true) {
59
                int wert = reader.getLastValue();
60
                System.out.println("Aktueller Wert: "+wert);
61
            }
62
        }
63
        catch ( Exception e )
64
        {
65
            e.printStackTrace();
66
        }
67
    }
68
  
69
}
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:
1
public class SerialTest
2
{
3
    public static InputStream connect (String portName) throws Exception
4
    {
5
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
6
        CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
7
        InputStream in = null;
8
        if ( commPort instanceof SerialPort ) {
9
            SerialPort serialPort = (SerialPort) commPort;
10
            serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
11
            in = serialPort.getInputStream();
12
        } else {
13
            throw new IOException(portName+ " ist kein Comport!");
14
        }
15
        return in;
16
    }
17
18
    public static void main ( String[] args )
19
    {
20
        try
21
        {
22
            SerialTest test = new SerialTest();
23
            InputStream in = test.connect("COM3:");
24
            while(true) {
25
                //Ein Zeichen von der Seriellen Schnittstelle lesen
26
                int wert = in.read();
27
                if(wert > -1) {
28
                    System.out.println("Neuer Wert:\n"+
29
                        "\tDezimal: "+wert+"\n"+
30
                        "\tZeichen: "+(char)wert+"\n"+
31
                        "\tHex: "+Integer.toHexString(wert)
32
                    );
33
                }
34
            }
35
        }
36
        catch ( Exception e )
37
        {
38
            e.printStackTrace();
39
        }
40
    }
41
  
42
}

von Daniel F. (df311)


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.

von dau45 (Gast)


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
1
gnu.io.NoSuchPortException
2
  at gnu.io.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:218)
3
  at SerialTest.connect(SerialTest.java:14)
4
  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]

von Läubi .. (laeubi) Benutzerseite


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:
1
import java.io.*;
2
import gnu.io.*;
3
4
public class SerialTest {
5
    public InputStream connect (String portName) throws Exception
6
    {
7
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
8
        CommPort commPort = portIdentifier.open("Der Port gehört mir!", 2000);
9
        InputStream in = null;
10
        if ( commPort instanceof SerialPort ) {
11
            SerialPort serialPort = (SerialPort) commPort;
12
            serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
13
            in = serialPort.getInputStream();
14
        } else {
15
            throw new IOException(portName+ " ist kein Comport!");
16
        }
17
        return in;
18
    }
19
20
    public static void main ( String[] args )
21
    {
22
        try
23
        {
24
            SerialTest test = new SerialTest();
25
            InputStream in = test.connect("COM1");
26
            while(true) {
27
                //Ein Zeichen von der Seriellen Schnittstelle lesen
28
                int wert = in.read();
29
                if(wert > -1) {
30
                    System.out.println("Neuer Wert:\n"+
31
                        "\tDezimal: "+wert+"\n"+
32
                        "\tZeichen: "+(char)wert+"\n"+
33
                        "\tHex: "+Integer.toHexString(wert)
34
                    );
35
                }
36
            }
37
        }
38
        catch ( Exception e )
39
        {
40
            e.printStackTrace();
41
        }
42
    }
43
}
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/

von dau45 (Gast)


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.

von Läubi .. (laeubi) Benutzerseite


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.

von dau45 (Gast)


Lesenswert?

Ach, ich sollte mal Kaffee kochen gehen...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

dau45 schrieb:
> Ach, ich sollte mal Kaffee kochen gehen...

:)

Naja hoffe geholfen zu haben :P

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.