Forum: PC-Programmierung Serielle Schnittstelle ansprechen unter win95 mit Visual C++


von michi (Gast)


Lesenswert?

Hallo Leute,
ich bin langsam an verzweifeln, suche jetzt schon den halben Tag ein
vernünftiges Beispiel oder eine DLL oder irgendwelche Hinweise womit
ich die Serielle Schnittstelle unter Win95, mit Visual C++, anprechen
kann.
Hab jede Menge DLLs und sonstige Code Schnippsel in mein Programm
eingefügt aber es tragen immer irgendwelche Fehler auf mit denen ich
nichts anfangen könnte, denn so sehr hab ich C noch nicht drauf.
Soweit ich weiß braucht man unter Win95 noch keine DLL um mit den Ports
zu sprechen, ich kann die Ports eigentlich mit dem befehl _outp und
_inp, das funkt auch mit dem LPT ganz gut, aber mit der Seriellen geht
das nicht. ich muss den wohl erst noch initialisieren oder so was?!?!?

Hat jemand nützliche Hinweise, oder am besten noch ein gut lesbares
Beispiel wo ich mir ein wenig abkupfern kann?
mfg michi

von Tobi (Gast)


Lesenswert?

für die serielle braucht man inter keinem windows eine dll. wird wie
eine datei angesprochen mit createfile und COMx als dateiname. weiteres
in der vc++ hilfe

von Rufus T. Firefly (Gast)


Lesenswert?

www.codeproject.com, suchen nach CSerialPort.
Das ist eine MFC-Klasse, die die Win32-API-Funktionen zum Behandeln der
seriellen Schnittstelle kapselt - es muss schon etwas mehr gemacht
werden, als nur mit CreateFile 'ne Datei aufzumachen (Handshake,
Baudrate etc.)

Die serielle Schnittstelle sollte man auf gar keien Fall mit direkten
I/O-Zugriffen ansprechen - einerseits sind die I/O-Adressen nur bei
COM1 und COM2 überhaupt standardisiert, andererseits muss man sich auch
um das Interrupthandling kümmern, da ohne Interrupts kaum sinnvoll mit
der seriellen Schnittstelle gearbeitet werden kann.
DOS ist zum Glück nun wirklich vollkommen tot (da musste man sowas noch
machen), und Betriebssysteme -sogar die Pseudobetriebssysteme wie
Windows 95/98/Me- haben dafür stabil und vernünftig funktionierende
Devicetreiber.

Der Einsatz von Devicetreibern ermöglicht es auch, serielle
Schnittstellen mit völlig anderer Hardware anzusprechen, ohne auf deren
Aufbau eingehen zu müssen (PCI-Karten oder gar USB-Seriell-Adapter).

von michi (Gast)


Angehängte Dateien:

Lesenswert?

Ok eigentlich wollte ich es ja auf die einfache tour machen, mit
_outp().., aber es kann ja auch nicht schaden wenn ich gleich eine
vernüpftige ansteuerung des COM Ports mache.
Um das kurz vorweg zu nehmen, meine Hardware die am COM Port dranhängt
verarbeitet kein Handshaking usw. wie macht nichts las empfangen.
So, ich hab jetzt nur die datei serialport.h in mein Programm
eingebunden, und schon hab ich 28 Fehler, was nun?
Genau aus diesem Grund habe ich schon vor 9 Stunden, mir lieber was
anderes gesucht, als mir die ganze Zeit den Kopf zu zerbrechen warum da
nun Fehler sind?!!!!
Kann mir jemand weiterhelfen?
mfg

von Tobi (Gast)


Lesenswert?

du hast vergessen windows.h einzubinden. da winken die compilermeldungen
ja schon geradezu mit dem virtuellen zaunfahl wenn der alle nicht ansi-c
datentypen(?) nicht findet

von michi (Gast)


Angehängte Dateien:

Lesenswert?

Wie gesagt, ich hab C noch nicht so gut drauf und was BOOL ist weiss ich
nicht!
Hab jetzt <windows.h> eingebunden, und hab auch 0 Fehler und Warnungen.
Wie mache ich jetzt weiter? Wie kann ich die COM Schnittstelle öffen und
wie kann ich Daten Senden und Empfangen?

