Forum: PC-Programmierung USB Serial Port Weiterleitung


von Christian N. (spaetsommerkind)


Lesenswert?

Hallo,

nachdem ich bislang nichts Passendes zu diesem Thema finden konnte, 
versuche ich hier mal mein Glück:

Ich habe ein Bluegiga (Bluetooth Funkmodul), das per seriellem Kabel an 
COM1 meines PCs angeschlossen ist. Jetzt möchte ich aber gerne, dass die 
Daten, die an COM1 ankommen auf den USB Serial Port weitergeleitet 
werden und umgekehrt. Ist das möglich? Ich glaube, aus dem was ich 
bislang gelesen habe ging hervor, dass das so nicht geht. Aber wenn das 
so ist würde ich gerne mal genauer wissen, warum nicht geht.

Eben habe ich noch gelesen, dass einfache Portweiterleitung unter DOS 
auch mit copy com1: comx: möglich ist. Das geht dann aber nur in eine 
Richtung, richtig? Und vermutlich schon gar nicht mit dem USB Serial 
Port?

Würde mich über eine Antwort sehr freuen.
Mit freundlichen Grüßen,
Christian N.

von MichiB (Gast)


Lesenswert?

Hi Christian,

wenn ich dich richtig verstanden habe, dann brauchst du doch einfach nur 
sowas:

http://www.pollin.de/shop/detail.php?pg=OA==&a=NTY5ODcyOTk=&w=Njg4OTM5&ts=120

von Christian N. (spaetsommerkind)


Lesenswert?

Hallo,

vielen Dank für die Antwort. Da habe ich mich undeutlich ausgedrückt. 
COM1 und ein USB Port sind bei mir bereits belegt und zwar einmal mit 
einem seriellen Kabel (COM1) und mit einem USB Dongle (COM5). Die Daten, 
die an COM1 ankommen sollen jetzt PC intern weitergeleitet werden an den 
COM5 Port, so dass die Daten letztendlich bei dem Dongle landen (und 
umgekehrt). Ich brauche keine Hardwarelösung.


Viele Grüße,
Christian

von Gast (Gast)


Lesenswert?

dazu müsste man ein Prog basteln was die Daten von einem Port nimmt und 
zum anderen weiterschickt (und umgekehrt)

Wenn Interesse kann ich das mal probieren...

Welchen  Baudraten?

von Christian R. (supachris)


Lesenswert?


von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Sowas? http://com0com.sourceforge.net/

Im Prinzip ja, nur nicht als Kopplung zweier virtueller 
Schnittstellen, sondern zweier realer Schnittstellen. (Ja, die 
USB-Seriell-Bridge wird oft auch "virtuell" genannt, ist aber realer als 
die von com0com implementierte)

von Christian N. (spaetsommerkind)


Lesenswert?

Genau darum geht es (Kopplung zweier realer Schnittstellen) und ich 
wundere mich warum ich so etwas nicht finden kann. Deswegen habe ich 
inzwischen vermutet, dass das so aus irgendwelchen Gründen nicht 
realisierbar ist. Aber es stimmt schon, es spricht ja eigentlich nichts 
dagegen sich da selber ein Programm für zu basteln (Baudrate: 115200) 
und die Daten vom COM1 zu lesen und auf den COM5 zu schreiben und 
umgekehrt... Aber das kann ich dann auch erstmal selber probieren, bevor 
da jemand seine Zeit für opfert.

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Genau sowas suche ich auch gerade. Habs mit meinen bescheidenen C++ 
Kenntnissen leider nicht hinbekommen so ein Programm zu schreiben.

Bitte sag bescheid wenn du es hinbekommst.

von Christian R. (supachris)


Lesenswert?

