Hi! Ich habe grad ein kleines C++ problem. Ich möchte ein kabel bauen das mir langzeitbelichtung mit einer EOS erlaubt. prinzipiell muss ich da nur einen schalter haben der angesteuert wird... alles kein problem. Das ansteuern geht über RTS eines seriellen ports. Nun hab ich mir aus der MS Hilfe mal eine kleine routine kopiert die die ports öffnet, und (da noch kein kabel) mit einem multimeter die pins gemessen. Im geschlossenen betrieb haben die Pins bei dem echten com1 eine spannung von ~ -11V. Ist der Port offen, sind es 11V. Das programm hab ich gestestet und es funktioniert. Nun aber das problem. Da ich das am Notebook machen will, und dieses weder seriell noch parallel hat, muss ich einen USB -> Seriell adapter dazwischen schalten. Dafür nehme ich den ELV UR - 100. Alles wieder verdrahtet zeigt mir im geschlossenen zustand -8.2V. Allerdings lässt sich der port mit dem selben c++ code nicht öffnen. Treiber sind installiert, im geräte manager wird mir auch ein neuer com port 3 angezeigt. Aber der Port geht einfach nicht auf. Mit einer speziellen software die auch dafür geschrieben wurde, klappt das, nur hab ich den code dieser software nicht, und will diese auch nicht benutzen. Das zeigt aber, aber die hardware in ordnung ist. Nun, muss ich beim ansprechen eines virtuellen ports irgendwas anders machen? hier der code, falls daraus was ersichtlich wird. DCB dcb; HANDLE hCom; BOOL fSuccess; TCHAR *pcCommPort = TEXT("COM3"); hCom = CreateFile( pcCommPort, GENERIC_WRITE, 0, // must be opened with exclusive-access NULL, // default security attributes CREATE_ALWAYS, // must use OPEN_EXISTING 1, // not overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (hCom == INVALID_HANDLE_VALUE) { // Handle the error. printf ("CreateFile failed with error %d.\n", GetLastError()); return (1); getchar(); } // Build on the current configuration, and skip setting the size // of the input and output buffers with SetupComm. SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); fSuccess = GetCommState(hCom, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return (2); } // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_57600; // set the baud rate dcb.ByteSize = 8; // data size, xmit, and rcv dcb.Parity = NOPARITY; // no parity bit dcb.StopBits = ONESTOPBIT; // one stop bit fSuccess = SetCommState(hCom, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return (3); } _tprintf (TEXT("Serial port %s successfully reconfigured.\n"), pcCommPort); ich muss dazu sagen, das ich mich im bereich hardwareansteuerung nicht wirklich auskenne, daher hab ich das von MS einfach nur kopiert und dann getestet obs läuft oder nicht. thx.
"Der Port geht einfach nicht auf" - was ist denn der Fehlercode, den CreateFile zurückgibt? Es gibt -von der Seite der Programmierung her- keinen Unterschied zwischen "virtuellen" seriellen Schnittstellen und "echten". Zumindest beim Überfliegen sehe ich im Code keine großen Probleme - allenfalls, wenn eine Schnittstelle mit einer Nummer größer 9 im System angesprochen werden soll, muss eine andere Syntax für den Gerätenamen verwendet werden -> "\\.\COM10" anstelle von "COM10". Aber das ist schon seit weit über einem Jahrzehnt in der Dokumentation von CreateFile beschrieben ...
Ich würde die DCB nicht löschen. Kann sein, dass du nicht alle Parameter setzt dann. Nimm sie wie sie ist und ändere nur deine Parameter.
Das tut er.
1 | SecureZeroMemory(&dcb, sizeof(DCB)); // 1 |
2 | dcb.DCBlength = sizeof(DCB); // 2 |
3 | fSuccess = GetCommState(hCom, &dcb); // 3 |
Zwar wird die Struktur in (1) nullinitialisiert angelegt, aber in (2) wird sie korrekt initialisiert und in (3) werden die aktiven Werte daraus kopiert. Das ist die korrekte Art des Umgangs mit dieser Struktur.
@Rufus Es gibt keine fehler meldung. Das Programm wird bis zur Ausgabe "Port has been reconfigured" etc. abgearbeitet, und ended wie es soll, ohne irgendeine fehlermeldung. Der Port geht einfach nur nicht auf (was ich halt daran sehe das ich zwischen pin 5 und 7 keine spannungsänderung messen kann)
Dann funktioniert alles. Solange Du nicht explizit dafür sorgst, daß auf den Handshakeleitungen etwas geschieht, wird auf ihnen auch nichts geschehen. Es gibt mehrere Arten, dafür zu sorgen, daß etwas auf den Handshakeleitungen geschieht: - Im Gerätemanager bei den Eigenschaften der jeweiligen Schnittstelle die "Hardwareflussteuerung" aktivieren (das wird bei Deiner USB-Seriell-Schnittstelle nicht aktiviert sein, bei den onboard-Schnittstellen aber schon) - "von Hand" an den Handshakeleitungen klappern (das geht mit beispielsweise mit EscapeCommFunction(hSerial, SETDTR)) - im DCB einstellen, daß die Hardwarehandshakeleitungen auch genutzt werden sollen (dafür sind die Elemente fOutxCtsFlow, fOutxDsrFlow, fDtrControl, fRtsControl etc. zuständig) Ersteres ist zunächst am einfachsten, aber am unzuverlässigsten. Deine Anwendung sollte, wenn sie denn wirklich Hardwarehandshake benötigt, sich auch selbst darum kümmern, den zu aktivieren.
Aber an meinem Com1 ist die hardwareflusssteuerung auch nicht aktiv, und trotzdem wird der port geöffnet wenn ich an dem "echten" port messe. Aber danke! :) Hab mal nach RTScontrol gegoogelt und ein simples dcb.fRtsControl = RTS_CONTROL_ENABLE; führt zum korrekten öffnen des ports :) thx!
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.