Ich hab mal versucht das Beispiel welches auf
http://www.codeproject.com/system/cserialport.asp zu finden ist, in
mein Programm eingefügt, und wieder gibt es fehler....

--------------------Konfiguration: Camdriver - Win32
Debug--------------------
Kompilierung läuft...
main.cpp
D:\Elektronik\Kamera\Camdriver\main.cpp(12) : error C2143:
Syntaxfehler : Fehlendes ';' vor 'try'
D:\Elektronik\Kamera\Camdriver\main.cpp(12) : error C2143:
Syntaxfehler : Fehlendes ';' vor '{'
D:\Elektronik\Kamera\Camdriver\main.cpp(12) : error C2447:
Funktionskopf fehlt - Parameterliste im alten Stil?
D:\Elektronik\Kamera\Camdriver\main.cpp(25) : error C2143:
Syntaxfehler : Fehlendes ';' vor 'catch'
D:\Elektronik\Kamera\Camdriver\main.cpp(26) : error C2143:
Syntaxfehler : Fehlendes ';' vor '{'
D:\Elektronik\Kamera\Camdriver\main.cpp(26) : error C2447:
Funktionskopf fehlt - Parameterliste im alten Stil?
Fehler beim Ausführen von cl.exe.

Camdriver.exe - 6 Fehler, 0 Warnung(en)

von Tobi (Gast)


Lesenswert?

1. wenn du bool nicht kennst, cursor drüber und f1 drücken. das sollte
man doch schon kennen

2. vielleicht solltest du mit null vorwissen lieber ersteinmal klein
anfangen und die sprache lernen bevor du dich an soetwas ran wagst

3. man bekommt über f1 auch zu compilerfelern hilfe

von michi (Gast)


Lesenswert?

Tschuldigung das ich um Hilfe gebeten hab! Ich bin kein Informatiker,
nur ein kleiner dummer E-Techniker der erst ein Semester C hatte und
seiner blöden MC Schaltung übern PC steuern will. Gäbe es Bill Gates
nicht hätten wir es alle viel leichter im leben. Vielleicht sollte ich
doch mal auf Linux umsteigen, aber da fehlt mir eben die Zeit mich da
einzuarbeiten.

von René König (Gast)


Lesenswert?

Das hat nichs mit Bill Gates zu tun. Das liegt daran, daß Du den
Funktionscode ausserhalb der Funktion stehen hast. Auch unter Linux
darfst Du Deinen Code nicht einfach so zusammenhangslos im Raume stehen
lassen.

@Tobi
bool != BOOL

von Jürgen Schuhmacher (Gast)


Lesenswert?

Sioe Dir mal www.wxWidgets.org an. Damit kannst du direkt in Win UND
Linux programmieren. Auf www.iftools.com findest Du meine Anleitung zum
Arbeiten mit der seriellen Schnittstelle. Im original sind direkt
Beispielprogramme. Der Vorteil dieser Lib: Der erzeugte Code läuft auf
allen Windowsversionen. Du kannst aber auch ein einfaches Beispiel mit
DEV-CPP benutzen - in ganz rudimentärem C, ohne Objektorientierung.

von Rufus T. Firefly (Gast)


Lesenswert?

Es ist kein Wunder, daß der Compiler hier Fehlermeldungen ausspuckt:

  void main()
  {
  }

  try {
      CSerialPort port;
      port.Open(1, 1200, CSerialPort::NoParity, 8,
        CSerialPort::OneStopBit,
        CSerialPort::XonXoffFlowControl);

  ... etc.


Du hast hier außerhalb von main() einen try/catch-Block angeordnet.

Versuch das doch mal in der Funktion main() unterzubringen.

Bill Gates ist das nicht in die Schuhe zu schieben, auch unter Linux
funktioniert das so nicht.

von michi (Gast)


Angehängte Dateien:

Lesenswert?

@Rufus klar kann das nicht gehen kann, aber innerhalb von main geht es
auch nicht!

Das ist mir jetzt auch alles scheiß egal!!! Ich habe die Lösung für
alle dummen E-Techniker gefunden!!!
http://members.inode.at/anton.zechner/az/Seriell.htm
Hier ist alles über die serielle Schnittstelle beschrieben in Deutsch,
und sogar ein kleines Tool welches man in sein Programm einbinden kann
und mit vielen Beispielen wie das Programm funktionier :o)
Das ganze läuft mit dem CreateFile.. ReadeByte...WriteByte...usw. Und
jetzt kommts! Alles lauf ohne Fehler!!!! Aber ich hab noch ein....es
läuft auch mit WINXP!!!!!! :o))))
mfg