Naja, ganz so einfach ist das ja nicht. Was machst du z.B. wenn ein 
Gerät eine höhere Baudrate hat? Für einen ganz speziellen Fall, wenn 
alle Randbedingungen eingehalten werden, ist das sicher schnell gemacht, 
aber wenn´s universell sein soll, wird´s schon schwierig....

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Dann macht man die Baudrate für beide Ports halt einstellbar.

von ... .. (docean) Benutzerseite


Lesenswert?

das schon aber wenn der eine mit 115200 empfängt und der andere nur mit 
9600 sendet...

Hast du irgendwann einen Pufferüberlauf....

von df311 (Gast)


Lesenswert?

naja, das problem mit den geschwindigkeitsunterschieden kann man auf 
verschiedene arten lösen (bzw. versuchen zu lösen):
1. konstanter datenfluss: hier muss entweder eine flusskontrolle her 
(XON/XOFF oder hardware - rts/cts bzw. dtr/dsr) oder man akzeptiert 
einfach, dass man die geräte sowieso nie zusammenstöpseln könnte, ohne 
daten zu verlieren.
2. "blockweiser" datenfluss: hier kann zu einem gewissen grad das 
"übersetzungsprogramm" mit einem eigenen puffer eingreifen und die daten 
als pseudo-konstanten datenfluss weiterleiten; allerdings ist auch in 
diesem fall eine flusskontrolle nicht verkehrt.

das große problem bei verwendung der hardware-flusskontrolle ist, dass 
sie nur mit "echtem" rs232-verkehr funktioniert, über usb überhaupt 
nicht, da ganz einfach keine leitungen dafür vorhanden sind.
die verwendung von software-flusskontrolle ist wiederum abhängig von der 
art der übertragenen daten (ascii/binär), wobei bei binärdaten wiederum 
(meistens) keine flusskontrolle möglich ist, da XON/XOFF auch als 
nutzdaten vorhanden sein können

von df311 (Gast)


Lesenswert?

ähm, wenn ein teilnehmer mit 115200 empfängt und der andere mit 9600 
sendet gibts maximal leere puffer, keinen überlauf ;-)
von sinn und unsinn unterschiedlicher geschindigkeiten mal abgesehen...

von Christian R. (supachris)


Lesenswert?

@df311

Also meine FT232 USB-Serialports haben alle Leitungen dran, die auch 
eine normale COM-Schnittstelle hat. Incl. Hardware-Handshake. Und das 
funktioniert auch. Es liegt also nicht am USB, sondern daran, ob die 
Leitungen herausgeführt sind.

Und wenn der 115k Teilnehmer dauerhaft Daten sendet, die du an den 
9600er weitergeben musst? Was passiert dann?

von E. B. (bergere)


Lesenswert?

Ich habe ein ähnliches Problem.

Und zwar habe ich meinen PC der Daten über COM-1 sendet (wobei da ein 
USB-Serial Adapter dran hängt). Diese Daten erreichen meinem Atmega128 
und führen dort die jeweilige Aktion aus. Nun soll mein PC aber erstmal 
keine Daten mehr schicken bis der Atmega fertig mit arbeiten ist und 
wartet von daher auf eine spezielle Nachricht vom Atmega. Kommt die 
Nachricht bei meinem PC an dann darf dieser wieder einen Befehl an den 
Atmega senden.

Das Problem ist folgendes. Ich nutze unter Windows das Robot Terminal 
mit welchem alles einwandfrei funktioniert. Ich kann senden und 
empfangen.

Arbeite ich jedoch unter Linux dann kann ich zwar Daten von meinem PC 
auf die Leitung senden aber keine empfangen? (Nutze hierzu ein 
selbstgeschriebenes Terminal) Und zwar überhaupt keine. Ich habe schon 
den Atmega zum Dauersender umprogrammiert aber mein Buffer im PC bleibt 
unter Linux komplett leer. Es kommt überhaupt gar nichts an.

Merkwürdig.

