Forum: PC-Programmierung Parameter Serielle Schnittstelle


von Thomas H. (datatom)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich möchte Daten vom PC zum Controller senden.

In meinem C++ Programm habe ich folgende Einstellungen vorgenommen:
1
hSerial = CreateFile("COM4",
2
    GENERIC_READ | GENERIC_WRITE,
3
    0,
4
    0,
5
    OPEN_EXISTING,
6
    FILE_ATTRIBUTE_NORMAL,
7
    0);
8
9
...
10
11
dcbSerialParams.BaudRate=CBR_19200; //CBR_57600;
12
dcbSerialParams.ByteSize=8;
13
dcbSerialParams.StopBits=ONE5STOPBITS;//ONESTOPBIT;
14
dcbSerialParams.Parity=NOPARITY;

Leider klappt das Senden nicht.

Mit den Einstellungen, die ich in Putty vorgenommen habe, klappt es. Die 
Einstellungen in Putty habe ich per jpg-Datei beigefügt.

Wo liegt der Fehler?

Vielen Dank im Voraus.

Grüße

datatom

von ingo (Gast)


Lesenswert?

Versuche mal die HW-Flusskontrolle auszuschalten:
   dcbSerialParams.fOutxCtsFlow=0;
   dcbSerialParams.fOutxDsrFlow=0;

mfG ingo

von DirkB (Gast)


Lesenswert?

Du hast auch 1.5 Stopbits eingestellt.

von Thomas (Gast)


Lesenswert?

DirkB schrieb:
> Du hast auch 1.5 Stopbits eingestellt.

Die Stopbits stehen wie ich gerade noch einmal nachgeschaut habe, 
dierekt beim WriteFile auf 1.

von Thomas (Gast)


Lesenswert?

ingo schrieb:
> Versuche mal die HW-Flusskontrolle auszuschalten:
>    dcbSerialParams.fOutxCtsFlow=0;
>    dcbSerialParams.fOutxDsrFlow=0;
>
> mfG ingo

Die beiden Parameter stehen, beim WriteFile auf 0.

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe mal alle Parameter als jpg beigefügt.

