Forum: Mikrocontroller und Digitale Elektronik GSM SMS auslesen und auswerten


von Matthias (Gast)


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

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..

von Stephan (Gast)


Lesenswert?

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.

von Matthias (Gast)


Lesenswert?

ich benutze kein handshake, auch nicht wenn der PC mit dem GSM 
kommuniziert. Habe diese Leitungen nicht verwendet.

von Stephan (Gast)


Lesenswert?

Dann musst Du RTS und CTS des GSM-Moduls verbinden, sonst schickt das 
GSM-Modul keine Daten. Evtl. auch DSR und DTR.

von Matthias (Gast)


Lesenswert?

aber am PC erhalte ich daten, ohne das ich diese Leitungen verwende. 
Jedoch klappts mit dem PIC nicht.. Sollte deshalb nicht an dem 
liegen??..

von Gustav (Gast)


Lesenswert?

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.

von Matthias (Gast)


Lesenswert?

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..

von Stephan (Gast)


Lesenswert?

Und was kommt als Antwort nach AT bzw. AT+CMGF=1 ???

von Peter Z. (Gast)


Lesenswert?

Kann es sein das Du noch ein CR LF senden musst?
Schau mal was der PC raushaut....

von Matthias (Gast)


Lesenswert?

@ 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!!!

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

So sieht das aus was ich vom GSM erhalte!

von Stephan (Gast)


Lesenswert?

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.

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Der Code im Bild.

Folgendes wird geschickt:

AT

AT+CMGF=1

AT+CMGL

von Peter Z. (Gast)


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

ja ich hab eine andere..

von Glaskugel (Gast)


Lesenswert?

Matthias schrieb:
> ja ich hab eine andere..

Und warum gehts dann nicht?

von Peter Z. (Gast)


Lesenswert?

Na dann zeig doch mal deine puts und gets Funktionen....
Vielleicht liegt ja darin der Hund begraben!?

von Stephan (Gast)


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

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!

von Harald (Gast)


Lesenswert?

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.

von Harald N. (harald_)


Lesenswert?

> 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.

von Andreas F. (aferber)


Lesenswert?

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

von Lars (Gast)


Lesenswert?

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

von Harald N. (harald_)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.