Java Com lesen und schreiben

Gast #1939067
Lesenswert?

Hallo,

ich habe ein Programm für meinen Atmega8 geschrieben, der gibt mit, wenn 
ich ein 's' sende den ADC-Wert zurück - soweit geht dies im 
Hyperterminal.
Jetzt möchte ich dies jedoch in Java implementieren, um hier eine 
Temperatursteuerung zu bauen, jedoch weiss ich nicht, wie ich in Java 
gleichzeitig senden und empfangen kann?, ich denke hintereinander kann 
ich dies nicht machen?

Gruß
Pfeiffy
Gast #1939075
Lesenswert?

Wenn Du in Java etwas gleichzeitig machen willst ist die Klasse "Thread" 
dein Freund.
Alternativ kann man in einer Klasse das Interface "Runnable" 
implementieren.
Gute Onlinedoku über Java findet sich unter "Java ist auch eine Insel". 
Das ist ein Onlinebuch, das man sich auch runterladen kann.
Ausseredem solltest Du immer die Onlinereferenz der Java API offen 
haben.
Serielle Programmierung habe ich in Java noch nicht gemacht, da brauchts 
dann Rechner/Betriebssystemspezifische Module. Sollte aber kein 
hexenwerk sein, Google hilft da bestimmt weiter.
Bei Fragen : Hier rein posten
Gast #1939087
Lesenswert?

Hallo,

ja, suche - so einfach ist es auch nicht, habe ich gerade gemacht. Das 
problem ist, dass ich in Java praktisch gleichzeitig senden und 
Empfangen muss, das mache ich klar in einem Thread, aber der Comport ist 
eben beim senden dann durch das empfangen gesperrt - das ist die Frage.

Gruß
Pfeiffy
Gast #1939355
Lesenswert?

Pfeiffy schrieb:
> Das
> problem ist, dass ich in Java praktisch gleichzeitig senden und
> Empfangen muss,

Das sehe ich so noch nicht. Nur weil Du

Pfeiffy schrieb:
> der gibt mit, wenn
> ich ein 's' sende den ADC-Wert zurück

ein Zeichen schreibst und dann 2 Byte empfangen willst, brauchst du 
keine 2 Threads und gleichzeitiges schreiben und lesen.
Alleine die Hardware hat im PC schon 16 Byte Puffer, die Treiber werden 
das noch etwas vergrößern.
Wenn Dein Protokoll also nicht deutlich komplexer wird, würde ich mir 
das Multithreading an der Stelle sparen.
Gast #1939960
Lesenswert?

Hallo,
ok, com in Java war bis jetzt noch nicht so meine Welt, kannst du mir 
sagen, mit was für einem Befehl ich das mache?, das schreiben - worauf 
ich ja die 2 byte erwarte ist der Befehl:
1
outputStream.write("S".getBytes());

Gruß
Pfeiffy
Persönliche Seite #1939998
Lesenswert?

Also, das einlesen machst du am besten eventbasiert mit einem 
SerialPortEventListener.
Hier mal ein funktionsfähiges Quick&Dirty Beispiel:
1
public class SeriellTest implements SerialPortEventListener {
2

3
    private CommPortIdentifier portID;
4
    private SerialPort serport;
5
    private InputStream inputStream;
6
    private OutputStream outputStream;
7

8
    public SeriellTest() {
9
        try {
10
            portID = CommPortIdentifier.getPortIdentifier("COM1"); //oder /dev/ttyS0
11
            serport = (SerialPort) portID.open("foobar", 2000);
12
            serport.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
13
            inputStream = serport.getInputStream();
14
            outputStream = serport.getOutputStream();
15
            serport.addEventListener(this);
16
            serport.notifyOnDataAvailable(true);
17
        } catch (Exception e) {
18
            e.printStackTrace();
19
        }
20
    }
21

22
    public void serialEvent(SerialPortEvent evt) {
23
        if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
24
            try {
25
                StringBuffer readBuffer = new StringBuffer();
26
                int c;
27
                //lies bis \r\n
28
                while ((c = inputStream.read()) != 10) {
29
                    if (c != 13) {
30
                        readBuffer.append((char) c);
31
                    }
32
                }
33
                inputStream.close();
34
                String eingelesen = readBuffer.toString();
35
                //mach was mit den eingelesenen Daten
36
            } catch (IOException e) {
37
                e.printStackTrace();
38
            }
39
        }
40
    }
