auslesen der seriellen schnittstelle
-
hallo
also ich habe mir letzte woche bei ebay nen gps-empfänger ersteigert. spitzen ding... funzt auch alles soweit gut.
das ding arbeitet mit NMEA (http://de.wikipedia.org/wiki/National_Marine_Electronics_Association)
jetzt hab ich folgendes geschrieben://--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <iostream> #include "Serial.h" #include "Serial.cpp" using namespace std; //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { CSerial serial; if (serial.Open(2, 9600)) cout << "erfolg!" << endl; else cout << "misserfolg!" << endl; char* lpBuffer = new char[100]; do { serial.ReadData(lpBuffer, 100); } while (lpBuffer == Null); cout << lpBuffer; delete []lpBuffer; cin.get(); return 0; } //---------------------------------------------------------------------------aber wie zu erwarten: es funktioniert nicht.
ich bekomme zwar meine datensätze (siehe wiki) rein, aber meistens stehn noch irgendwelche wirren zeichen davor oder dahinter. es kommt auch vor dass ich mal garnichts anzeigt, oder auch mal nach 20 zeichen oder so einfach aufhört. ich vermute der liest das was gerade rein kommt. aber wie bekomm ich den dazu beim sinnvollen anzufangen und am ende des sinnvollen aufzuhören?
danke erstmal
bob007
ps:
seriel.h:// -------------------------------------------------------------------------------------- // (c) 2003 www.winapi.net // // Serial.h // // Headerdatei für eine einfache, aber leistungsfähige // Kommunikation über die Serielle Schnittstelle // -------------------------------------------------------------------------------------- #ifndef __SERIAL_H__ #define __SERIAL_H__ class CSerial { public: CSerial(); ~CSerial(); BOOL Open (int nComPortNr, int nBaud, int nBits, int nParity, int nStopp); BOOL Close (void); BOOL ModeSet (int nBaud, int nBits, int nParity, int nStopp); BOOL SetTimeout (int iTotalReadTimeout); BOOL IsOpen (void); int ReadData (char *buffer, int iMaxCount); int SendData (const char *buffer, int iBytesToWrite); BOOL WriteCommByte (unsigned char ucByte); private: HANDLE hComm; DCB dcb_alt; COMMTIMEOUTS timeouts_alt; }; #endifund seriel.cpp:
// -------------------------------------------------------------------------------------- // (c) 2003 www.winapi.net // // Serial.cpp // // CPP-Datei für eine einfache, aber leistungsfähige // Kommunikation über die Serielle Schnittstelle // -------------------------------------------------------------------------------------- #include <windows.h> #include "Serial.h" CSerial::CSerial() { hComm = INVALID_HANDLE_VALUE; } CSerial::~CSerial() { Close (); } BOOL CSerial::IsOpen() { if (INVALID_HANDLE_VALUE != hComm) return (TRUE); else return (FALSE); } BOOL CSerial::ModeSet (int nBaud, int nBits, int nParity, int nStopp) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (FALSE); } DCB dcb; ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState (hComm, &dcb)) return (FALSE); dcb.BaudRate = nBaud; dcb.ByteSize = (BYTE)nBits; dcb.Parity = (BYTE)nParity; dcb.StopBits = (BYTE)nStopp; if (!SetCommState (hComm, &dcb)) return (FALSE); return (TRUE); } BOOL CSerial::Open (int nComPortNr, int nBaud, int nBits, int nParity, int nStopp) { if (INVALID_HANDLE_VALUE != hComm) { return (TRUE); } char szPort[16]; wsprintf (szPort, "\\\\.\\COM%d", nComPortNr); hComm = CreateFile (szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hComm == INVALID_HANDLE_VALUE) return (FALSE); if (!GetCommTimeouts(hComm, &timeouts_alt)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD ; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD ; timeouts.ReadTotalTimeoutConstant = 3000; // Timeout ist 3000ms timeouts.WriteTotalTimeoutMultiplier = 1000; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hComm, &timeouts)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } DCB dcb; ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState (hComm, &dcb)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } dcb_alt = dcb; dcb.fBinary = TRUE; // muss immer "TRUE" sein! dcb.fParity = TRUE; 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_ENABLE; dcb.fAbortOnError = FALSE; dcb.wReserved = 0; // muss immer "0" sein! dcb.BaudRate = nBaud; dcb.ByteSize = (BYTE)nBits; dcb.Parity = (BYTE)nParity; dcb.StopBits = (BYTE)nStopp; dcb.fParity = (dcb.Parity != NOPARITY); if (!SetCommState(hComm, &dcb)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } return(TRUE); } BOOL CSerial::Close (void) { BOOL bResult; if(INVALID_HANDLE_VALUE == hComm) return (TRUE); SetCommTimeouts(hComm, &timeouts_alt); SetCommState(hComm, &dcb_alt); bResult = CloseHandle(hComm); hComm = INVALID_HANDLE_VALUE; return(bResult); } BOOL CSerial::SetTimeout (int iTotalReadTimeout) { if (INVALID_HANDLE_VALUE == hComm) return (TRUE); COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD ; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD ; timeouts.ReadTotalTimeoutConstant = (DWORD) iTotalReadTimeout; timeouts.WriteTotalTimeoutMultiplier = 1000; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hComm, &timeouts)) return (FALSE); return(TRUE); } BOOL CSerial::WriteCommByte (unsigned char ucByte) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (FALSE); } if (!TransmitCommChar(hComm, ucByte)) return (FALSE); return (TRUE); } int CSerial::SendData (const char *buffer, int iBytesToWrite) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (0); } DWORD dwBytesWritten = 0; WriteFile(hComm, buffer, iBytesToWrite, &dwBytesWritten, NULL); return ((int) dwBytesWritten); } int CSerial::ReadData (char *buffer, int iMaxCount) { if (INVALID_HANDLE_VALUE == hComm) { SetLastError(ERROR_INVALID_HANDLE); return (0); } DWORD dwRead = 0; char chRead; int i = 0; while (ReadFile(hComm, &chRead, 1, &dwRead, NULL)) { if (dwRead != 1) break; buffer[i++] = chRead; if (i == iMaxCount) break; } return (i); }
-
Hallo,
zuerst solltest du darauf achten wie dein Datensatz ausschauen muss: die baudrate, die Anzahl der daten bits , das stopp bit und eventuell dass parity bit (sollte in der Beschreibung des Empfängers nach zu lesen sein)
auf der wikipedia seite kannst du zb sehen das die baudrate 4800 beträgt anstatt 9600
das heist diese zeile ist falsch: if (serial.Open(2, 9600))
richtig: if (serial.Open(2, 4800))Es ist auch diese zeile in der du zusätlich daten bits und stop bits angeben solltest.(in der serial.cpp siehst du die zusätzlich möglichen parameter anschauen)
und dieser teil macht dein Ergebnis zum Zufall:
char* lpBuffer = new char[100];
do {
serial.ReadData(lpBuffer, 100);
} while (lpBuffer == Null);
cout << lpBuffer;
delete []lpBuffer;der do zweig wird genau einaml ausgeführt egal ob in diesem moment indem er erreicht wird gerade etwas gesendet wird oder nicht
versuch mal
int recived = 0;
char* lpBuffer = new char[100];
do {
recived = serial.ReadData(lpBuffer, 100);
} while (!recived);
cout << lpBuffer;
delete []lpBuffer;jetzt wird solange gelesen bis wirklich etwas empfangen wurde.
ihoffe etwas geholfen zu haben.
lg RAY
-
also danke erstmal
das mit den 9600baud weis ich. das is ne eigenart von meinem gps. das funktioniert auch soweit
das mit der recived variable geht soweit. jetzt hab ich zumindest immer was drin stehn... sinnvoll is des aber trotzdem noch ned. es kommen immer noch diese sinnlosen zeichen. irgendwie hab ich auch die falsche lib gepostet... bei der geposteten funzt der open befehl immer ned.
ich brauche:
port 2
baud 9600
data 8
parity none
stop 1
wie muss den da der aufruf dazu heißen? bzw was bedeutet none als integerwert???ich schick mal noch die libs die ich im mom verwende... bzw hat jemand welche mit denen es funzt?
serial.h:// Serial.h #ifndef __SERIAL_H__ #define __SERIAL_H__ #define FC_DTRDSR 0x01 #define FC_RTSCTS 0x02 #define FC_XONXOFF 0x04 #define ASCII_BEL 0x07 #define ASCII_BS 0x08 #define ASCII_LF 0x0A #define ASCII_CR 0x0D #define ASCII_XON 0x11 #define ASCII_XOFF 0x13 class CSerial { public: CSerial(); ~CSerial(); BOOL Open( int nPort = 2, int nBaud = 9600 ); BOOL Close( void ); int ReadData( void *, int ); int SendData( const char *, int ); int ReadDataWaiting( void ); BOOL IsOpened( void ){ return( m_bOpened ); } protected: BOOL WriteCommByte( unsigned char ); HANDLE m_hIDComDev; OVERLAPPED m_OverlappedRead, m_OverlappedWrite; BOOL m_bOpened; }; #endifserial.cpp:
// Serial.cpp #include "stdafx.h" #include "Serial.h" CSerial::CSerial() { memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) ); memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) ); m_hIDComDev = NULL; m_bOpened = FALSE; } CSerial::~CSerial() { Close(); } BOOL CSerial::Open( int nPort, int nBaud ) { if( m_bOpened ) return( TRUE ); char szPort[15]; char szComParams[50]; DCB dcb; wsprintf( szPort, "COM%d", nPort ); m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); if( m_hIDComDev == NULL ) return( FALSE ); memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) ); memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) ); COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 0; CommTimeOuts.WriteTotalTimeoutMultiplier = 0; CommTimeOuts.WriteTotalTimeoutConstant = 5000; SetCommTimeouts( m_hIDComDev, &CommTimeOuts ); wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud ); m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); dcb.DCBlength = sizeof( DCB ); GetCommState( m_hIDComDev, &dcb ); dcb.BaudRate = nBaud; dcb.ByteSize = 8; unsigned char ucSet; ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 ); ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 ); ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 ); if( !SetCommState( m_hIDComDev, &dcb ) || !SetupComm( m_hIDComDev, 10000, 10000 ) || m_OverlappedRead.hEvent == NULL || m_OverlappedWrite.hEvent == NULL ){ DWORD dwError = GetLastError(); if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent ); if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent ); CloseHandle( m_hIDComDev ); return( FALSE ); } m_bOpened = TRUE; return( m_bOpened ); } BOOL CSerial::Close( void ) { if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE ); if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent ); if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent ); CloseHandle( m_hIDComDev ); m_bOpened = FALSE; m_hIDComDev = NULL; return( TRUE ); } BOOL CSerial::WriteCommByte( unsigned char ucByte ) { BOOL bWriteStat; DWORD dwBytesWritten; bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite ); if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){ if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0; else{ GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE ); m_OverlappedWrite.Offset += dwBytesWritten; } } return( TRUE ); } int CSerial::SendData( const char *buffer, int size ) { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); DWORD dwBytesWritten = 0; int i; for( i=0; i<size; i++ ){ WriteCommByte( buffer[i] ); dwBytesWritten++; } return( (int) dwBytesWritten ); } int CSerial::ReadDataWaiting( void ) { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); DWORD dwErrorFlags; COMSTAT ComStat; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); return( (int) ComStat.cbInQue ); } int CSerial::ReadData( void *buffer, int limit ) { if( !m_bOpened || m_hIDComDev == NULL ) return( 0 ); BOOL bReadStatus; DWORD dwBytesRead, dwErrorFlags; COMSTAT ComStat; ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); if( !ComStat.cbInQue ) return( 0 ); dwBytesRead = (DWORD) ComStat.cbInQue; if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit; bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead ); if( !bReadStatus ){ if( GetLastError() == ERROR_IO_PENDING ){ WaitForSingleObject( m_OverlappedRead.hEvent, 2000 ); return( (int) dwBytesRead ); } return( 0 ); } return( (int) dwBytesRead ); }
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Nimm doch eine fertige, geprüfte und zuverlässige Klasse:
http://www.codeproject.com/system/serial.aspEs macht IMHO keinen Sinn das Rad immer wieder neu zu erfinden...
-
hm sry aber des funzt irgendwie noch viel weniger...

-
bob007 schrieb:
hm sry aber des funzt irgendwie noch viel weniger...

Wenn ich mir deine main-Funktion so ansehe, vermute ich, dass das an deinem Code liegt, nicht an irgendeiner Bibliothek.
-
MFK schrieb:
Wenn ich mir deine main-Funktion so ansehe, vermute ich, dass das an deinem Code liegt, nicht an irgendeiner Bibliothek.
hm also mein main sieht jetzt so aus:
int main(int argc, char* argv[]) { CSerial serial; serial.Open(_T("COM2")); serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1); serial.SetupHandshaking(CSerial::EHandshakeHardware); DWORD dwBytesRead = 0; BYTE abBuffer[100]; do { serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead); if (dwBytesRead > 0) { cout << abBuffer; } } while (dwBytesRead == sizeof(abBuffer)); serial.Close(); cin.get(); return 0; }das is so direkt aus dem bespiel kopiert. müsste eigendlich so passen.
Problem:
ich bekomme mal wieder garnichts rein... und wenn ich dann nach einigen versuchen ausgerechte mal den richtigen moment erwische sieht die ausgabe in etwa so aus:GPGGA,194902.000,5015.1327,N,01f══┘3f3fY4Yã♠Vã&µFãV&&µvãÍcFvµFãÍcã♠♠♠♠ªV&k $GPGSA,A,3,17,23,20,04,11d,,,,,,,,3.8,2.4,3.0*3D $GPRMC,194902.000,A,5015.▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄1der datensatz in der mittleren zeile scheint soweit zu passen.
in der ersten zeile fehlt am anfang was (hab ich vml ned mit erwischt...) aber ich hab keinen plan was das ab dem "f" darstellen soll. eigendlich müsste es da ganz anders weiter gehen.
genau das gleiche in der letzten zeile nach dem "5." musste es eigendlich mit 1327,N," weitergehen und nicht mir irgendwelchen sonderzeichen.
-
hm, sieht so aus, als würdest du da teilweise HTML-Code empfangen, denn &#...; wird in HTML glaube ich verwendet um UNICODE-Zeichen auszugeben.
dem zu Folge wären die Zahlen zwischen &# und ; die Nummern der Zeichen im UNICODE-Zeichensatz.
du solltest dein Prog mal so umschreiben, dass es die ausgaben in einer Datei speichert, und diese Datei solltest du dir mal z.B. im Internet Explorer oder im Firefox anschauen.
Mal sehen, wie das dann aussieht.MfG DrakoXP
-
also das, was du da oben geschrieben hast, sieht bei mir so aus:
GPGGA,194902.000,5015.1327,N,01f══┘3f3fY4Yã
Vã&µFãV&&µvãÍcFvµFãÍcã


