Hallo Zusammen Ich habe ein Problem. Ich arbeite mit einem Microcontroller PIC18F6622 und einem GSM Modul von Mipot. SMS versenden funktioniert aber SMS auslesen und Auswerten geht nicht. Ich kommuniziere über die UART-Schnittstelle(Rx und Tx). SMS auslesen sollte so funktionieren ("AT+CMGL"). Mit dem PIC sollte der Befehl gets(Antwort_GSM); funktionieren, jedoch bleibt das System immer hängen. Wenn das GSM Modul viu PC kommuniziert wird, funktioniert es Perfekt. SMS können ausgelesen werden! Hat irgendjemand eine Ahnung, an was es liegen könnte oder hat jemand schon ähnliche Probleme gehabt, welcher mit helfen könnte? Hoffe auf schnelle Antworten! Danke
kleine Bemerkung noch: Wenn der PIC mit dem PC verbunden wird, können die Befehle vom PC tiptop abgespeichert und angezeigt werden. Nur funktionierts mit dem GSM Modul nicht..
Wie läuft der Handshake, über RTS/CTS oder gar nicht? Bei letzterem muss RTS/CTS beim GSM-Modul verbunden werden. Der PC bedient das nämlich.
ich benutze kein handshake, auch nicht wenn der PC mit dem GSM kommuniziert. Habe diese Leitungen nicht verwendet.
Dann musst Du RTS und CTS des GSM-Moduls verbinden, sonst schickt das GSM-Modul keine Daten. Evtl. auch DSR und DTR.
aber am PC erhalte ich daten, ohne das ich diese Leitungen verwende. Jedoch klappts mit dem PIC nicht.. Sollte deshalb nicht an dem liegen??..
Häng doch mal bitte deinen Code an. Wenns mit dem PC funktioniert, dann kanns ja nur entweder ein analogen Problem sein oder ein Fehler im Code.
Dies ist die Funktion welche SMS lesen soll: void read_sms(void) { printf("%c",escape); delay_ms(200); puts(""); delay_ms(400); puts("AT"); delay_ms(400); puts("AT+CMGF=1"); delay_ms(400); puts("AT+CMGL"); gets(Antwort1); lcd_gotoxy(0,0); printf(lcd_putc,"Nachricht:"); lcd_gotoxy(0,1); printf(lcd_putc,"%s",Antwort1); } Die Nachricht soll in der Variable Antwort1 gespeichert werden. Das Programm bleibt jedoch am gets(Antwort1); Befehl hängen..
Kann es sein das Du noch ein CR LF senden musst? Schau mal was der PC raushaut....
@ Stephan: nach "AT+CMGF=1" schickt mir das GSM ein "OK" @ Peter Z.: mit dem Befehl puts(); wird anschliessend automatisch ein CR und LF angehängt! Was ich auch Probiert habe ist: Der PIC schickt die Befehle an das GSM Modul und das GSM schickt mir die Antwort an den PC. Dies scheint Problemlos zu funktionieren!!!
Wenn nach AT bzw. AT+CMGF=1 ein "OK" kommt, scheiden alle bisherigen vermuteten Ursachen aus. Poste doch mal den Code, den Du mit dem PC schickst.
Wusste garnicht das puts CR und LF schickt... in meiner LIB steht folgendes void puts(char *str) { char k; while (k=*str++) putchar(k); putchar(10); } Aber vielleicht hast Du ja eine andere?! bzw. brauchst gar kein CR
Matthias schrieb:
> ja ich hab eine andere..
Und warum gehts dann nicht?
Na dann zeig doch mal deine puts und gets Funktionen.... Vielleicht liegt ja darin der Hund begraben!?
Es ist ja wohl so, dass mit dem PC nach "AT" bzw. "AT+CMGF=1" ein "OK" zurückkommt, nur nach dem "AT+CMGL" nicht. Ich vermute daher eher, dass es an der wesentlich längeren Antwort nach "AT+CMGL" liegt. Hyperterminal und Konsorten haben ja üblicherweise einen Puffer eingebaut, der beim PIC nicht vorliegt bzw. hier nicht programnmiert ist. Ich schätze mal, dass das ein Problem mit der Compilierung des C-Codes ist, evtl. wird RCIF im Register PIR1 nicht (richtig) abgefragt o.ä. oder der Code braucht woanders sehr lange. Probier's mal mit Inline Assembler und nimm als Vorlage den Code aus http://www.sprut.de/electronic/pic/grund/rs232.htm
der PIC besitzt eigentlich auch einen Buffer.. Die Befehle puts und gets funktionieren, da ich mit dem PC auch mit einem anderen PIC(16F677A) kommunizieren kann. Ich kann mit gets einen Text auslesen und am Display ausgeben. Nur mit dem PIC den ich benutze (PIC18F6622) funktionierts nicht!
Schau doch mal mit dem Oszi nach, ob das GSM-Modul überhaupt was sendet. Wenn nicht, dann liegt der Fehler schon vor Deinem Get-Kommando. Im übrigen würde ich lieber ne Service-Routine für den Uart schreiben und das per Interrupt rein holen.
> Wie läuft der Handshake, über RTS/CTS oder gar nicht? Bei letzterem muss > RTS/CTS beim GSM-Modul verbunden werden. Der PC bedient das nämlich. Im AT Command Mode werden kein Handshake unterstützt. AT+CMGL führt dazu, dass das GSM Module alle SMS im Speicher auf einmal sendet. Da hat der kleine PIC dann viel zu tun und wenn es dumm läuft, dann reicht das RAM nicht aus. Ich empfehle oft den New Message Indikator NMI. Mit dem Zusammenspiel aus AT+SMP und AT+NMI kann man das Verhalten bei eingehenden SMS beeinflussen. Man bekommt dann +CNMI (plus Nummer des Speicherplatzes der SMS). Die SMS steht nicht immer auf Platz 1. Die SMS wird dahin geschrieben wo ein Platz frei ist. - Platz X lesen - Platz X löschen - Mit AT+CMGL prüfen ob der SMS speicher wirklich leer ist. Wenn nein dann weitere SMS einlesen und löschen. Um AT+SMP und AT+NMI voll auszureizen, muss man leider SMS im PDU Mode verstehen. Der PDU Mode ist nicht ganz so einfach zu verstehen. http://www.gsm-modem.de/sms-pdu-mode.html Das Lesen kann auch mit AT+CMGL erfolgen, aber dann sollte man nach dem Lesen der ersten SMS aufhören, diese bearbeiten und dann AT+CMGL wiederholen bis der Speicher wirklich leer ist.
Das Problem ist ganz einfach, dass du die Antworten der Kommandos vor dem AT+CMGL nicht einliest (das "OK\r\n"). Daher ist direkt nach dem Senden des AT+CMGL noch das letzte Zeichen der letzten Antwort im Empfangsregister des UART, das ist ein "\n", dein gets() liest dieses als erstes Zeichen, erkennt ein Zeilenende, und liefert dir einen leeren String zurück. Andreas
Ich möchte keine schlafenden Hunde wecken, finde aber nichts was mir irgendwie weiter hilft... Nur dieses Thread ist identisch mit meinem Problem. Ich habe einen Code den ich in C-Programmiert bzw gefunden und modifiziert habe. Ich möchte eine die erste SMS von einem WAVECOM WMOD2 modem auslesen und den reinen SMS-Text dann weiter nutzen. Ich habe das Modem an ein STK500 angeschlossen und verwende einen ATMega88. Ich kann ohne Problem das Modem direkt an den PC anschließen und mit hterm kommunizieren, es wird keine Pin verwendet. Ich Schicke mit hterm die befehle mit einem abschließenden cr, welches mir auf dem Bildschirm auch angezeigt wird, zb beim AT befehle AT\r. Dann bekomme ich vom Modem ein AT OK\r zurück. Schließe ich das STK500 anstatt des modems an meinen PC an, bekomme ich ein AT\r vom ATMega gesendet, antworte ich dann mit einem AT OK\r macht der ATMega auch so weiter wie er soll, er schickt den nächsten AT befehl und soweiter... Schließe ich aber das Modem direkt an das STK500 an, wartet er immer nur auf die Antwort, aber es scheint keine zu kommen. Bei der Modem-Pc kommunikation sehe ich beim Debuggen auch immer, das der µC alle meine mit hterm geschickten antworten fleißig in den Buffer schreibt, aber bei Modem-µC steht nichts im Buffer.. muss ich evtl irgendwo noch drauf warten? ich bein jetzt eine woche dadran und weiß echt nicht mehr weiter... Das Modem wird über PC als auch mit STk nur über Ground, Rx und Tx angeschlossen, und beim PC funktioniert das ja auch super. Ich habe es auch schon probiert, wie in einem anderen Thread beschrieben, RTS auf high zu setzen, hat aber auch nicht geholfen, somal es am PC ja auch ohne funktioniert. Hier mal ausschnitte meines Codes Hier die UART funktionen
1 | void WaitToCompleteReceive() |
2 | {
|
3 | //clear Flag
|
4 | uart_rx_flag = false; |
5 | |
6 | //warte auf Taste oder auf Flag für String komplett empfangen
|
7 | while (uart_rx_flag == false); |
8 | }
|
9 | |
10 | |
11 | // einen String senden
|
12 | // vor Aufruf der Funktion muss man prüfen, ob uart_t_flag==1 ist
|
13 | // nur dann kann ein neuer String gesendet werden
|
14 | |
15 | void put_string(char *daten) { |
16 | |
17 | if (uart_tx_flag==1) { |
18 | // String daten ind en Sendepuffer kopieren
|
19 | strcpy(uart_tx_buffer, daten); |
20 | // Flag für 'Senden ist komplett' löschen,
|
21 | uart_tx_flag = 0; |
22 | // UDRE Interrupt einschalten, los gehts
|
23 | UCSR0B |= (1<<UDRIE0); |
24 | }
|
25 | }
|
26 | |
27 | // einen empfangenen String kopieren
|
28 | // vor Aufruf der Funktion muss man prüfen, ob uart_rx_flag==1 ist
|
29 | // anderenfalls ist der RX Buffer noch ungültig
|
30 | |
31 | void get_string(char *daten) { |
32 | |
33 | if (uart_rx_flag==1) { |
34 | // String kopieren
|
35 | strcpy(daten, uart_rx_buffer); |
36 | // Servo-Control
|
37 | // wenn 1. buchstabe r/l ist, ...
|
38 | //if(daten[0] == 'r'){
|
39 | // OCR1A += 100;
|
40 | //}
|
41 | //if(daten[0] == 'l'){
|
42 | // OCR1A -= 100;
|
43 | //}
|
44 | // Flag löschen
|
45 | uart_rx_flag = 0; |
46 | }
|
47 | }
|
Hier meine abfrage funktion in der main
1 | const char ATAntwort[] = "AT"; |
2 | const char ATSMS[] = "+CMGR:" |
3 | .
|
4 | .
|
5 | .
|
6 | .
|
7 | .
|
8 | .
|
9 | do
|
10 | {
|
11 | put_string("AT\r"); |
12 | WaitToCompleteReceive(); |
13 | }
|
14 | while(!strncmp(uart_rx_buffer,ATAntwort, 2) == 0); |
15 | do
|
16 | {
|
17 | put_string("AT+CMGR=1\r"); |
18 | WaitToCompleteReceive(); |
19 | usw.... |
Ich hoffe die Problemstellung ist ausführlich genug und verständlich geschrieben und das mir jemand helfen kann, ich kann leider alles erst abends ausprobieren, danke schon mal
> Schließe ich aber das Modem direkt an das STK500 an, wartet er immer nur > auf die Antwort, aber es scheint keine zu kommen. <<< snip >>> > Ich möchte mit einem PIC16F876 über rs232 mit einem Modem (Wavecom WM02) > komunizieren. <<< snip >>> Der obige Satz ist aus dem Thread von Markus. Linke siehe hier: Beitrag "RS232 Komunikation mit PIC" Matthias, ich würde dir das gleiche wie Markus empfehlen. Folge einfach meinen Hinweisen und poste das Ergebnis hier. Gruß Harald
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.