Serielle Schnittstelle (RS-485 Device) abfragen

raysprak

Mitglied
Hallo Helfer?
Hilfe!
Ich habe den Auftrag bekommen, Daten eines Gertes abzufragen, welche an einer seriellen Schnittstelle (COM1) angeschlossen ist. (RS-485)
Ich habe schon alle Posts durchgewälzt, jedoch nichts brauchbares gefunden.
Das Device, welches ich am Port angeschlossen habe, sollte bei jeder Bewegung einen anderen Wert senden.....tut es aber nicht....sonder immer das gleiche.
Nämlich: 1243596
mehr nicht.
Ich brauche aber die wirklichen Werte....die bekomme ich aber nicht.....da kann ich das Gerät bewegen, wie ich will.
Was mache ich falsch?

Ich der Code, den ich zum Testen schrieb (nicht lachen, falls das Müll ist):

#include <windows.h>
#include <stdio.h>


int main(int argc,char** argv)
{
DCB dcb;
COMMTIMEOUTS CTO;
COMMCONFIG CC;


ZeroMemory (&dcb, sizeof(dcb));

if(!BuildCommDCB("COM1 baud=19200 parity=N data=8 stop=2",&dcb))
{
MessageBox(0,"Error BuildCommDCB","Test",MB_OK);
}

HANDLE hFile = NULL;
hFile = CreateFile("COM1",GENERIC_READ,0,0,OPEN_EXISTING,0,NULL);

if(hFile == NULL)
{
MessageBox(0,"Error CreateFile","Test",MB_OK);
}

if(!GetCommState(hFile, &dcb))
{
MessageBox(0,"Error GetCommState","Test",MB_OK);
}


dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = CBR_19200;
dcb.ByteSize = (BYTE)8;
dcb.StopBits = (BYTE)2;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = TRUE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.wReserved = 0;

CTO.ReadIntervalTimeout = 500;
CTO.ReadTotalTimeoutConstant = 500;
CTO.ReadTotalTimeoutMultiplier = 500;
CTO.WriteTotalTimeoutConstant = 500;
CTO.WriteTotalTimeoutMultiplier = 500;

if(!SetCommTimeouts(hFile,&CTO))
{
MessageBox(0,"Error CommTimeouts","Test",MB_OK);
}

if(!SetCommState(hFile,&dcb))
{
DWORD error = GetLastError();
char cerr[64];
char cerr2[16];
itoa((int)error,cerr2,10);
strcpy(cerr,"Error SetCommState: ");
strcat(cerr,cerr2);
MessageBox(0,cerr,"Test",MB_OK);
}


if(!SetDefaultCommConfig("COM1",&CC,sizeof(CC)))
{
MessageBox(0,"Error SetDefaultCommConfig","Test",MB_OK);
}
if(hFile == INVALID_HANDLE_VALUE)
MessageBox(0, "Fehler 1", "", 0);

char buff;
DWORD dlength = 0;

char sBuffer[1024];

while(1)
{
ReadFile(hFile,&buff,1,&dlength,NULL);
sBuffer[0] = buff;
printf("%d\n",sBuffer);

}

return 0;
}
 
Der Fehler liegt in der Zeile
Code:
printf("%d\n",sBuffer);
Da gibst Du die Adresse von sBuffer aus. Die Zeile sollte so lauten:
Code:
printf("%d\n",sBuffer[0]);
oder einfach
Code:
printf("%d\n",buff);
 
Danke für den Tip, jokey2!
Aber das war es nicht....ich habe nicht das Problem, dass ich die falschen Daten gesendet bekomme, sondern dass ich immer nur diesen einen Wert bekomme, keinen anderen.