41
}
Persönliche Seite #1940052
Lesenswert?

Pfeiffy schrieb:
> kannst du mir sagen, wie ich dann den String ("S") mitgeben kann?

genauso, wie du es schon geschrieben hast, ich hab dir ja im Konstruktor 
schon einen OutputStream angelegt.

Jetzt fügst du z.B. noch eine Funktion ein:
1
private void schreibeAufSeriell(String foo) {
2
        try {
3
            outputStream.write(foo.getBytes());
4
            outputStream.flush();
5
            outputStream.close();
6
        } catch(IOException e) {
7
            e.printStackTrace();
8
        }
9
    }
Gast #1940273
Lesenswert?

Hallo,
ich kanns leider erst heute Abend direkt mit dem AVR testen, aber so 
stelle ich es mir vor:
1
import gnu.io.*;
2

3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.io.OutputStream; //import java.io.OutputStream;
6
import java.util.Enumeration;
7
import java.util.TooManyListenersException;
8

9
//import OeffnenUndSenden.serialPortEventListener;
10

11
public class SeriellTest implements SerialPortEventListener {
12

13
  private CommPortIdentifier portID;
14
  private SerialPort serport;
15
  private InputStream inputStream;
16
  private OutputStream outputStream;
17
  static String empfangen;
18
  
19
  
20
  public static void main(String[] args)
21
  {
22
    SeriellTest st = new SeriellTest();
23
    st.schreibeAufSeriell("s");
24
    System.out.println("empfangen: " + empfangen);
25
  
26
  }
27

28
  
29
  
30
  public SeriellTest() {
31
    try {
32
      portID = CommPortIdentifier.getPortIdentifier("COM1"); // oder
33
                                  // /dev/ttyS0
34
      serport = (SerialPort) portID.open("foobar", 2000);
35
      serport.setSerialPortParams(4800, SerialPort.DATABITS_8,
36
          SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
37
      inputStream = serport.getInputStream();
38
      outputStream = serport.getOutputStream();
39
      serport.addEventListener(this);
40
      serport.notifyOnDataAvailable(true);
41
    } catch (Exception e) {
42
      e.printStackTrace();
43
    }
44
  }
45

46
  public void serialEvent(SerialPortEvent evt) {
47
    if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
48
      try {
49
        StringBuffer readBuffer = new StringBuffer();
50
        int c;
51
        // lies bis \r\n
52
        while ((c = inputStream.read()) != 10) {
53
          if (c != 13) {
54
            System.out.println("empfange");
55
            readBuffer.append((char) c);
56
          }
57
        }
58
        inputStream.close();
59
        empfangen = readBuffer.toString();
60
        // mach was mit den eingelesenen Daten
61
      } catch (IOException e) {
62
        e.printStackTrace();
63
      }
64
    }
65
  }
66

67
  private void schreibeAufSeriell(String foo) {
68
    try {
69
      outputStream.write(foo.getBytes());
70
      outputStream.flush();
71
      outputStream.close();
72
    } catch (IOException e) {
73
      e.printStackTrace();
74
    }
75
  }
76
  
77
}

das heisst: sofort nach meinem senden, sendet der AVR, welches sofort in 
den String "empfangen" übergeben wird und ich kann den empfangenen 
String  benutzen.

Gruß
Pfeiffy
Persönliche Seite #1940316
Lesenswert?

Di Pfe schrieb:
> aber, um etwas zu empfangen muss ich ja zuerst senden, durch das senden
> löse ich somit ja erst den serial-event aus.

Ja.
Der Event kommt aber irgendwann, deshalb musst du in der Methode auf 
das Ereignis reagieren.
Du kannst nicht davon ausgehen, dass deine Daten sicher zwischen der 
Ausführung der beiden Zeilen
1
st.schreibeAufSeriell("s");
2
System.out.println("empfangen: " + empfangen);
ankommen.
#1940317
Lesenswert?

Dann so?: nach dem empfangen abfragen, was ich gesendet habe?
1
import gnu.io.*;
2

3
import java.io.IOException;
4
import java.io.InputStream;
5
import java.io.OutputStream; //import java.io.OutputStream;
6
import java.util.Enumeration;
7
import java.util.TooManyListenersException;
8

