www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik GSM Alarmanlage mit Positionsbestimmung


Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
mein projekt wächst und immer wieder befinden sich neue steine auf dem 
weg zur großen erleuchtung.

vorab möchte ich auf meinen anderen beitrag hinweisen in dem ihr mir 
schon geholfen habt und der für die weitere problemlösung vielleicht 
hilfreich ist.


Beitrag "UART empfängt nur einmal."



nun möchte ich ja auch gerne per sms befehle schicken können, auf die
der µC dann reagiert.
dafür würde ich ja wie immer uart_gets() benutzem um etwas vom modem
einzulesen.
jedoch weiß ich ja nicht wann eine sms eintrifft und um dies zu erkennen
müsste der µC ja permanent an der seriellen schnittstelle auf text
warten.
dies wäre mit dem aufruf von uart_gets() erledigt da die funktion erst
beendet wird wenn die max string länge erreicht wurde oder ein string
endzeichen erkannt wird.
eine ausgabe vom modem wäre z.B. +CMTI:"SM",3 diese zeile sagt mir das
eine neue sms im speicherbereich 3 gespeichert wurde.
die darauf folgende antwort vom µC wäre dann (öffne SMS 3)-->AT+CMGR=3.
folglich wird der inhalt der sms ausgegeben mit dem sich dann arbeiten
ließe.

mein problem ist nun:
nach dem aufruf der funktion uart_gets() wartet der µC auf zeichen.
falls aber keine sms eintrifft empfängt der µC keine zeichen vom modem,
wartet bis ins nächste jahrhundert und beendet nicht die uart_gets()
funktion um mit dem weiteren programm fortzufahren.
heißt: in der zeit zwischen aufruf der funktion und eingehender sms
beobachtet der µC nicht den status von pinX.
das ist aber fatal da der µC ja eine sms verschicken soll wenn sich was
an pinX verändert.

kurz gesagt in zwei fällen soll reagiert werden:
wenn sich pinX verändert und wenn eine sms mit befehl eintrifft.

wie löse ich dieses problem?

Autor: Google Nutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stichwort : Interupts ....

Autor: Google Nutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eine notlösung wäre den sms speicher des modems abzufragen um zu gucken 
ob irgendwann mal eine neue sms eingetroffen ist.

es wäre aber besser wenn das ding direkt reagiert immerhin teilt das 
modem einem ja auch mit das gerade eine neue sms eintrifft.

und bei dieser lösung hätte man ja wieder das problem mit den 
nichtausgelesenen zeichen im buffer......

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja interupts......
arbeite ich nicht schon damit?

und wenn nicht wie setze ich das um??
ich programmiere noch nicht allzulang in c.

Autor: Google Nutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
steht alles im Tut...

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schön wäre etwas wie

kein hinweis auf zeichen am uart:
das programm fragt in dauerschleife pinX ab um zu sehen ob sich was 
verändert.

zeichen kommen an:
erst alles empfangen und dann gucken auf was die empfangenen zeichen 
zutreffen....

neue befehle (empfangene sms)
pin anfrage
error message
e.t.c.
das könnte man ja mit einer case schleife machen

nachdem alles abgearbeitet ist sofort wieder gucken ob pinX immer noch 
so ist wie es sein sollte....

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja das bin ich aber schon mehrfach durchgegangen...
irgendwie bekomm ich das nicht so einfach hin wie das da steht

deshalb ja auch schon den anderen thread

Autor: schurli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Habe das gleiche Problem wie du!
Ich habs so gelöst:
unsigned char neu[10];

while (1)
{
  // Auf UART-Eingabe prüfen
  if((UCSR0A & (1<<RXC0)))
  {
    gets(neu);           //Speichert den String auf neu ab.
    printf("Hallo\n");   //Gibt Hallo an die Serielle Schnittstelle aus.
  }

}

Autor: schurli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eventuell eine if-Abfrage nach
if((UCSR0A & (1<<RXC0))).
Wenn das erste Zeichen ein "+" ist, dann den String mit gets(neu) 
einlesen.

Den String dann mit den entsprechenden Stringfunktionen behandeln.

mfg

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
geht denn nicht öfters bei dieser variante ein zeichen am anfang 
verloren, weil zu spät angefangen wurde einzulesen??

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich benutze ja schon diese interrupt routine.....
kann man die nicht einfach verwenden??

// Interruptroutine, die Zeichen aus dem UART sofort ausliest, wenn empfangen
SIGNAL (SIG_UART_RECV)     
{
  udr_data= UDR;   //Byte auf jeden Fall abholen, sonst Endlosinterrupt
  
  if(rbuffcnt < RBUFFLEN)    // keinen Zeichen in einem vollen Ringpuffer überschreiben
    rbuff[(rbuffpos+rbuffcnt++) % RBUFFLEN] = udr_data;  // welche Position? Gelesene Zeichenpos + Anzahl Zeichen MODULO Pufferlänge 
                                // (von 0 wieder anfangen, wenn Ende erreicht)
}

// Nächstes zu lesendes Zeichen aus Ringpuffer zurückgeben
unsigned char ser_getc (void)    
{
  unsigned char c;

  while(!rbuffcnt);       // Warte bis ein Zeichen vorhanden ist
  
  cli();            // Interruptbehandlung kurz aussetzen. Ab jetzt muß es schnell gehen (wenig Befehle), damit Zeichen, die 
                // ab jetzt eintreffen nicht verloren gehen.
  rbuffcnt--;          // anschl. ein Zeichen weniger zum ausgeben
  c = rbuff [rbuffpos++];  // Zeichen holen, was nach dem bereits gelesenen liegt
  if (rbuffpos >= RBUFFLEN)  rbuffpos = 0;  // wenn hinterstes Zeichen (rechts im Puffer) gelesen wurde, dann wieder vorne anfangen

  sei();            // Interruptbehandlung wieder aktivieren

  return (c);        // Zeichen zurückgeben
}


Und dann rufe ich uart_gets() auf um die antwort vom modem zu empfangen 
und da liegt doch dann irgendwo der fehler oder??

void uart_gets( char* Buffer, uint8_t MaxLen )
{




  uint8_t NextChar;
  uint8_t StringLen = 0;

  do {

      NextChar = ser_getc();

      if (NextChar=='\n' || NextChar=='\r') {
          if (!StringLen)
              continue;    // erstmal alle \r und \n am Anfang ignorieren
          else
              break;       // danach makiert das erste \r oder \n das Ende
      }

      *Buffer++ = NextChar;
      StringLen++;

  } while (StringLen < MaxLen-1);

  *Buffer = '\0';
}

Autor: Eddy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der holt ja scheinbar alle zeichen direkt in den buffer falls da welche 
sind
 und die uart_gets() funktion übergibt ja nur die zeichen aus dem buffer 
irgendeiner variablen oder nicht???


kann ich dann nicht einfach was machen von wegen wenn buffer leer ist 
dann rufe nicht uart_gets() auf?

wäre das nicht die sauberste lösung??
wie würde man das realisieren?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.