Naja vielleicht hatte jemand von euch schonmal das selbe Problem. Ach 
und ich nutze 8Bit Daten und 1Stop Bit und keine Parität. Ist im Atmega 
und im meinem  selbstgeschrieben Terminal Programm unter Linux ebenfalls 
so festgelegt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann dürfte das Problem entweder im nicht richtig funktionierenden 
Devicetreiber der USB-Seriell-Bridge für Linux liegen, oder aber (und 
viel wahrscheinlicher) im selbstgeschriebenen Terminalprogramm für 
Linux.

Das kannst Du leicht selber testen, indem Du die RXD- und TXD-Leitungen 
des USB-Seriell-Adapters miteinander verbindest (und nichts weiter 
anschließt).

Was Dein Terminalprogramm sendet, muss es auch wieder empfangen. Tut es 
das nicht, ist es kaputt. Oder der Treiber.

von Christian N. (spaetsommerkind)


Lesenswert?

Also ich habe jetzt diese MFC Klasse gefunden: 
http://lamp.codeproject.com/KB/system/cserialport.aspx und ich denke 
mal, dass man sich damit ganz gut die gewünschte Anwendung 
zusammenbasteln kann. Ich bin nicht wirklich fit was die C++ 
Programmierung angeht, aber ich werde jetzt mal ein bißchen damit 
rumspielen. Vielleicht ist ja auch jemand schneller als ich? :)

von yalu (Gast)


Lesenswert?

Solltest du zufälligerweise Cygwin installiert haben, kannst du
gewünschtes ganz leicht mit socat machen:
1
socat /dev/ttyS0 /dev/ttyS4

Evtl. sind noch ein paar Optionen zur Änderung der Schnittstellen-
parameter erforderlich.

Cygwin nur wegen socat zu installieren ist aber vielleicht etwas mit
Kanonen auf Spatzen geschossen.

von ... .. (docean) Benutzerseite


Lesenswert?

Hab mal was angefangen (in Java)

http://www.jan-hendrikbade.de/com_bridge/index.php

UNBEDINGT Liesmich.txt beachten!

von Christian N. (spaetsommerkind)


Lesenswert?

Hi, schon mal vielen Dank, dass du dir die Mühe gemacht hast und den 
Code zur Verfügung gestellt hast. Bei mir funktioniert das Ganze aber 
irgendwie noch nicht. Ich bekomme zwar keine Fehlermeldung, aber die 
angelegten Daten kommen auch nicht da an, wo sie hin sollten.

von ... .. (docean) Benutzerseite


Lesenswert?

Was kommt denn überhaupt auf der Konsole an?

Bzw. kannst du die Ausgabe hier mal posten?

von Christian N. (spaetsommerkind)


Lesenswert?

Ausgabe:
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
Port gefunden: COM1
Port gefunden: COM6
197


Am Anfang scheint ja sogar ein Zeichen übertragen worden zu sein. Der 
COM6 ist allerdings ein USB Serial Port. Könnte es vielleicht daran 
liegen?

von ... .. (docean) Benutzerseite


Lesenswert?

hmm muss ich mal noch ei9n paar Debug Ausgaben einfügen...

Aber da kommt dauernd was auf der Schnittstelle?

von Christian N. (spaetsommerkind)


Lesenswert?

Ja, kommt es. Hast du es denn mal bei dir ausgetestet? Ich habe mir die 
Implementierung jetzt noch nicht genauer angesehen, aber ich habe zur 
Zeit bei meinen Visual C++ Versuchen die Schwierigkeit, dass ich auf 
einen Port nicht gleichzeitig lesend und schreibend zugreifen kann. Der 
Befehl zum Lesen blockiert einen Port aber so lange, bis dort auch 
tatsächlich etwas ankommt. Ich muss also erst immer abfragen, ob ein 
Event an einem Port ausgelöst wurde, dann erst schauen, ob auf den Port 
gerade von meinem zweiten Thread zugegriffen wird und darf erst danach 
den Buffer auslesen. Nur scheinbar wird beim Lesen immer genau eine 
bestimmte Byte-Anzahl ausgelesen. Wenn die nicht im Buffer vorliegt, 
wird so lange gewartet, bis die Bytes auch ausgelesen werden können und 
damit ist dann der Port für den zweiten Thread wiederum blockiert und es 
geht nicht mehr weiter. Also das Ganze ist scheinbar wirklich nicht so 
trivial wie es aussieht...