ªV&k $GPGSA,A,3,17,23,20,04,11d,,,,,,,,3.8,2.4,3.0*3D $GPRMC,194902.000,A,5015.▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄1also immer noch ziemlich sinnlos.

-
DrakoXP: Schreib bitte nicht so einen Müll. Danke.
-
in wiefern war das eben Müll?
es war immerhin nen Versuch wert.
schließlich kann man in HTML wirklich &#...; schreiben um ein Zeichen anzuzeigen.
-
ja des hat in der ausgabe auch scho so ausgesehen wie du des da beschrieben hast. des is irgendwie nur durch diesen "code" tag hier im forum passiert. richtig sah die ausgabe dann so aus:
GPGGA,194902.000,5015.1327,N,01f══┘3f3fY4Yã
Vã&µFãV&&µvãÍcFvµFãÍcã


ªV&k $GPGSA,A,3,17,23,20,04,11d,,,,,,,,3.8,2.4,3.0*3D $GPRMC,194902.000,A,5015.▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄1
-
das wusste ich ja nicht
-
DrakoXP schrieb:
das wusste ich ja nicht
Konntest du auch nicht und dein Versuch war keine schlechte Idee! Die Trolls hier schreiben halt manchmal merkwürdige Sachen

-
jep ganau meine meinung. but now back to topic. kann mir jemand weiterhelfen?
-
naja, jetzt mal was anderes:
vielleicht sind die Ausgaben gar nicht sinnlos, sondern nur du kannst nichts damit anfangen.
du solltest dich vllt mal mit der Technologie von GPS auseinandersetzen, also z.B. wie die Pakete aussehen, die verschickt werden.
Dann könntest du einen Parser schreiben, der diese Pakete auswertet und das dann auch für unwissende verständlich macht.So ist es ja auch bei den ID3Tags.
Wenn man da einfach die letzten 128 Byte ausgibst kommt nur Müll raus.
Wenn du aber diese 128 Byte in folgende Struktur schreibst:typedef struct tagID3V1 { char szTag[3]; // Kennzeichnung für ID3v1-Tags, bei ID3v1 immer "TAG" char szTitle[30]; // Titel des Liedes char szInterpret[30]; // Interpret char szAlbum[30]; // Album char szYear[4]; // Erscheinungsjahr char szComment[30]; // beliebiger Kommentar char cGenre; // Genre } SID3V1_real, *PID3V1_real;kannst du aus den ID3Tags einige tolle Informationen erfahren.
so in etwa solltest du es vllt mal bei GPS versuchen.
guck einfach mal Internet, was du so über GPS finden kannst.
-
das auseinandersetzten is nicht das problem... ich kann jeden beliebigen Hyperteminal nehmen und einfach den eingang auslesen und bekomm das rein was ich haben will. das muss sozusagen an der bibliothek oder meinem progrämmchen liegen liegen.
richtig müsste die ausgabe so lauten (wobei die zahlenwerte etwas variieren können):GPGSA,A,2,23,04,20,,,,,,,,,,3.2,3.0,1.037
$GPRMC,204834.000,A,5015.1331,N,01155.7288,E,,357.55,080107,,,A72und mit so ner ausgabe kann ich dann auch was anfangen und das ganze dann entsprechend verabeiten. aber nicht wenn irgendwo zwischen drin irgendwelche seltsamen, undefinierbaren, im protokoll nicht definierten zeichen vorkommen.
-
ok
konnt des problem lösen. unter http://www.microsoft.com/germany/MSDN/webcasts/library.aspx?id=118762251 ist alles genaustens beschrieben