AT-Befehle
-
Das müssen wir anders machen...
folgendes würde funzen:
char CSerialPort::ReadByte() { ReadFile(hComm, &text, 1, &received, 0); /* ist received und hComm global???*/ return text; }aber wenn man alle verfügbaren zeichen kriegen will:(hier mit Call-By-Reference)
im Hauptprgramm:char * text;und in der Klasse:
void CSerialPort::ReadByte( char * text) { ReadFile(hComm, &text, 100 /*denke das reicht...*/, &received, 0); /* ist received und hComm global???*/ return text; }ReadFile kehrt zurück, wenn keine Zeichen mehr anliegen... Deshalb sollte das mit 100 oder X funktionieren...
Tschau
-
Hallo nochmal,
irgendwie hab ich glaub ich ein grundlegendes Problem und komm einfach nicht dahinter. Also mein Funktionsaufruf sieht so aus:void CHandytoolDlg::OnSendat() { // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen if(m_bConnectStatus == TRUE) { const char* atCommand = "AT\n"; // bringt mir an dieser Stelle \n ein 'ENTER' ? port.WriteByte(atCommand); } Sleep(1000); char* response, *display; display = port.ReadByte(response); }Ich möchte das so machen, wie es im Hyperterminal funzt. Man gibt AT ein und bestätigt mit 'ENTER' - danach kommt die Antwort OK.
Also sende ich den Befehl an den COM Port:
BOOL CSerialPort::WriteByte(const char* bybyte) { unsigned long size = strlen(bybyte); iBytesWritten=0; if(WriteFile(hComm,bybyte, size,&iBytesWritten,NULL)==0) return false; else return true; }Da es dann ja einige ms dauert bis die Antwort am COM Port liegt hab ich mal nen Sleep (großzügig) eingebaut. Bringt das was?
Die Funktion zum auslesen:
char* CSerialPort::ReadByte(char* text) { DWORD dwBytesRead; ReadFile(hComm, text, 100, &dwBytesRead, 0); return text; }hComm ist global.
Kann das alles so überhaupt funktionieren?
Gruß
Sebastian
-
Ich sehe da auf den ersten Blick kein grundsätzliches Problem. Es könnte aber sein, dass ReadFile erst dann zurückkommt, wenn alle 100 angeforderten Bytes empfangen wurden.
Mit SetCommTimeouts könntest du dafür sorgen, dass ReadFile vorher zurückkommt.
NACHTRAG:
Es ist nicht sinnvoll, den Zeiger auf den Puffer zurückzugeben, der ist ja schon Parameter. Gib lieber die Anzahl der empfangenen Zeichen zurück.
-
Hallo,
danke erstmal für die Infos. Ich glaub der Fehler liegt schon beim schreiben des Befehls. Hab jetzt mal nen WaitCommEvent() hinzugefügt der empfangene Char meldet. Aber da kommt nix. Ich muss die Befehle ja mit nem 'ENTER' beenden. Dann dürfte es doch reichen, wenn ich \n dranhäng?void CHandytoolDlg::OnSendat() { // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen if(m_bConnectStatus == TRUE) { const char* atCommand = "AT+CMGR=1\n"; port.WriteByte(atCommand); } DWORD data = EV_RXCHAR; if(WaitCommEvent(port.hComm, &data, NULL) == 0) MessageBox("Es liegen keine Daten an.","Fehler",MB_OK+MB_ICONINFORMATION); else { char* response, *display; display = port.ReadByte(response); } }
-
'\n' ist ein Linefeed. IIRC brauchst du für AT-Kommandos ein Carriage Return '\r'.
-
Okay.
Dann sollte doch aber die WaitCommEvent() direkt mitteilen, dass Daten anliegen? Hab EV_RXCHAR noch durch EV_RXFLAG ersetzt.
Laut MSDN :EV_RXFLAG The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function.
Irgendwie komm ich damit noch nicht so ganz klar. Ist mein erstes Projekt mit der seriellen Schnittstelle und ich weiß auch nicht so recht, wie und wo ich die Fehler suchen soll. Aber ich denke, dass genau da der Fehler liegt, weil die Verbindung an sich ja steht.
Vielleicht kannst du mir ja nen Rat geben
Gruß
Sebastian
-
Du kannst WaitCommEvent nicht vorgeben, worauf es warten soll. Der zweite Parameter ist ein out-Parameter, d.h. WaitCommEvent schreibt da rein, was passiert ist.
Wenn der Rückgabewert von Null verschieden ist, musst du den Inhalt von data prüfen.
-
Also eher sowas in der Art:
void CHandytoolDlg::OnSendat() { // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen if(m_bConnectStatus == TRUE) { char* atCommand = "AT+CMGR=1\r"; port.WriteByte(atCommand); } DWORD data; if(WaitCommEvent(port.hComm, &data, NULL) == 0) MessageBox("Es liegen keine Daten an.","Fehler",MB_OK+MB_ICONINFORMATION); else { if(data == EV_RXFLAG) { char* response, *display; display = port.ReadByte(response); } } }Aber irgendwie liefert die Funktion immer nur 0 zurück.
Woran könnte das liegen?
Gruß
-
Ich hab mich mal ein wenig schlau gemacht: Offenbar kannst du mit SetCommMask festlegen, worauf WaitCommEvent warten soll.
In jedem Fall solltest du GetLastError aufrufen, wenn WaitCommEvent fehlschlägt.
-
Hallo,
hab jetzt mal meine Funktionen mit GetLastError() gecheckt und es funktioniert auch alles bis auf die ReadByte() Funktion. Hier ist sie nochmal:
char* CSerialPort::ReadByte(char* text) { DWORD dwBytesRead; ReadFile(hComm, text, 100, &dwBytesRead, 0); DWORD dwErrorReport; dwErrorReport = GetLastError(); return text; }Die Fehlermeldung die ich bekomm ist:
Unzulässiger Zugriff auf einen Speicherbereich. [998]Kann mir da jemand weiterhelfen?
Gruß
Sebastian
-
Tja, worauf zeigt denn der Zeiger, den du als Parameter übergibst?