von ... .. (docean) Benutzerseite


Lesenswert?

Unter Java kann man vorm lesen fragen wieviele Bytes man den lesen 
kann...(ohne zu blockieren)

Vlt. gibts bei dir sowas auch...

von Christian N. (spaetsommerkind)


Lesenswert?

Hm ok, genau so etwas bräuchte ich. Dann schaue ich nochmal, ob ich so 
etwas finden kann.

von Christian N. (spaetsommerkind)


Lesenswert?

Es gibt eine neue Version der CSerialPort Klasse: 
http://www.naughter.com/serialport.html

Da gibt es dann auch eine Funktion, um zu überprüfen, wieviele Bytes im 
Buffer liegen und das klappt auch wunderbar. Aber es hängt noch an 
anderer Stelle. Ich habe die WaitEvent Funktion verwendet, um zu 
überprüfen, ob Daten eingetroffen sind. Diese Funktion blockiert aber 
scheinbar den Schreibzugriff auf den entsprechenden Port. Das sollte 
doch eigentlich nicht sein. Ich habe es dann auch mal mit der Funktion 
CSerialPort::DataWaiting ausprobiert, die ja eigentlich nur eine gewisse 
Zeit den Port überwachen sollte. Aber auch diese Funktion hängt so 
lange, bis Daten an den Port angelegt werden. Das verstehe ich nicht.

von Christian R. (supachris)


Angehängte Dateien:

Lesenswert?

Ich benutze immer eine leicht abgewandelte Variante der Klasse hier:
http://www.codeguru.com/Cpp/I-N/network/serialcommunications/article.php/c2483

Im Anhang meine Version, die alle (virtuellen und echten) COM-Ports von 
1 bis 255 benutzen kann, und beliebige Binärdaten senden kann.
Funktioniert einwandfrei, nicht blockierend durch Thread. Kannst ja 
einfach 2 davon benutzen, und alles transparent weiter leiten. Sollte in 
wenigen Minuten zusammen geklickt sein.

von Christian R. (supachris)


Angehängte Dateien:

Lesenswert?

Noch die Header-Datei dazu.

von Christian N. (spaetsommerkind)


Lesenswert?

Was mache ich denn, wenn ich eine Baudrate von 115200 einstellen will? 
Das geht nämlich nicht und ich weiß nicht, wo ich das ändern kann.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

CSerialPort::InitPort() mit der geeigneten Baudrate (3. Parameter) 
aufrufen?

Was soll da nicht gehen?

von Christian N. (spaetsommerkind)


Lesenswert?

Wobei, ich verstehe das Ganze nicht. Ich dachte, du meinst die 
CommTest-Datei, aber das kann ja nicht sein. Du hast ja geschrieben, 
dass man 255 Ports benutzen kann. Was meinst du denn mit 
zusammenklicken? Ich stehe gerade auf dem Schlauch.

von Christian R. (supachris)


Lesenswert?

Was geht wo nicht? Bei "meiner" Klasse kann man eine x-beliebige 
Baudrate einstellen. ich fahr mit den USB-Serialports immer 460.800 oder 
921.600 baud problemlos.
Zusammenklicken meinte ich eine kleine MFC-Anwendung, die 2 Instanten 
der SerialPort Klasse hat, die "über kreuz" verbunden sind.
Was für ein CommTest?

von Christian N. (spaetsommerkind)


Lesenswert?