von Tobi (Gast)


Lesenswert?

genau diesen lösungsweg hab ich im 2. post geschrieben... naja, egal

von Rufus T. Firefly (Gast)


Lesenswert?

"@Rufus klar kann das nicht gehen kann, aber innerhalb von main
 geht es auch nicht!"

Ich hab' mir das mal näher angesehen. Verschiebt man den
catch/try-Block in die Funktion main(), so spuckt der Compiler
sinnvolle Fehlermeldungen wie

  c:\test-prj\camdrive\main.cpp(13) : error C2039: 'NoParity' : is
not a member of 'CSerialPort'
        c:\test-prj\camdrive\serialport.h(23) : see declaration of
'CSerialPort'

aus. Kein Wunder, das ist da ja auch nicht definiert. In serialport.h
steht nicht sehr viel drin.

Du verwendest jede Menge Definitionen, die überhaupt nicht zu Deiner
Klasse CSerialport passen - und genau das sagt Dir Dein Compiler.


Wo bitte hast Du Deinen CSerialport-Sourcecode her?

Wenn Du auf Codeproject den Suchbegriff cserialport eingegeben hättest,
wäre der erste Link dieser hier gewesen:

  http://www.codeproject.com/system/cserialport.asp

Den meinte ich.

Davon abgesehen musst Du auch serialport.cpp zum Projekt hinzufügen,
aber das ist jetzt ja wohl eh' irrelevant.



Insgesamt stellt sich mir allerdings die Frage, warum ich überhaupt
versucht habe, Dir zu helfen, wenn Dir doch alles "scheiß egal!!!"
ist.

Reduziere mal die Anzahl der von Dir verwendeten Ausrufungszeichen,
sonst wird mir noch schlecht.

von First Borg (Gast)


Lesenswert?

Hi
Ich wollte auch sowas versuchen, aber unter Visual Studio 2003 .NET
unter Win Xp.
Habe auch das Cserial entdeckt... aber das funktioniert nicht... es
gibt fehler wie c:\Programme\Microsoft Visual Studio .NET
2003\Vc7\include\serialport.h(31): error C2504: 'CException':
Basisklasse undefiniert

oder auch Dword wurde schonmal als "nicht deklariert" bezeichnet
etc...

eine idee was zu tun ist? Oder wie das mit Visual Studio internen
möglichkeiten geht?

von Chris (Gast)


Lesenswert?

<ot>
Ich kann einfach nicht verstehen, wieso jemand hundert(e) von Euro
ausgibt für ein Programm wie Visual Studio .NET 2003, um dann an
elementaren Problemen zu scheitern.

Darf ich fragen, wieso du dir so ein großes und teures Programm kaufst,
nur um Code für den COM-Port mittels copy&paste zu kompilieren zu
versuchen?

Ich möchte niemandem etwas unterstellen, aber das klingt fast nach:
"wie kann ich in 3DSMax eine Kugel erstellen?!!1"
Bei so einer Frage hätte ich berechtigte Zweifel, ob der Fragesteller
3DSmax wirklich gekauft hat. Das macht nämlich niemand, der an einer
Kugel scheitert.
</ot>

Lern C (oder C++).
Gilt für den OP und für dich.

Man kann es nicht oft genug wiederholen: Ohne Grundkenntnisse in einer
Programmiersprache kann man nicht gescheit programmieren. Man wird
immer wieder über grundlegende Fehler stolpern, die mit nur ein paar
Grundkenntnissen sofort offensichtlich wären.

