Forum: Mikrocontroller und Digitale Elektronik GSM Alarmanlage mit Positionsbestimmung


von Eddy (Gast)


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?

von Google Nutzer (Gast)


Lesenswert?

Stichwort : Interupts ....

von Google Nutzer (Gast)


Lesenswert?


von Eddy (Gast)


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

von Eddy (Gast)


Lesenswert?

ja interupts......
arbeite ich nicht schon damit?

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

von Google Nutzer (Gast)


Lesenswert?

steht alles im Tut...

von Eddy (Gast)


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

von Eddy (Gast)


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

von schurli (Gast)


Lesenswert?

Hi

Habe das gleiche Problem wie du!
Ich habs so gelöst:
1
unsigned char neu[10];
2
3
while (1)
4
{
5
  // Auf UART-Eingabe prüfen
6
  if((UCSR0A & (1<<RXC0)))
7
  {
8
    gets(neu);           //Speichert den String auf neu ab.
9
    printf("Hallo\n");   //Gibt Hallo an die Serielle Schnittstelle aus.
10
  }
11
12
}

von schurli (Gast)


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

von Eddy (Gast)


Lesenswert?

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

von Eddy (Gast)


Lesenswert?

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

1
// Interruptroutine, die Zeichen aus dem UART sofort ausliest, wenn empfangen
2
SIGNAL (SIG_UART_RECV)     
3
{
4
  udr_data= UDR;   //Byte auf jeden Fall abholen, sonst Endlosinterrupt
5
  
6
  if(rbuffcnt < RBUFFLEN)    // keinen Zeichen in einem vollen Ringpuffer überschreiben
7
    rbuff[(rbuffpos+rbuffcnt++) % RBUFFLEN] = udr_data;  // welche Position? Gelesene Zeichenpos + Anzahl Zeichen MODULO Pufferlänge 
8
                                // (von 0 wieder anfangen, wenn Ende erreicht)
9
}
10
11
// Nächstes zu lesendes Zeichen aus Ringpuffer zurückgeben
12
unsigned char ser_getc (void)    
13
{
14
  unsigned char c;
15
16
  while(!rbuffcnt);       // Warte bis ein Zeichen vorhanden ist
17
  
18
  cli();            // Interruptbehandlung kurz aussetzen. Ab jetzt muß es schnell gehen (wenig Befehle), damit Zeichen, die 
19
                // ab jetzt eintreffen nicht verloren gehen.
20
  rbuffcnt--;          // anschl. ein Zeichen weniger zum ausgeben
21
  c = rbuff [rbuffpos++];  // Zeichen holen, was nach dem bereits gelesenen liegt
22
  if (rbuffpos >= RBUFFLEN)  rbuffpos = 0;  // wenn hinterstes Zeichen (rechts im Puffer) gelesen wurde, dann wieder vorne anfangen
23
24
  sei();            // Interruptbehandlung wieder aktivieren
25
26
  return (c);        // Zeichen zurückgeben
27
}


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

1
void uart_gets( char* Buffer, uint8_t MaxLen )
2
{
3
4
5
6
7
  uint8_t NextChar;
8
  uint8_t StringLen = 0;
9
10
  do {
11
12
      NextChar = ser_getc();
13
14
      if (NextChar=='\n' || NextChar=='\r') {
15
          if (!StringLen)
16
              continue;    // erstmal alle \r und \n am Anfang ignorieren
17
          else
18
              break;       // danach makiert das erste \r oder \n das Ende
19
      }
20
21
      *Buffer++ = NextChar;
22
      StringLen++;
23
24
  } while (StringLen < MaxLen-1);
25
26
  *Buffer = '\0';
27
}

von Eddy (Gast)


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?

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.