Ich habe im Moment echt keine Ahnung woran es liegt:(

von Peter II (Gast)


Lesenswert?

woher weisst du das nichts gesendet wird? eventuell sendest du ja das 
falsche?

von Thomas (Gast)


Lesenswert?

Peter II schrieb:
> woher weisst du das nichts gesendet wird? eventuell sendest du ja das
> falsche?

Wenn etwas gesendet wird, blinkt das LED auf dem Controller. So passiert 
es auch bei Putty und beim Bascom-Terminal.

von Peter II (Gast)


Lesenswert?

dann zeig doch mal die stellen vom senden, es ist eigentlich egal welche 
Paremter eingestellt sind, senden muss immer gehen. (ausser wenn die 
hardwareflusskontrolle eingeschaltet ist)

von Flusskontrolle (Gast)


Lesenswert?

fDtrControl und fRtsControl stehen doch auf 1

von Thomas (Gast)


Lesenswert?

Ich habe noch mal nachgeforscht. Der Fehler liegt bei den Stopbits. Egal 
ob ich eine 1 oder ONE5STOPBITS, ich bekomme bei SetCommState immer 
einen Fehler:
1
if(!SetCommState(hSerial, &dcbSerialParams))
2
  {
3
    //error setting serial port state
4
    printf("Fehler bei GetCommState beim Parameter belegen!\n");
5
  }
6
  else
7
  {
8
    printf("Kein Fehler bei GetCommState beim Parameter belegen!\n");
9
  }

Die Stopbits sind bei WinBase.h folgendermaßen deklariert:
1
#define ONESTOPBIT          0
2
#define ONE5STOPBITS        1
3
#define TWOSTOPBITS         2

Ich weiß nicht warum ich da einen Fehler bekomme.

von Thomas H. (datatom)


Lesenswert?

Letzten Beitrag bitte komplett vergessen. Die Stopbits würden auf 1,5 
stehen, da gibts natürlich einen Fehler.

Allerdings klappt das Senden und Empfangen trotzdem noch nicht.

Irgendein Parameter scheint noch falsch gesetzt zu sein.

von Peter II (Gast)


Lesenswert?

Thomas Holländer schrieb:
> Irgendein Parameter scheint noch falsch gesetzt zu sein.

glaube ich nicht! Auch mit falschen Parmeter sendet die Schnittstelle. 
Prüfe bitte erstmal deine Sende routine und schau mal nach wann die LED 
leuchten müssste. (also erst bei einem epmfangen byte oder hängt sie 
direkt an der sende leitung)

von Thomas H. (datatom)


Lesenswert?

Hier mal der komplette Quellcode:
1
// SerielleSchnittstelle.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
2
//
3
4
#include "stdafx.h"
5
#include "stdio.h"
6
#include "stdlib.h"
7
#include "string.h"
8
#include "windows.h"
9
#include "strsafe.h"
10
11
12
void ErrorExit(LPTSTR lpszFunction);
13
14
int i = 1;
15
HANDLE hSerial;
16
COMMTIMEOUTS timeouts;
17
DCB dcbSerialParams;
18
char szBuff;        
19
char szBuff1[8];
20
char szBuff2[8];
21
char szBuff3[8];
22
DWORD dwBytesRead;
23
DWORD dwBytesWrite;
24
int n = 8; //4096;
25
26
int _tmain(int argc, _TCHAR* argv[])
27
{
28
  hSerial = CreateFile("COM4",
29
    GENERIC_READ | GENERIC_WRITE,
30
    0,
31
    0,
32
    OPEN_EXISTING,
33
    FILE_ATTRIBUTE_NORMAL,
34
    0);
35
  if(hSerial==INVALID_HANDLE_VALUE)
36
  {
37
    if(GetLastError()==ERROR_FILE_NOT_FOUND)
38
    {
39
      // Generate an error
40
      // Fehlercode ausgeben
41
      if(!GetProcessId(NULL))
42
      {
43
        ErrorExit(TEXT("GetProcessId"));
44
      }
45
      //serial port does not exist. Inform user.
46
      printf("Fehler bei CreateFile. Serial Port existiert nicht!\n");
47
    }
48
    //some other error occurred. Inform user.
49
    printf("Fehler bei CreateFile. Sonstiger Fehler!\n");
50
  }
51
  else
52
  {
53
    printf("Kein Fehler bei CreateFile!\n");
54
  }
55
  //////////////////////////////
56
  if (!GetCommState(hSerial, &dcbSerialParams)) 
57
  {
58
    //error getting state
59
    printf("Fehler bei GetCommState!\n");
60
  }
61
  else
62
  {
63
    printf("Kein Fehler bei GetCommState!\n");
64
  }
65
  dcbSerialParams.BaudRate=CBR_19200; //CBR_57600;
66
  dcbSerialParams.ByteSize=8;
67
  dcbSerialParams.StopBits=ONESTOPBIT;
68
  dcbSerialParams.Parity=NOPARITY;
69
  dcbSerialParams.fOutX=1;
70
  dcbSerialParams.fInX=1;
71
72
  if(!SetCommState(hSerial, &dcbSerialParams))
73
  {
74
    //error setting serial port state
75
    printf("Fehler bei GetCommState beim Parameter belegen!\n");
76
  }
77
  else
78
  {
79
    printf("Kein Fehler bei GetCommState beim Parameter belegen!\n");
80
  }
81
  ///////////////////////////////
82
  timeouts.ReadIntervalTimeout=50;
83
  timeouts.ReadTotalTimeoutConstant=50;
84
  timeouts.ReadTotalTimeoutMultiplier=10;
85
  timeouts.WriteTotalTimeoutConstant=50;
86
  timeouts.WriteTotalTimeoutMultiplier=10;
87
88
  if(!SetCommTimeouts(hSerial, &timeouts))
89
  {
90
    //error occureed. Inform user
91
    printf("Fehler bei Timeout!\n");
92
  }
93
  else
94
  {
95
    printf("Kein Fehler bei Timeout!\n");
96
  }
97
  //////////////////////////////////
98
  while(i < 9999999)
99
  {   
100
    i = 0;
101
    if(!ReadFile(hSerial, &szBuff2, n, &dwBytesRead, NULL))
102
103
    {
104
      //error occurred. Report to user.
105
      printf("Fehler bei ReadFile!\n");
106
    }
107
    else
108
    {  i = atoi(szBuff2);
109
    _itoa_s(i,szBuff3,10);
110
    printf (szBuff3);
111
    printf ("\n");
112
    }
113
    ////////////////////////////////
114
    //szBuff[0] = 'r';
115
    i = i + 1000;
116
    _itoa_s(i,szBuff1,10);  
117
    if(!WriteFile(hSerial, &szBuff1, n, &dwBytesWrite, NULL))
118
    {
119
      //error occurred. Report to user.
120
      printf("Fehler bei WriteFile!\n"); 
121
    }
122
    else
123
    {
124
      printf (szBuff1);
125
      printf ("\n");
126
    }
127
128
  }
129
  ///////////////////////////////
130
  CloseHandle(hSerial);
131
  ////////////////////////////////
132
  system("pause");
133
  return 0;
134
}
135
136
// Fehlerfunktion
137
void ErrorExit(LPTSTR lpszFunction) 
138
{ 
139
  // Retrieve the system error message for the last-error code
140
141
  LPVOID lpMsgBuf;
142
  LPVOID lpDisplayBuf;
143
  DWORD dw = GetLastError(); 
144
145
  FormatMessage(
146
    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
147
    FORMAT_MESSAGE_FROM_SYSTEM |
148
    FORMAT_MESSAGE_IGNORE_INSERTS,
149
    NULL,
150
    dw,
151
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
152
    (LPTSTR) &lpMsgBuf,
153
    0, NULL );
154
155
  // Display the error message and exit the process
156
157
  lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
158
    (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
159
  StringCchPrintf((LPTSTR)lpDisplayBuf, 
160
    LocalSize(lpDisplayBuf) / sizeof(TCHAR),
161
    TEXT("%s failed with error %d: %s"), 
162
    lpszFunction, dw, lpMsgBuf); 
163
  MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 
164
165
  LocalFree(lpMsgBuf);
166
  LocalFree(lpDisplayBuf);
167
  ExitProcess(dw); 
168
}

von ingo (Gast)


Lesenswert?

Hier mal eine DCB-Initialisierung, die bei mir zuverlässig funktioniert:

   // BuildCommDCB("baud=9600 parity=N data=8 stop=1",&MyDcb);
   // sscanf(Dialog1.baudrate,"%ld",&a);

   MyDcb.BaudRate=a; /* oder was Anders */
   MyDcb.DCBlength=sizeof(DCB); /* !!! */
   MyDcb.fBinary=1;
   MyDcb.fOutxCtsFlow=0;
   MyDcb.fOutxDsrFlow=0;
   MyDcb.fDtrControl=DTR_CONTROL_ENABLE;
   MyDcb.fDsrSensitivity=0;
   MyDcb.fRtsControl=RTS_CONTROL_ENABLE;
   SetCommState(ComHandle,&MyDcb);


Evtl fehlt dir die DCBlength!
mfG ingo

von Peter II (Gast)


Lesenswert?

Thomas Holländer schrieb:
> i = i + 1000;
>     _itoa_s(i,szBuff1,10);
>     if(!WriteFile(hSerial, &szBuff1, n, &dwBytesWrite, NULL))

das sieht merkwürdig aus. du Sendest hier 8byte (n=8) aber in szBuff1 
sind nur 4byte + 0byte. Dann sendest du auch keine \n - kann sein das 
deine Hardware auf ein \n wartet?

von Thomas H. (datatom)


Lesenswert?

ingo schrieb:
> Hier mal eine DCB-Initialisierung, die bei mir zuverlässig funktioniert:
>
>    // BuildCommDCB("baud=9600 parity=N data=8 stop=1",&MyDcb);
>    // sscanf(Dialog1.baudrate,"%ld",&a);
>
>    MyDcb.BaudRate=a; /* oder was Anders */
>    MyDcb.DCBlength=sizeof(DCB); /* !!! */
>    MyDcb.fBinary=1;
>    MyDcb.fOutxCtsFlow=0;
>    MyDcb.fOutxDsrFlow=0;
>    MyDcb.fDtrControl=DTR_CONTROL_ENABLE;
>    MyDcb.fDsrSensitivity=0;
>    MyDcb.fRtsControl=RTS_CONTROL_ENABLE;
>    SetCommState(ComHandle,&MyDcb);
>
>
> Evtl fehlt dir die DCBlength!
> mfG ingo

Hab ich übernommen klappt leider nicht:-(

Peter II schrieb:
> Thomas Holländer schrieb:
>> i = i + 1000;
>>     _itoa_s(i,szBuff1,10);
>>     if(!WriteFile(hSerial, &szBuff1, n, &dwBytesWrite, NULL))
>
> das sieht merkwürdig aus. du Sendest hier 8byte (n=8) aber in szBuff1
> sind nur 4byte + 0byte. Dann sendest du auch keine \n - kann sein das
> deine Hardware auf ein \n wartet?

Hab auch mal den Wert 12345678 mitgegeben, klappt trotzdem nicht.

von Peter II (Gast)


Lesenswert?

Thomas Holländer schrieb:
> Hab auch mal den Wert 12345678 mitgegeben, klappt trotzdem nicht.

du senderst aber immer noch kein Zeilenende - woher soll deine Hardware 
wissen das nicht noch ein Zeilchen kommt?

von Thomas H. (datatom)


Lesenswert?

Wie geht das denn mit dem Zeilenende?

von Peter II (Gast)


Lesenswert?

Thomas Holländer schrieb:
> Wie geht das denn mit dem Zeilenende?

also noch deutlicher kann man es kaum sagen du must ein \r oder \n 
senden - keine ahnung was deine Hardware erwartet!

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:
> Peter II schrieb:
>> woher weisst du das nichts gesendet wird? eventuell sendest du ja das
>> falsche?
>
> Wenn etwas gesendet wird, blinkt das LED auf dem Controller.

Wann genau blinkt diese LED?
Wenn der Controller ein gültiges Kommando erhalten hat oder bei jedem 
Zeichen, dass der Controller bekommt?

Wenn du noch eine LED + Vorwiderstand hast. Häng die mal direkt an die 
Rx Leitung vom Controller. Deren blinken zeigt dir zuverlässig an, ob da 
was über die Schnittstelle kommt oder nicht. Egal ob das was da 
daherkommt, Sinn macht oder ob es richtig ist. Sobald der PC an der 
Leitung wackelt (und das muss er, wenn er sendet), dann blinkt die LED 
auch.

von Karl H. (kbuchegg)


Lesenswert?

1
hSerial = CreateFile("COM4",

häng da mal an die Gerätebezeichnung einen : hinten drann. "COM4:" wenn 
ich mich recht erinnere, dann ist der : der Auslöser für das 
Betriebssystem, dass es sich hierbei um ein Gerät handelt und nicht etwa 
um eine Datei namens "COM4".

von Peter II (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> häng da mal an die Gerätebezeichnung einen : hinten drann. "COM4:" wenn
> ich mich recht erinnere, dann ist der : der Auslöser für das
> Betriebssystem, dass es sich hierbei um ein Gerät handelt und nicht etwa
> um eine Datei namens "COM4".

NEIN - com4 ist schon richtig.

von Udo S. (urschmitt)


Lesenswert?

man kann auch auf PC Seite erst mal Send und Recieve verbinden um zu 
sehen ob etwas gesendet wird. Klar muss man das PC seitig dann auch 
lesen, aber die Lesefunktion braucht man in der Regel sowiso.
Auch klar, falsch gesetzte parameter erkenne ich so nicht aber es ging 
ja darum ob überhaupt gesendet wird.

von Thomas H. (datatom)


Lesenswert?

Peter II schrieb:
> also noch deutlicher kann man es kaum sagen du must ein \r oder \n
> senden - keine ahnung was deine Hardware erwartet!

Klappt jetzt. Ich habe am Ende \r angefügt und nun werden Daten 
gesendet.

Danke an alle die mit Rat und Tat zur Seite waren.

Grüße

datatom

von Peter II (Gast)


Lesenswert?

Thomas Holländer schrieb:
> Klappt jetzt. Ich habe am Ende \r angefügt und nun werden Daten
> gesendet.

sie wurden auch schon vorher gesendet ...

von Thomas H. (datatom)


Lesenswert?

is ja gut:-)

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.