Sorry für die Verwirrung: ich hatte die Demoapplikation unter 
http://www.codeguru.com/Cpp/I-N/network/serialcommunications/article.php/c2483 
heruntergeladen und ausprobiert und dachte, du sprichst davon.

Habe noch nie eine MFC-Anwendung zusammengeklickt, aber das scheint ja 
wirklich nicht so schwierig zu sein. Werde mich also mal daran 
versuchen.

von Christian N. (spaetsommerkind)


Lesenswert?

@docean:

Ich habe mir nochmal deine Com Bridge angesehen. Bei mir hat das nicht 
funktioniert, weil ich einen Hardware Handshake brauchte.
Nachdem ich noch die Zeile
1
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
hinzugefügt hatte, funktonierte es fast. Danach musste ich noch die 
Daten mit
1
outputfremd.flush();
flushen. Jetzt sieht es eigentlich ganz gut aus, allerdings bekomme ich 
scheinbar doch noch nicht exakt hinten das heraus, was vorne angelegt 
wird. Mal sehen, ob ich noch fündig werde...

von ... .. (docean) Benutzerseite


Lesenswert?

ach so das hattest du nicht erwähnt...

wo hast du
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | 
SerialPort.FLOWCONTROL_RTSCTS_OUT);

eingefügt?

von ... .. (docean) Benutzerseite


Lesenswert?

habs gefunden...

das flush() hab ich auch hinzugefügt....

0.2.0

    * Flusskontrolle hinzugefügt

http://www.jan-hendrikbade.de/com_bridge/index.php

von Christian N. (spaetsommerkind)


Lesenswert?

So, ich bins nochmal... Also die com_bridge funktioniert eigentlich 
jetzt wunderbar, aber eben doch irgendwie nicht so, dass sie meine 
Zwecke erfüllen würde.

Ich habe eine Applikation, die auf einen Com Port zugreift. Wenn ich die 
Applikation beende und mir anschaue, wie die Applikation den Port 
initalisiert hat, sieht das so aus:

Baudrate: 115200
Parität: none
Datenbits: 1
Zeitlimit: ON
XON/XOFF: OFF
CTS-Handshaking: OFF
RTS-Handshaking: OFF
DSR-Handshaking: OFF
DTR-Handshaking: OFF
DTR-Signal: ON
RTS-Signal: ON

Jetzt möchte ich die com_bridge dazwischen schalten, sie müsste also den 
Port mit den gleichen Einstellungen initialisieren. Wenn ich jetzt die 
com_bridge mit dem gleichen Port benutze, habe ich folgende 
Unterschiede:

Zeitlimit: OFF
RTS-Handshaking: ON
RTS-Signal: OFF

Wenn ich die com_bridge ohne Hardware-Steuerung benutze, ist das 
RTS-Handshaking = OFF. Aber das RTS-Signal bekomme ich auch mit
1
serialPort.setRTS(true);
 nicht umgeschaltet. Meine Applikation funktioniert mit der 
dazwischengeschalteten com_bridge jedenfalls nicht und ich vermute, dass 
es an den Einstellungen liegt, denn die Datenübertragung klappt 
eigentlich.

Hat jemand eine Idee, was ich noch anders machen könnte?

von Christian R. (supachris)


Lesenswert?

Christian N. wrote:

> Ich habe eine Applikation, die auf einen Com Port zugreift. Wenn ich die
> Applikation beende und mir anschaue, wie die Applikation den Port
> initalisiert hat, sieht das so aus:
>
> Baudrate: 115200
> Parität: none
> Datenbits: 1
> Zeitlimit: ON
> XON/XOFF: OFF
> CTS-Handshaking: OFF
> RTS-Handshaking: OFF
> DSR-Handshaking: OFF
> DTR-Handshaking: OFF
> DTR-Signal: ON
> RTS-Signal: ON

Wo siehst du das denn? Die Einstellungen, die im Gerätemanager von 
Windows stehn, sind nicht die, die das programm eingestellt hat.

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.