von First Borg (Gast)


Lesenswert?

Ich habe Grundkentnisse in C++ (wir machen grad nen Kurs in der Uni,
aber in dem ist der Zugriff auf Ports nicht vorgesehen).

Und gekauft in dem Sinne ist es auch nicht... Unsere Uni ist im MSDNAA
Programm, und dabei darf man sich das ganz offiziell von MS downloaden
wenn man Student an der Uni ist.

von Tobi (Gast)


Lesenswert?

habt ihr denn den zugriff auf dateien über createfile usw gehabt? dann
kannst du auch auf ports zugreifen. falls du noch die guten alten dos
tage kennst wirst du wissen,dass es da keinen unterschied gibt

von onkel Tuca (Gast)


Lesenswert?

High
ich hab für meine abschluss arbeit eine relaiskarte ansteueren müssen
und ein 4byte frame schiken müssen der spass funktioniert wie unten
gezeigt mann kann sicherlcih auch andere sachen damit machen
tja ich wünsch dir was ...
/*/*/*/*/*/*/*/**/*/*/*/**/*/*/*/*/*/*/**/*/*/*/*/*/**/
 DCB dcb;
   HANDLE hComm;
   BOOL fSuccess;
   char *pcCommPort = "COM1";

   hComm = CreateFile( pcCommPort,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // no security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    0,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );

   if (hComm == INVALID_HANDLE_VALUE)
   {
       // Handle the error.
       printf ("CreateFile failed with error %d.\n",
GetLastError());

   }

   // Build on the current configuration, and skip setting the size
   // of the input and output buffers with SetupComm.

   fSuccess = GetCommState(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n",
GetLastError());

   }

   // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

   dcb.BaudRate = CBR_19200;     // 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(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n",
GetLastError());

   }
   else
   {
       char frame[4];
  frame[0] = 1;
  frame[1] = 1;
  frame[2] = 0;
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);
  DWORD dwBytesWritten = 0;
   WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);
     //TransmitCommChar(hComm,frame);
  frame[0] = 3;
  frame[1] = 1;
  frame[2] = 4;
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);

   WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);
BOOL bResult;


  DCB dcb_alt;
  SetCommState(hComm, &dcb_alt);

  bResult = CloseHandle(hComm);
  hComm   = INVALID_HANDLE_VALUE;
   }
/*/*/*/*/*/*/*/**/*/*/*/*/**/*/*/*/*
happy greetings

von philip (Gast)


Lesenswert?

kannst du das auf 8 byte erweitern ? und zeigen wo die bytes sind die du
da sendest? also einfach kommanteiren byte 0-7 ?

von Rufus T. Firefly (Gast)


Lesenswert?

WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);

Das geht schief. Statt (BYTE)frame sollte da die Anzahl der zu
schreibenden Bytes stehen. Hier also der Wert vier. Besser noch: sizeof
(frame).

von philip (Gast)


Lesenswert?

kann einer das programm auf 8 bit umschreiben?
und die bits wenn möglich in nen string oder so packen so das ich die 8
bits gleich zusammen habe? arrys sind mist :(
ich bekomme es nicht hin versuchs scho die ganze nacht und komm immer
noch nicht weiter

von icke (Gast)


Lesenswert?

8bit?, Arrays sind Mist und 'Strings' sind es nicht?. Du weißt doch
sicher, daß ein String ein Array ist?...
Ich hoffe du willst hier nen Gag landen.

Was er sendet steht in frame[], den kannst du vergrößern und z.B auch 8
Byte(!) in einen Übertragungsblock packen. Aber dann solltest du daran
denken, wie in Rufus Post steht steht WriteFile(..) auch die größere
Größe anzugeben. Mit sizeof(frame) ists natürlich quasi automatisch.

von keksohr (Gast)


Lesenswert?

ne nen gang wolte ich hier net machen... bin noch nicht so lange mit c++
dabei.. komme aber stückweise immer weiter :)

ja okay dasn string eigendlichn arry ist okay hast gewonnen ;)

öhm ja das mit dem sizeof(frame) hab ich drin, hab das ganze nun auf
ein sende befehl umgebaut und gleich dann auf 8array erweitert
was ich nicht verstehe so ganz ist die zeile hier :

 frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);

   WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);

kann einer mal bitte die 2 zeilen genau erklären ?!

von icke (Gast)


Lesenswert?

in frame[] werden die Werte erzeugt, die gesendet werden sollen.
frame[3] ist vielleicht als so ne Art checksumme gedacht, wo die
anderen 'ge xored' werden und gecasted.
Freme kannst du auch wie gesagt mehr Einträge verpassen.

WriteFile macht den IO. Wenn du über WriteFile mehr wissen möchtest,
empfehle ich in die MS-Hilfe zu gucken. Aber du erkennst ja, daß da der
Handle auf die Schnittstelle steht, die du oben ja geöffnet hast, ein
Zeiger auf die Daten die gesendet werden sollen, sowie die Anzahl der
zu sendenden Zeichen. Das sind die ersten drei und wichtigsten
Parameter. Fürs weitere wie gesagt: MS-Hilfe.

von keksohr (Gast)


Lesenswert?

//#include <cstdlib>
#include <windows.h>
//#include <string.h>
//#include <stdio.h>
#include <iostream.h>
#include <conio.h>
#include <dos.h>
//#include <stdlib.h>
#include <time.h>
#include <unistd.h>
//#include <string>




int main()
{

 DCB dcb;
   HANDLE hComm;
   BOOL fSuccess;
   char *pcCommPort = "COM1";

   hComm = CreateFile( pcCommPort,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // no security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    0,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );

   if (hComm == INVALID_HANDLE_VALUE)
   {
       // Handle the error.
       printf ("CreateFile failed with error %d.\n",
GetLastError());

   }

   // Build on the current configuration, and skip setting the size
   // of the input and output buffers with SetupComm.

   fSuccess = GetCommState(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n",
GetLastError());

   }

   // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

   dcb.BaudRate = CBR_9600;     // 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(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n",
GetLastError());

   }
   else
   {
       char frame2[4];
       char frame[8];
  frame[0] = 1;
  frame[1] = 0;
  frame[2] = 1;
  frame[3] = 1;
  frame[4] = 1;
  frame[5] = 0;
  frame[6] = 1;
  frame[7] = 1;
  frame[8] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2] ^
frame[3] ^ frame[4] ^ frame[5] ^ frame[6]  ^ frame[7]);
  DWORD dwBytesWritten = 0;
   WriteFile(hComm, &frame, sizeof(frame), &dwBytesWritten, NULL);
     //TransmitCommChar(hComm,frame);
  frame2[0] = 3;
  frame2[1] = 1;
  frame2[2] = 4;
   WriteFile(hComm, &frame, sizeof(frame2), &dwBytesWritten, NULL);


  BOOL bResult;

  DCB dcb_alt;
  SetCommState(hComm, &dcb_alt);
  bResult = CloseHandle(hComm);
  hComm   = INVALID_HANDLE_VALUE;
   }

cout << "Done...";
cout << endl ;
getch();
return 0;
}


auch wenn ich den unteren teil raus nehme, klappt es nich so wie es
soll.. er sendet zwar aber hmm meine schaltung kommt da net so drauf
klar!
  frame[8] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2] ^
frame[3] ^ frame[4] ^ frame[5] ^ frame[6]  ^ frame[7]);

bei der zeile bin ich mir auch nicht so sicher...

kann da einer mal drauf schauen was da los ist?

von RaveKev (Gast)


Lesenswert?

Ich hab mal ne Frage:


Ich muss auch ein Projekt für meine Schule machen, bei dem ich die
"RelaisPlatine 8-fach seriell" von Conrad ansteuern muss.
Ich benutze WinXP, und da ich nen Laptop habe, habe ich auch nur USB.

An die RelaisPlatine muss ich einen 4ByteBlock senden (Commando,
Adresse, Daten, XOR .. also wie das hier schon gemacht wurde).

Ich hab mir auch schon den Code von oben zu Herzen genommen, es auf
COM2 gesetzt (so heißt mein USB-Port für die Relaiskarte.. hoff ich
mal, also hab ich so eingestellt) und compiliert.
Das compilieren ging, der sagte mir dann auch in dem Programm
"Done..." aber es machte auf meiner RelaisPltine einfach nicht
"klick"..

Woran kann das liegen?
Liegt es daran, dass ich WinXP benutze? hab gehört, dass es da mit denm
COM-Ansprechen nicht so einfach sei.

ich suche jetzt schon seit fast 2 Monaten nach informationen für mein
Projekt, aber habe noch keine so hilfreichen gefunden, wie in diesem
Threat..
Mein Projekt soll / muss bis Mittwoch fertig sein..

könnte mir vielleicht auch noch jemand weitere infos per Mail zukommen
lassen?  ravekev@web.de

von RaveKev (Gast)


Lesenswert?

Ich hab jetzt diesen Code verwendet.
Er sagt mir zwar nach dem Kompilieren und Ausfürhen, dass er es
erfolgreich gesendet hat, mit dem Wörtchen "Done..." aber bei der
RelaisKarte macht es immer noch nicht "klick"


#include <windows.h>
#include <iostream.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <unistd.h>


int main()
{

 DCB dcb;
   HANDLE hComm;
   BOOL fSuccess;
   char *pcCommPort = "COM2";

   hComm = CreateFile( pcCommPort,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // no security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    0,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );

   if (hComm == INVALID_HANDLE_VALUE)
   {
       // Handle the error.
       printf ("CreateFile failed with error %d.\n",
GetLastError());

   }

   // Build on the current configuration, and skip setting the size
   // of the input and output buffers with SetupComm.

   fSuccess = GetCommState(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n",
GetLastError());

   }

   // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

   dcb.BaudRate = CBR_9600;     // 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(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n",
GetLastError());

   }
   else
   {
              char frame[4];
  frame[0] = 1;
  frame[1] = 1;
  frame[2] = 0;
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);
  DWORD dwBytesWritten = 0;
   WriteFile(hComm, &frame, sizeof
(frame), &dwBytesWritten, NULL);
     //TransmitCommChar(hComm,frame);
  frame[0] = 3;
  frame[1] = 1;
  frame[2] = 5;
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);

   WriteFile(hComm, &frame, sizeof
(frame), &dwBytesWritten, NULL);
BOOL bResult;


  DCB dcb_alt;
  SetCommState(hComm, &dcb_alt);

  bResult = CloseHandle(hComm);
  hComm   = INVALID_HANDLE_VALUE;
   }

cout << "Done...";
cout << endl ;
getch();
return 0;
}

von Tobi (Gast)


Lesenswert?

sieht aber richtig aus. schonmal das gesendete mit einer 2. ser.
Schnittstelle aufgefangen und angeschaut? Wenn da alles korrekt ankommt
sind intweder die Bytefolgen, die du schickst falsch oder irgendwas an
der Karte

von T.Stütz (Gast)


Lesenswert?

dcb_alt ist nicht korrekt initialisiert (zumindest dcb_alt.DCBLength
stimmt nicht => SetCommState fehlerhaft)

mach mal

memset(&dcb,0,sizeof(DCB));
dcb.DCBLengthz = sizeof(DCB);
memset(&dcb_alt,0,sizeof(DCB));
dcb_alt.DCBLengthz = sizeof(DCB);

bevor du den DCB per Get/SetCommState verwendest.

Versuch mal "\\\\.\\COM2" oder "COM2:" anstatt "COM2".

Gruss

von Tobi (Gast)


Lesenswert?

dcb_alt wird erst ganz am ende benutzt, sollte also irrelevant sein.
falsch aber egal ;)

bis zu com9 kann man es direkt schreiben, erst darüber muss der pfad
angegeben werden

von René König (Gast)


Lesenswert?

> bis zu com9 kann man es direkt schreiben

Das ist kein Grund, den Namen falsch anzugeben. Man kann es auch gleich
richtig machen. Man muß nicht warten, bis man auf die Klappe fällt.

Ansonsten liegt es sicherlich am nicht vollständig initialiserten DCB
(dcb, ohne _alt). Ein einfaches memset hilft da nicht wirklich weiter,
da muß schon richtig initialisiert werden (beispielsweise muß fBinary
auf TRUE gesetzt sein, das sollte nicht genullt werden (MSDN: this
member must be TRUE)).

von René König (Gast)


Lesenswert?

Ach ja: Die Aufrufe funktionieren erst gar nicht nicht, weil
dcb.DCBlength nicht initialisiert wurde. Aber wie gesagt, diese
Ergänzung allein reicht nicht.

von Tobi (Gast)


Lesenswert?

> fSuccess = GetCommState(hComm, &dcb);

dass sollte den dcb doch initialisieren, womit auch DCBlength gesetzt
wäre

von René König (Gast)


Lesenswert?

Erstens mal muß DCBLength bereits vor dem Auruf initialisiert werden.
Zweitens hast Du recht, der Rest wird dann von GetCommState
initialisiert. Wenn aber die Initialisierung, die GetCommState liefert,
in Ordnung ist, frage ich mich, wozu dann überhaupt noch die Baudrate
verändert werden muß. GetCommState initialisiert doch bereits.

Merkst Du was? GetCommState initialisiert natürlich, aber passt das
auch? Es reicht nicht, nur Baudrate, Parität, Anzahl der Stopbits und
die Bits pro Byte einzustellen. Es gibt noch sehr viel mehr
Möglichkeiten, den Port zu konfigurieren. Das muß auch passen.

Du bekommst das passend, wenn Du alles initialisierst, und zwar
immer. Nur dann hast Du Funktions-Garantie, alles andere ist
Glücksspiel.

von Tobi (Gast)


Lesenswert?

"Erstens mal muß DCBLength bereits vor dem Auruf initialisiert
werden."

Wiedersprechen will ich dir da nicht, aber ich hab das gerade mal
gecheckt und GetCommState initialisiert auch DCBlength einwandfrei.

Mit dem alles initialisieren, was Probleme machen könnte hast du recht.
Wenn ich das bisher richtig beopbachtet habe, behält Windows die
Einstllungen der Schnittstelle zwischen dem Öffnen bei, zumindest war
eine Baudrate danach noch die gleiche. Flusskontrollen jeglicher Art
könnten z.b das Senden behindern, da sollte der Fragesteller mal nach
schaun.

Ein Test mit einer 2. Schnittstelle als Empfänger sollte trotzdem die
meisten Probleme ausschliessen/deutlich machen können

von René König (Gast)


Lesenswert?

> Wiedersprechen will ich dir da nicht, aber ich hab das gerade mal
> gecheckt und GetCommState initialisiert auch DCBlength einwandfrei.

Ich gehe da keine Kompromnisse ein. Length-Parameter sind vor dem
Aufruf zu initialisieren. Mir ist es dabei völlig egal, was
irgendwelche Tests ergeben. Da gehe ich doch lieber auf Nummer Sicher.
Aber das kann ja jeder machen wie er mag.

Normalerweise checken die Funktionen bei der Parameter-Prüfung auch die
Length-Angabe, bevor sie eine Struktur füllen. Passt das dann nicht,
wird ein Fehler zurückgegeben. Wenn Du das erste Mal ein Gerät mit
einer anderen Schnittstelle ansteuern möchtest, z.B. via USB, wirst Du
sehen was ich meine. Bereits das Setup-API lässt Dich mit Deiner
Methode gnadenlos durchfallen. Und dann aber fröhliches Fehlersuchen...

von RaveKev (Gast)


Lesenswert?

Also..
Das Programm läuft jetzt (musste ich an nem anderen Rechner machen..)
Aber, sobald ich ne Auswahl mach, welches Relais angesprochen werden
soll, furnktioniert das wieder nichtmehr..
Hier nochmal mein Code. (Das [B]dick gedruckte[/B] ist der Teil, wie es
dann nichtmehr funktioniert)

#include <windows.h>
#include <iostream.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
#include <unistd.h>




int main()
{
  [B]int relais;

   cout<<"\nBitte geben sie an, welches Relais sie ansprechen
möchten: ";
cin>>relais;[/B]

DCB dcb;
   HANDLE hComm;
   BOOL fSuccess;
   char *pcCommPort = "COM3";

   hComm = CreateFile( pcCommPort,
                    GENERIC_READ | GENERIC_WRITE,
                    0,    // must be opened with exclusive-access
                    NULL, // no security attributes
                    OPEN_EXISTING, // must use OPEN_EXISTING
                    0,    // not overlapped I/O
                    NULL  // hTemplate must be NULL for comm devices
                    );

   if (hComm == INVALID_HANDLE_VALUE)
   {
       // Handle the error.
       printf ("CreateFile failed with error %d.\n",
       GetLastError());

   }

   // Build on the current configuration, and skip setting the size
   // of the input and output buffers with SetupComm.

   fSuccess = GetCommState(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n",
      GetLastError());

   }

   // Fill in DCB: 57,600 bps, 8 data bits, no parity, and 1 stop bit.

   dcb.BaudRate = CBR_19200;     // 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(hComm, &dcb);

   if (!fSuccess)
   {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n",
GetLastError());

   }
   else
   {
       char frame[4];
  frame[0] = 1;
  frame[1] = 1;
  frame[2] = 0;
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);
  DWORD dwBytesWritten = 0;
   WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);
     //TransmitCommChar(hComm,frame);
  frame[0] = 3;
  frame[1] = 1;
  frame[2] = 3;  [B]frame[2] = relais;[/B]
  frame[3] = static_cast<BYTE>(frame[0] ^ frame[1] ^ frame[2]);

   WriteFile(hComm, &frame, (BYTE)frame, &dwBytesWritten, NULL);
BOOL bResult;


  DCB dcb_alt;
  SetCommState(hComm, &dcb_alt);

  bResult = CloseHandle(hComm);
  hComm   = INVALID_HANDLE_VALUE;
   };

cout << "Done...";
cout << endl ;
getch();
return 0;
}

von RaveKev (Gast)


Lesenswert?

sry, hab mit mit [B] gearbeitet.. also auf jedenfall, wenn ich die
Zeilen:
int relais;
cout<<"\nBitte geben sie an, welches Relais sie ansprechen möchten:
";
cin>>relais;

und

frame[2] = relais;

hinzufüge, dann passiert garnichts mehr..

von Rufus T. Firefly (Gast)


Lesenswert?

frame[2] = relais;

Das sind zwei unverträgliche Datentypen; relais ist ein int (also ein
vorzeichenbehafteter 32-Bit-Wert), frame ist ein Array von char-Werten,
die nur 8 Bit groß sind).
Du weist einem davon den 32-Bit-Wert zu; das geht schief.

Mal drüber nachgedacht, Deinen Code in einem Debugger laufen zu lassen?

von RaveKev (Gast)


Lesenswert?

Das Relais wird nicht mal geschalten, wenn ich einfach nur ne ausgabe
reinbau..

zb:

int main()
{
  char relais;
   cout<<"\nBitte Relais angeben: ";
    cin>>relais;
   ... //normaler Code, ohne, dass ich dem frame[2] "relais" zuweise,
sondern frame[2] = 3;
}

Was ich damit sagen möchte ist, selbst wenn meine eingabe nichts mit
dem frame[2] zu tun hat, läuft das Programm trotzdem nicht... das
verwundert mich jetzt irgendwie komplett..

von RaveKev (Gast)


Lesenswert?

Also ich hab es jetzt rausbekommen..
Ich muss die Variable "relais" global machen.. also damit mein ich
außerhalb der main()..
(das hab ich nicht erklärt, um zu zeigen, was ich für ein toller Hecht
bin, und alle leute für doof halte.. sondern, falls ich "global"
falsch verstanden habe, und es somit falsch eingesetzt habe, ihr
trotzdem versteht, was ich mein.. :D )



Jetzt muss ich nur noch mein Programm soweit umändern, dass es aus nem
FMS (FeuerwehrFunk) rausfindet, welches Fahrzeug es ist, dann in ner
Access-Datenbank nach dem Fahrzeug suchen, und dann rausfinden, in
welchem Tor es steht..

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.