9
//import OeffnenUndSenden.serialPortEventListener;
10

11
public class SeriellTest implements SerialPortEventListener {
12

13
  private CommPortIdentifier portID;
14
  private SerialPort serport;
15
  private InputStream inputStream;
16
  private OutputStream outputStream;
17
  static String empfangen;
18
  static String gesendet; // was habe ich gesendet
19
  static String temp1;
20
  static String temp2;
21

22
  public static void main(String[] args) {
23
    SeriellTest st = new SeriellTest();
24
    gesendet = "s";
25
    st.schreibeAufSeriell(gesendet);
26
    System.out.println("empfangen: " + empfangen);
27

28
  }
29

30
  public SeriellTest() {
31
    try {
32
      portID = CommPortIdentifier.getPortIdentifier("COM1"); // oder
33
      // /dev/ttyS0
34
      serport = (SerialPort) portID.open("foobar", 2000);
35
      serport.setSerialPortParams(4800, SerialPort.DATABITS_8,
36
          SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
37
      inputStream = serport.getInputStream();
38
      outputStream = serport.getOutputStream();
39
      serport.addEventListener(this);
40
      serport.notifyOnDataAvailable(true);
41
    } catch (Exception e) {
42
      e.printStackTrace();
43
    }
44
  }
45

46
  public void serialEvent(SerialPortEvent evt) {
47
    if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
48
      try {
49
        StringBuffer readBuffer = new StringBuffer();
50
        int c;
51
        // lies bis \r\n
52
        while ((c = inputStream.read()) != 10) {
53
          if (c != 13) {
54
            System.out.println("empfange");
55
            readBuffer.append((char) c);
56
          }
57
        }
58
        inputStream.close();
59
        empfangen = readBuffer.toString();
60

61
        // Verarbeite die Temperaturen.......
62
        verarbTemp(empfangen, gesendet);
63

64
        // mach was mit den eingelesenen Daten
65
      } catch (IOException e) {
66
        e.printStackTrace();
67
      }
68
    }
69
  }
70

71
  private void schreibeAufSeriell(String foo) {
72
    try {
73
      outputStream.write(foo.getBytes());
74
      outputStream.flush();
75
      outputStream.close();
76
    } catch (IOException e) {
77
      e.printStackTrace();
78
    }
79
  }
80

81
  void verarbTemp(String empfangen, String gesendet) {
82

83
    // hier könnte ich abfragen, was ich gesendet habe
84
    if (gesendet == "s") {
85
      // der empfangene Wert ist die Temperatur an Punkt1
86
      temp1 = empfangen;
87
      // schreibe Temp1 weg
88

89
    }
90
    if (gesendet == "t") {
91
      // der empfangene Wert ist die Temperatur an Punkt2
92
      temp2 = empfangen;
93
      // schreibe Temp1 weg
94

95
    }
96

97
  }
98

99
}
Persönliche Seite #1940329
Lesenswert?

Wenn du jetzt noch endlich
1
System.out.println("empfangen: " + empfangen);

aus main() entfernen würdest, klappts wahrscheinlich sogar.
Ich würde an deiner Stelle gleich noch ganz auf die globale Variable 
"empfangen" verzichten, das verwirrt in der Konstellation nur.

Aber denk dran, dass dein AVR bei dem Code seine Strings mit \r\n 
abschliessen muss.
Gast #1940934
Lesenswert?

Hallo,
nun habe ich doch noch einen Fehler drinnen, ich kann das Programm 1 mal 
starten, aber beim nächsten mal ist der comport belegt, das ist ja blöd, 
da ich noch keine gui habe und beim stoppen keinen windows-event 
abfangen kann muss ich das Programm über die Kommandozeile stoppen, dann 
bleibt der comport wahrscheinlich offen - kann ich den irgendwie im PC 
wirder freigeben?

Gruß
Pfeiffy
Gast #1942910
Lesenswert?

Hallo,
ja ich habe herausgefunden: ich habe das Programm in eclipse laufen 
lassen und hier nur den Prozess nach dem beenden nicht gestoppt, da ich 
ja nur 1 mal sende, aber immer auf Bereitschaft bin. Lösung: entweder 
den Prozess im Eclipse stoppen oder ein system.exit(0) einbauen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren