ASCII über serielle Schnittstelle

Hallo,

ich schreibe gerade ein Programm, das über eine serielle Schnittstelle mit einer Anlage kommuniziert.
Für Testzwecke bilde ich diese Anlage nach. Die zwei Programme laufen auf Windows 7 64bit Rechnern, welche über die serielle Schnittstelle verbunden sind. Strings habe ich bereits über die Schnittstelle versenden können.
Zur Kommunikation nutze ich die RXTX API.
Die Anlage schickt die Daten als ACSII Zeichen an mein Programm. Später sollen diese ASCII Zeichen in Bit umgewandelt werden.
Meine Frage ist nun, wie man mit der RXTX API ASCII übertragen kann. Hat jemand eine Idee oder ein bisschen Code zur Orientierung.

Danke im Voraus :slight_smile:

Strings schicken ist doch ASCII, wo ist also das Problem?

Über die RXTX-Api kommst Du zunächst “nur” an den InputStream zum Lesen bzw OutputStream zum Schreiben heran. Streams sind byte-basiert. Um von Java aus textbasiert zu lesen/schreiben, musst Du Reader/Writer verwenden. Am Beispiel “Lesen” sieht das dann so aus:


// Hier sagst Du Java, dass über den InputStream Zeichen mit Charset ASCII kommen.
// Für ASCII gibt es im JDK eine Konstante (java.nio.charset.StandardCharsets.US_ASCII).
Reader streamReader = new InputStreamReader(comIn, StandardCharsets.US_ASCII);

Schreiben ist analog, halt nur mit OutputStream und OutputStreamWriter. Abhängig vom Anwendungsfall kann es noch Sinn machen, den InputStreamReader/den OutputStreamWriter einem BufferedReader/BufferedWriter als Konstruktorparameter zu übergeben und die Lese-/Schreiboperationen auf diesen auszuführen.

Edit: Habe jetzt nochmal die Eröffnungsfrage gelesen. Dafür ist meine Antwort wohl etwas umfangreich. Ich denke, das Entscheidende, was Dir gefehlt hat war, dass man das Charset bei der Erzeugung von Reader/Writer mitgeben kann. Dazu der generelle Tipp, sich mit der API des JDK zu beschäftigen und nicht einfach nur Beispielcode abzutippen. Hilfreich sind dabei die Vervollständigungsvorschläge Deiner IDE oder ein Blick in die Java-Docs: http://docs.oracle.com/javase/7/docs/api/index.html?overview-summary.html

[off-top]
Mir ist ja bekannt das RS232 immer noch genutzt wird, gerade bei so Späßen wie CNC-Maschinen oder älteren Geräten als “Wartungs-Connector”, und ich denke auch das die Technik auf Grund der Einfachheit dieser Schnittstelle damit noch lange arbeiten wird, aber ist es nicht mal Zeit aus dem ewigen Märchen der 80er aufzuwachen und in die Realität der 2010er zu kommen ?
Ich denke am allereinfachsten wären da Dinge 802.11 oder Ethernet und darauf dann IP. Oder ähnliches High-Level-Zeugs. Klar ist mir auch bewusst das man z.B. für ein NIC und einen IP-Stack schon mal ein bisschen mehr braucht, aber das sind heute Pfennig-Artikel und es gibt für verschiedene Bausteine auch fertige Software die dann über Brücken-Chips (man siehe z.B. Arduino oder Raspi) an die eigentliche Hardware anzuschließen.
Mir stellt sich da ernsthaft die Frage : ist es wirklich wirtschaftlicher auf einen ur-alt-Standard zu setzen und sich dafür die Mühe zu machen irgendwie von modernen Systemen die dies halt eben nicht mehr unterstützen irgendwelche Krücken a la USB-RS232 zu basteln anstatt einmal auf Stand 2014 zu kommen und mit etablierten Standards wie IP zu arbeiten ?

— EDIT —

@TO
Vermeide Cross-Postings.
-> [noparse]http://www.java-forum.org/netzwerkeprogrammierung/162549-ascii-ueber-serielle-schnittstelle.html[/noparse]

[quote=Sen-Mithrarin]@TO
Vermeide Cross-Postings.
-> http://www.java-forum.org/netzwerkeprogrammierung/162549-ascii-ueber-serielle-schnittstelle.html[/quote]

Cross-Postings sind kein Problem. Allerdings die Bitte: Wenn das Problem in einem anderen Forum gelöst wurde, dann poste auch hier die Lösung.

@Sen-Mithrarin : RXTX liefert einen InputStream, ein Socket auch. Das Problem wäre dort für den TO wohl genauso erhalten. Und ganz so einfach wie einem Arduino und co. einem das vorgaukeln ist es nicht immer mit WLan etc. Einfacher als mit RS232 wird es nie.

ähm, nein - das ist eine reine Kostenfrage

klar, für einen Bastler sind 0,10€ nicht viel, im Gegenteil - ich würde sogar noch ein bischen mehr drauf legen, 2€/3€. Denke aber mal bitte im industriellen Maßstab. Bei einer Stückzahl von 100.000 sind 0,10€ „nur“ 10.000€ am Ende. Bei 2€ sind das dann doch schon 200.000€. Und 100.000 sind nur eine kleine Stückzahl. Also reine marktwirtschaftliche Interessen.

Klar - ein „bisschen“ - lwIP - A Lightweight TCP/IP stack - Summary [Savannah] das ist etwas mehr als ein „bisschen“. Gerade wenn ich das Vergleiche mit dem was im µC für RS232/485 zu machen ist:

[ol]
[li]schreibe das Byte an die entsprechende Stelle des µC[/li][li]wenn Interrupt „Byte versendet“, schreibe nächstes Byte[/li][li]wiederhole 2 solange noch Bytes verfügbar sind[/li][/ol]

Fast jeder µC kann Daten über eine interne RS232/485 Schnittstelle verschicken. Für Ethernet brauchts dann wiederum zusätzliche Hardware. Die über andere Schnittstellen angesprochen werden müssen.

Einen Pegelwandler braucht man aber schon noch - das war es dann aber auch. Ansonsten stimme ich dir 100% zu.

Wenn du z.B. Zulieferer für BMW bist, ist die Stückzahl >1.000.000 da macht sich auch schon jeder einzelne Cent bemerkbar,…
Aber der TO hatte ja nichts davon geschrieben ob es Beruflich, Private, eine von Ihm Entwickelte Anlage geht,…
Vielleicht unterstützt die Anlage nun mal nur dieses Format, sich jetzt einen extra PC bauen, der als Zwischenstück eingesetzt werden kann um von TCP/IP auf RS232 zu formatieren ist dann denke ich alles andere als eine Sinnvolle Lösung, wenn der PC doch schon RS232 kann und in der Entwicklung unter Java ist das ziemlich egal ob RS232 oder TCP/IP.

ja :slight_smile: - SPHINX Computer - MOXA NPort 5110 - unheimlich praktisch die Dinger

Die gibt’s auch für die Hut-Schiene. Habe ich schon eingesetzt…

bye
TT

Genau das war es :slight_smile: Danke

Jetzt fehlt doch noch eine Kleinigkeit…
Angenommen ich sende den ASCII Wert „Z“ wandelt mir der Empfänger den Wert richtig in den Hexwert 5A um.
Wenn ich jedoch ^Q bzw. dc1 sende, wird jedes einzelne Zeichen in den entsprechenden Hexwert umgewandelt :frowning:
Wisst ihr da weiter?

[quote=itgirl]Wenn ich jedoch ^Q bzw. dc1 sende, wird jedes einzelne Zeichen in den entsprechenden Hexwert umgewandelt[/quote]Ist logisch, wenn es so im String steht:"^Qdc1". Du musst die entsprechenden Java-Escape-Sequenzen benutzen (also deren Representation als UTF16 Code-Point).

bye
TT

[QUOTE=Timothy_Truckle;101422]Ist logisch, wenn es so im String steht:"^Qdc1". Du musst die entsprechenden Java-Escape-Sequenzen benutzen (also deren Representation als UTF16 Code-Point).
[/QUOTE]
Macht Sinn. Wie kann ich denn z.B. ^Q maskieren?

Wüsste nicht, dass der Reader/Writer das erkennt.

Aber wenn ohnehin:

warum liest und schreibst Du nicht direkt aus/in die Bytes in die Streams?

Ich muss gestehen das mir die Frage auch in den Sinn kam : Warum unbedingt ASCII wenn nachher eh nur auf Bit-Ebene gearbeitet wird ?
Ich gehe mal von aus das hier von Gegenseite irgendein möchtegern-protokoll-Murks begangen wird der halt irgendwas in Richtung Übertragungssicherheit gewährleisten sollte.
Findet man leider viel zu oft : statt das man gleich ein eigenes Protokoll auf byte-ebene anbietet versucht man erstmal umständlich irgendwie über darstellbare Zeichen (also Strings) was rumzuwursten und dann selbst manuell umzurechnen.

Noch cooler, und schon auf dem Weg aus China zu mir:
http://www.seeedstudio.com/depot/WiFi-Serial-Transceiver-Module-w-ESP8266-p-1994.html
(siehe auch Wlan2Serial Modul für 5 euro - Mikrocontroller.net)

Das ist das Problem. Mit Bytes wüsste ich, wie ich arbeiten müsste, aber das Protokoll schreibt etwas anderes vor.

Aber scheinbar versteht es „^Q bzw. dc1“ als String nicht? Sondern erwartet hier ein 0x11

Außerdem habe ich das so verstanden, dass das Protokoll ASCII verwendet und nicht Strings? Daher müsstest Du ohnehin Deine Strings vorher in ASCII übersetzen und die Bytes senden. Ich weiß allerdings nicht, ob es da etwas fertiges das Steuerzeichen in Strings korrekt als ASCII interpretiert.

Letztendlich ist es ja egal in welcher Form Du von Deiner Seite aus sendest. Die Information wird als Bytes übertragen und die Gegenseite interpretiert diese Bytes als XY (eben abhängig vom Protokoll) von daher ist es der Gegenstelle egal, ob Du über irgendwelche Wrapper Strings verwendest oder direkt Bytes in den Stream steckst - das entscheidende ist, dass Du Dich ans Protokoll hältst, damit die Gegenstelle die Information korrekt interpretieren kann.