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.
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
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
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?
> 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)
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.
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.
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....
das schon aber wenn der eine mit 115200 empfängt und der andere nur mit 9600 sendet... Hast du irgendwann einen Pufferüberlauf....
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
ä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...
@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?
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.
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.
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? :)
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.
Hab mal was angefangen (in Java) http://www.jan-hendrikbade.de/com_bridge/index.php UNBEDINGT Liesmich.txt beachten!
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.
Was kommt denn überhaupt auf der Konsole an? Bzw. kannst du die Ausgabe hier mal posten?
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?
hmm muss ich mal noch ei9n paar Debug Ausgaben einfügen... Aber da kommt dauernd was auf der Schnittstelle?
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...
Unter Java kann man vorm lesen fragen wieviele Bytes man den lesen kann...(ohne zu blockieren) Vlt. gibts bei dir sowas auch...
Hm ok, genau so etwas bräuchte ich. Dann schaue ich nochmal, ob ich so etwas finden kann.
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.
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.
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.
CSerialPort::InitPort() mit der geeigneten Baudrate (3. Parameter) aufrufen? Was soll da nicht gehen?
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.
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?
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.
@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...
ach so das hattest du nicht erwähnt... wo hast du serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT); eingefügt?
habs gefunden... das flush() hab ich auch hinzugefügt.... 0.2.0 * Flusskontrolle hinzugefügt http://www.jan-hendrikbade.de/com_bridge/index.php
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.