printf("%d\n",buff);
und
printf("%d\n",sBuffer[0]);
Habe ich auch schon probiert........:-(
 
Hallo raysprak,

bei der ganzen Sache scheint es noch ein grundsätzliches Problem zu geben. Für die Kommunikation über die serielle Schnittstelle muss in der Regel ein bestimmtes Protokoll beachtet werden, damit die gegenseitige Kommunikation geordnet ablaufen kann.

Was für einen Wert bekommst du den ständig? Ist es vielleicht STX (= 0x02) ?
Dann könnte die Verbindung möglicherweise so ablaufen:

-> Gerät sendet STX (Sendebereitschaft)
<- Du sendest DLE (= 0x10, Empfangbereitschaft)
-> Das Gerät sendet die Datenbytes
-> Das Gerät sendet DLE, ETX (= 0x03) um das Ende der Übertagung anzuzeigen
<- Du sendest DLE (Empfangsbestätigung)

Gruß
MCoder
 
Danke MCoder, aber das ist es wohl auch nicht....
das Gerät sendet: 1243596
Mit diesem Wert kann ich beim besten Willen nichts anfangen......hat noch jemand vielleicht einen Tip?
 
raysprak hat gesagt.:
das Gerät sendet: 1243596
Ist das das Ergebnis von einer einzigen ReadFile()-Ausführung? Da du nur immer jweils ein Byte liest, kann der Wert nur zwischen 0 und 255 liegen. Wenn es mehrere Durchläufe (also mehrere gelesene Bytes) sind, solltest du die mal separieren.

Ansonsten denke ich schon, dass du ein bestimmtes Protokoll benötigst. Hast du keine weiteren Infos zu dem Gerät?

Gruß
MCoder
 
ja, Infos über das Gerät habe ich schon, aber das sind nur elektronische Infos und in der Elektronik kenne ich mich nun gar nicht aus.
Ich brauche doch nur ein paar Werte des Gerätes....*heul*
 
Wie schon gesagt, der Wert "1243596" ist nicht so richtig nachvollziehbar.
Lese doch nur mal ein Byte ("while(1)" wegtun) und prüfe das Ergebnis von ReadFile():
Code:
char  buff; 
DWORD dlength = 0;

if( ReadFile(hFile, &buff, 1, &dlength, NULL) )
{
    if( dlength == 1 )
    {
        printf("Byte gelesen: %d\n", buff);
    }
    else
    {
        printf("%d Bytes gelesen, aber 1 Byte erwartet\n", dlength);                    
    }
}
else
{
    printf("ReadFile() fehlgeschlagen\n");                    
}
 
Ein weiteres Danke an MCoder!
Leider ist die Ausgabe: "Byte gelesen = 0".
Jetzt würde jeder normal sterbliche denken, dass das Gerät nicht funktioniert.
Tut es aber.....
Die mit dem Gerät gelieferte Software funktionert 1a und gibt mir jede noch so kleine Drehbewegung aus.
Und was mach ich jetzt?
Nun bin ich schon auf der Suche nach Code, der mich in die mitgelieferte Software "haken" lässt....das ist aber nur die Notlösung, weil ich diese Software gern umgehen möchte...:(
 
Wenn immer nur '0' zurückkommt könnte es sein, dass die Parameter der Schnittstelle nicht stimmen.
Bist du dir über die Angaben zu Baudrate, Parität etc. sicher?
Auf jeden Fall sollte es reichen nur die DCB-Struktur (am besten alle Member) und die Timeouts zu setzen. Auf "BuildCommDCB()" kannst du verzichen, weil doppelt gemoppelt und "SetDefaultCommConfig()" muss auch nicht sein.
Vielleicht kommst du mit folgenden Einstellungen weiter:
Code:
dcb.DCBlength         = sizeof(m_DCB);      
dcb.BaudRate          = CBR_19200;
dcb.fBinary           = 1;
dcb.fParity           = 0;
dcb.fOutxCtsFlow      = 0;
dcb.fOutxDsrFlow      = 0;
dcb.fDtrControl       = DTR_CONTROL_ENABLE;
dcb.fDsrSensitivity   = 0;
dcb.fTXContinueOnXoff = 0;
dcb.fOutX             = 0;
dcb.fInX              = 0;
dcb.fErrorChar        = 0;
dcb.fNull             = 0;
dcb.fRtsControl       = 1;
dcb.fAbortOnError     = 0;
dcb.fDummy2           = 0;
dcb.wReserved         = 0;
dcb.XonLim            = 2048;
dcb.XoffLim           = 512;
dcb.ByteSize          = 8;
dcb.Parity            = NOPARITY;
dcb.StopBits          = TWOSTOPBITS;
dcb.XonChar           = 17;
dcb.XoffChar          = 19;
dcb.ErrorChar         = 0;
dcb.EofChar           = 0;
dcb.EvtChar           = 0;
dcb.wReserved1        = 0;

CTO.ReadIntervalTimeout         = 200;
CTO.ReadTotalTimeoutConstant    = 200;
CTO.ReadTotalTimeoutMultiplier  = 0;
CTO.WriteTotalTimeoutConstant   = 0;
CTO.WriteTotalTimeoutMultiplier = 2000;

HANDLE hFile = CreateFile("COM1",GENERIC_READ,0,0,OPEN_EXISTING,0,NULL);

if( SetCommState(hFile,&dcb) ...
if( SetCommTimeouts(hFile,&CTO ...

//... Lesen
 
Zurück