Forum: Mikrocontroller und Digitale Elektronik Probleme bei UART Auswertung


von Josef F. (Gast)


Lesenswert?

Hallo,

ich habe folgendes Problem. Ich möchte einen String welcher über die 
UART Schnittstelle meines AVRs rein kommt auswerten. Dazu habe ich eine 
Funktion geschrieben.

Für die UART Schnittstelle verwende ich die Lib von Peter Fleury.

Es kommt ein String in folgenden Format an: #Befehl
Das # ist also das Startzeichen, abgeschlossen wird der String mit einem 
Return.

Ich möchte diesen Befehl dann ohne das # in ein Char Array Speichern.

Leider funktioniert das aber nicht, es scheint gar nichts in das Array 
gespeichert zu werden.

Leider bin ich zu blöd den Fehler zu finden.

Hier mal mein Code.

1
void Befehl()
2
{
3
  
4
  uint8_t bufferzaehler = 0;
5
  uint8_t string_complete=1;
6
  char c;
7
  
8
  do
9
  {
10
    c = uart_getc();
11
    if( c != UART_NO_DATA )
12
    {
13
      
14
      if(c==35)
15
      {   
16
        Relais1ein();
17
        c = uart_getc();
18
        while( c != '\n' )
19
        {
20
          if( c != UART_NO_DATA )
21
          {
22
            Befehlsbuffer[bufferzaehler++] = c;
23
            c = uart_getc();
24
          }
25
        }
26
        
27
        Befehlsbuffer[bufferzaehler] = '\0';
28
        string_complete=0;
29
      }
30
    }
31
    
32
  }while(string_complete);
33
34
35
}

Hier noch die Main-Funktion
1
char Befehlsbuffer[14]={"00000000000000"};
2
int main(void)
3
{
4
//Hier sind noch einige Initialisierungen
5
6
    
7
    
8
  do
9
  {
10
  Befehl();
11
12
  uart_puts(Befehlsbuffer);
13
      
14
  } while (1);
15
}

Generell funktioniert die UART Schnittstelle, nur meine Auswertung 
funktioniert nicht.

Hat jemand einen Vorschlag an was es liegen könnte?

Danke

Josef

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

>   char c;
>
>     c = uart_getc();
>     if( c != UART_NO_DATA )

Sieh dir nochmal die Doku zu den Funktionen an, insbesondere den 
Return-Typ der Funktion uart_getc. Sieh dir auch an, welcher Wert sich 
hinter UART_NO_DATA (bzw. den anderen Konstanten) verbirgt und überleg 
inwiefern das mit dem Return Typ der Funktion zusammenhängt bzw. warum c 
kein char sein darf.

von Karl H. (kbuchegg)


Lesenswert?

>       if(c==35)

PS: wenn du # meinst, dann schreib auch #
1
      if( c == '#' )
ist doch viel lesbarer und verständlicher. Es gibt keinen Grund, warum 
du da selbst den ASCII Code dafür raussuchen solltest. Das kann der 
Compiler perfekt für dich erledigen.

: Bearbeitet durch User
von Josef F. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Sieh dir nochmal die Doku zu den Funktionen an, insbesondere den
> Return-Typ der Funktion uart_getc. Sieh dir auch an, welcher Wert sich
> hinter UART_NO_DATA (bzw. den anderen Konstanten) verbirgt und überleg
> inwiefern das mit dem Return Typ der Funktion zusammenhängt bzw. warum c
> kein char sein darf.

Vielen Dank für den Tipp. Sowas blödes, da habe ich mich vertan.
Ich habe den Datentyp der Variablen c nun von char zu uint16_t geändert.

Leider funktioniert mein Code noch immer nicht.
1
void Befehl()
2
{
3
  
4
  uint8_t bufferzaehler = 0;
5
  uint8_t string_complete=1;
6
  char c;
7
  
8
  do
9
  {
10
    c = uart_getc();
11
    if( c != UART_NO_DATA )
12
    {
13
      
14
      if(c==35)
15
      {   
16
        Relais1ein();
17
        c = uart_getc();
18
        while( c != '\n' )
19
        {
20
          if( c != UART_NO_DATA )
21
          {
22
            Befehlsbuffer[bufferzaehler++] = c;
23
            c = uart_getc();
24
          }
25
        }
26
        
27
        Befehlsbuffer[bufferzaehler] = '\0';
28
        string_complete=0;
29
      }
30
    }
31
    
32
  }while(string_complete);
33
   Relais1aus();
34
35
}

Aus Testgründen habe ich eine Funktion Relais1ein(); nach dem Erkennen 
des # Zeichens eingefügt. Diese wird auch ausgeführt, das Relais wird 
aktiviert.

Am Ende der do-while Schleife soll dieses Relais wieder ausgeschaltet 
werden. Dies geschieht nicht. Ich gehe daher davon aus dass er die 
Schleife niemals verlässt.

Kann jemand noch einen weiteren Fehler entdecken?

Vielen Dank

Josef

von Ein (Gast)


Lesenswert?

Josef F. schrieb:
> char Befehlsbuffer[14]={"00000000000000"};

Dein Befehlsbuffer ist kürzer als dein String. In C passt ein 14-Zeichen 
String leider nicht in einen 14-Byte Puffer.

von Josef F. (Gast)


Lesenswert?

Ich habe jetzt zum Test noch zwei weitere Relais eingebunden.
Es wird nur Relais 1 aktiviert. Relais 2 und 3 nicht.

1
   while( c != '\n' )
2
        {
3
          if( c != UART_NO_DATA )
4
          {
5
            Befehlsbuffer[bufferzaehler++] = c;
6
            c = uart_getc();
7
            Relais2ein();
8
          }
9
        }
10
        
11
        Befehlsbuffer[bufferzaehler] = '\0';
12
        string_complete=0;
13
        Relais3ein();
14
      }
15
    }

Er kommt also gar nicht erst in die If-Anweisung
1
if( c != UART_NO_DATA )

Was läuft hier nur schief?

von Josef F. (Gast)


Lesenswert?

Ich habe jetzt nochmal einiges versucht, unter anderem die if-Abfrage 
umgeschrieben zu:
1
if( ! (c & UART_NO_DATA)


Aber diese Bedingung scheint nicht erfüllt zu werden. Heißt das, die 
UART Lib bekommt keine weiteren Daten außer dem # mehr?

Ich bin langsam echt am Verzweifeln.

Wäre für eine Hilfe sehr dankbar.

Schönen Abend

Josef

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Vielen Dank für den Tipp. Sowas blödes, da habe ich mich vertan.
> Ich habe den Datentyp der Variablen c nun von char zu uint16_t geändert.

so , so
Wo, genau, in dem geposteten Code hast du das gemacht?

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Ich bin langsam echt am Verzweifeln.


erstens: trenne den Empfang eines Zeichens von der Verarbeitung des 
Strings.
Beides hat erst mal nichts miteinander zu tun. D.h. in dere 
Empfangsroutine, die eine Zeile von der UART liest, hat die Auswertung 
nichts verloren. Die Empfangsroutine soll die Zeichen in einem BUffer 
sammeln und Bescheid geben, wenn ein \n gesichtet wurde und die Zeile 
somit vollständig ist.

zweitens: Die Empfangsroutine sollte im Idealfall nicht warten. Sie holt 
ein Zeichen von der UART, wenn eines da ist, und hängt es an die bisher 
empfangegen Zeichen hinten an. Wenn das Zeichen ein  \n ist, dann hängt 
sie nichts hinten an, sondern meldet dem Aurufer, dass der String 
vollständig ist.

drittens: du hast eine funktionierende UART, die du benutzen kannst. Du 
kannst sie nicht nur benutzen, um dir damit gewollte Meldungen 
auszugeben, sondern du kannst sie auch zum Debuggen benutzen. Nichts und 
niemand hindert dich daran, dass du ein Zeichen, welches du empfängst, 
zum Sender (Terminal) zurücksendest um so dort zu sehen, was los ist. 
Nichts und niemand hindert dich zb daran, dir mittels Sonderzeichen 
'Markierungen' auszugeben, so dass du als Programmierer im Terminal 
siehst, welche Schleife verlassen wird, welches if genommen wird. Du 
hast eine UART und ein Terminal! Nutze sie, damit dir das Programm 
selber hilft, es zu debuggen.

von Karl H. (kbuchegg)


Lesenswert?

Und noch was:
wenn deine Eingabe von einem anderen Programm kommt, dann leg das erst 
mal zur Seite und debugge bzw. entwickle deine Empfangs- bzw. Auswertung 
erst mal mit einem Terminal. Denn dann hast du Debug-Möglichkeiten (weil 
du auch was ausgeben kannst) und musst nicht im Nebel stochern.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

als erste Anregung, ungetestet und ohne Fehlerbehandlung
1
uint8_t inLine;
2
char lineBuff[20];
3
uint8_t lineLen;
4
5
uint8_t getLine()
6
{
7
  uint16_t c = uart_getc();
8
9
  if( c == UART_NO_DATA )
10
    return 0;
11
12
  uart_putc( '*' );
13
  uart_putc( c );
14
  uart_putc( '*' );
15
16
  if( c == '\n' ) {
17
    lineBuff[lineLen] = '\0';
18
    return 1;
19
  }
20
21
  lineBuff[lineLen] = c;
22
  lineLen++;
23
24
  lineBuff[lineLen] = '\0';  // zum debuggen, damit der String immer
25
                             // gültig ist.
26
  uart_puts( '\n' );
27
  uart_puts( lineBuff );
28
  
29
  return 0;
30
}
31
32
int main()
33
{
34
  ...
35
36
  lineBuff[0] = '\0';
37
  lineLen = 0;
38
39
  while( 1 )
40
  {
41
    if( getLine() )
42
    {
43
      uart_puts( "Kommando: *" );
44
      uart_puts( lineBuff );
45
      uart_putc( '*' );
46
47
      lineBuff[0] = '\0';
48
      lineLen = 0;
49
    }
50
  }
51
}

: Bearbeitet durch User
von Josef F. (Gast)


Lesenswert?

Karl Heinz schrieb:
> so , so
> Wo, genau, in dem geposteten Code hast du das gemacht?

Vielen Dank für Deine Tipps.

Ich habe leider bei diesem Post nur die Zeile für das Relais eingefügt. 
Die Variable habe ich in meiner Entwicklungsumgebung aber natürlich 
angepasst. Tut mir Leid dass mir da beim Erstellen des Beitrages ein 
Fehler unterlaufen ist.

Karl Heinz schrieb:
> erstens: trenne den Empfang eines Zeichens von der Verarbeitung des
> Strings.
> Beides hat erst mal nichts miteinander zu tun. D.h. in dere
> Empfangsroutine, die eine Zeile von der UART liest, hat die Auswertung
> nichts verloren. Die Empfangsroutine soll die Zeichen in einem BUffer
> sammeln und Bescheid geben, wenn ein \n gesichtet wurde und die Zeile
> somit vollständig ist.

Ich habe leider folgendes Problem, weshalb ich das auch direkt 
zusammengefasst habe. Der String welcher an meinen µC gesendet wird 
enthält nicht nur meine Befehle sondern zwischendurch auch alles 
mögliche andere. Auch etliche Zeichen lang ohne  \n.
Darauf habe ich keinen Einfluss. Lese ich jetzt dauernd nur die 
Schnittstelle ein und speichere was dort ankommt ist der Prozessor in 
der Zeit nur damit beschäftigt den sinnlosen String zu speichern.

Dann müsste ich auch noch kontrollieren ob der Buffer übergeläuft, und 
vielleicht steht dann schon ein Teil eines gültigen Befehls mit darin, 
was dann beim löschen des übergelaufenen Buffers mit gelöscht wird.

Deswegen dachte ich ich prüfe dann immer nur ob ein # vorhanden ist.
Das ist in meinem Code natürlich auch noch nicht brauchbar, da er in 
diesem Fall eben in einer Endlosschleife hängt bis ein # kommt.

Ich denke mein ganzer Ansatz ist schlecht. Wie sollte man das in diesem 
Fall denn richtig angehen?

Mich würde dennoch interessieren warum er in meinem Code nicht in die 
if-Abfrage springt.
Da ist sicher ein grundsätzlicher Fehler drin, aber ich komme nicht 
darauf :(

Danke

Gruß Josef

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Ich habe leider folgendes Problem, weshalb ich das auch direkt
> zusammengefasst habe. Der String welcher an meinen µC gesendet wird
> enthält nicht nur meine Befehle sondern zwischendurch auch alles
> mögliche andere. Auch etliche Zeichen lang ohne  \n.
> Darauf habe ich keinen Einfluss. Lese ich jetzt dauernd nur die
> Schnittstelle ein und speichere was dort ankommt ist der Prozessor in
> der Zeit nur damit beschäftigt den sinnlosen String zu speichern.

ok. Dann starte die Aufzeichnung erst mit der Erkennung des '#'.

>
> Dann müsste ich auch noch kontrollieren ob der Buffer übergeläuft,

das musst du sowieso.

> und
> vielleicht steht dann schon ein Teil eines gültigen Befehls mit darin,
> was dann beim löschen des übergelaufenen Buffers mit gelöscht wird.

Dadurch, dass du die Aufzeichnung erst startest, wenn ein '#' gesichtet 
wird, erledigt sich dann auch dieses Problem.

> Ich denke mein ganzer Ansatz ist schlecht. Wie sollte man das in diesem
> Fall denn richtig angehen?

So wie ich das skizziert habe. Nur führst du dir noch ein Flag ein, 
welches die Aussage erlaubt: können die Zeichen zu einem Kommando 
gehören oder nicht. Wird ein '#' gesichtet, geht das Flag auf 1, kommt 
der '\n' geht das Flag wieder (neben all dem anderen) auf 0. Die Zeichen 
kommen nur dann in den Buffer rein, wenn das Flag auf 1 steht.

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Mich würde dennoch interessieren warum er in meinem Code nicht in die
> if-Abfrage springt.

Ich kenn deinen letzten Code nicht. Aber
1
        while( c != '\n' )
2
        {
3
          if( c != UART_NO_DATA )
4
          {
5
            Befehlsbuffer[bufferzaehler++] = c;
6
            c = uart_getc();
7
          }
8
        }

du gehst davon aus, dass zu jedem beliebigen Zeitpunkt ein neues Zeichen 
da ist. Dem ist aber nicht so. UART ist vergleichsweise langsam. D.h. in 
der überwiegenden Mehrzahl der Fälle wirst du UART_NO_DATA kriegen.
Nur: wenn da einmal UART_NO_DATA gekommen ist, wie soll da jemals was 
anderes kommen? Du rufst ja uart_getc nie wieder auf.


Machs so, wie ich das skizziert habe. Füg noch die 
Aufzeichnungs-Start_Stop Kennung mit dem '#' hinzu und gut ists. So 
vergeudet dein Programm am wenigsten Rechenzeit und bearbeitet nur dann 
die UART, wenn es auch tatsächlich was zu tun gibt. Man muss nicht 
mutwillig den µC durch die UART lahmlegen, zumal die Änderung nicht 
aufwändig ist.

von Josef F. (Gast)


Lesenswert?

Karl Heinz schrieb:
> So wie ich das skizziert habe. Nur führst du dir noch ein Flag ein,
> welches die Aussage erlaubt: können die Zeichen zu einem Kommando
> gehören oder nicht. Wird ein '#' gesichtet, geht das Flag auf 1, kommt
> der '\n' geht das Flag wieder (neben all dem anderen) auf 0. Die Zeichen
> kommen nur dann in den Buffer rein, wenn das Flag auf 1 steht.

Gut ich werde als nächstes mal versuchen Deine Ratschläge umzusetzen.

Ich habe inzwischen noch etwas probiert.
1
    c = uart_getc();
2
    if( ! (c & UART_NO_DATA)  )
3
    {
4
      
5
      if(c=='#')
6
      {   
7
        uart_putc( '*' );
8
        uart_putc( c );
9
        uart_putc( '*' );
10
        c=0;
11
12
        c = uart_getc();
13
        uart_putc( '*' );
14
        uart_putc( c );
15
        uart_putc( '*' );
16
        while( c != '\r' )

Sende ich mit dieser Variante folgendes #test erscheint mir am Terminal 
*#***

Scheinbar liefert mir also uart_getc beim zweiten Mal kein Zeichen.
Daraufhin habe ich den Teil wie folgt geändert, also eine kleine 
Verzögerung eingebaut.
1
    c = uart_getc();
2
    if( ! (c & UART_NO_DATA)  )
3
    {
4
      
5
      if(c=='#')
6
      {   
7
        uart_putc( '*' );
8
        uart_putc( c );
9
        uart_putc( '*' );
10
        c=0;
11
        _delay_ms(10);
12
        c = uart_getc();
13
        uart_putc( '*' );
14
        uart_putc( c );
15
        uart_putc( '*' );
16
        while( c != '\r' )
Dies liefert nun wie gewünscht *#**t*

Warum ist hier eine Verzögerung nötig?

Komisch ist dann auch dass in der while-Schleife keine Verzögerung mehr 
nötig ist.
Also in diesem Teil.
1
        while( c != '\n' )
2
        {
3
          if( c != UART_NO_DATA )
4
          {
5
            Befehlsbuffer[bufferzaehler++] = c;
6
            c = uart_getc();
7
          }

Meine Main sieht ja wie oben bereits geschrieben wie folgt aus.
1
  do
2
  {
3
  Befehl();
4
5
  uart_puts(Befehlsbuffer);
6
      
7
  } while (1);
8
}

Als Gesamtausgabe am Terminal erhalte ich nun:
*#**t*test

Also wie gewünscht.
Ich verstehe nur nicht weshalb an dieser einen Stelle eine Verzögerung 
nötig ist, hat da jemand einen Tipp?

Vielen Dank

Josef

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Scheinbar liefert mir also uart_getc beim zweiten Mal kein Zeichen.

Wie oft denn noch?

Dein µC ist mindestens um einen Faktor 1000 schneller als die UART 
übertragen kann. Zwischen 2 Zeichen kann der µC sprichwörtlich auf einen 
Kaffee gehen und eine Partie Schach spielen!

Du musst bei JEDEM uart_getc abfragen, ob das UART Modul UART_NO_DATA 
liefert!

> Daraufhin habe ich den Teil wie folgt geändert, also eine kleine
> Verzögerung eingebaut.

Was soll der Quatsch?
Die Fleury Routinen melden dir mit UART_NO_DATA ob etwas da ist oder 
nicht.
Abfragen, Auswerten und darauf reagieren. Wenn nichts da ist, ist nichts 
da.

Was soll ich den noch tun, ausser dir Code zu geben? Soll ich kommen und 
ihn eintippen? Mach ich glatt.

: Bearbeitet durch User
von Josef F. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wie oft denn noch?
>
> Dein µC ist mindestens um einen Faktor 1000 schneller als die UART
> übertragen kann. Zwischen 2 Zeichen kann die UART sprichwörtlich auf
> einen Kaffee gehen und eine Partie Schach spielen!
>
> Du musst bei JEDEM uart_getc abfragen, ob das UART Modul UART_NO_DATA
> liefert!

Leider hat sich Deine letzte Antwort mit meiner letzten überschnitten, 
so dass ich sie nicht mehr lesen konnte. Das tut mir sehr Leid ich 
wollte Dich nicht mit meiner Unfähigkeit verärgern. Entschuldige dass 
ich Deine Zeit vergeudet habe...

Karl Heinz schrieb:
> Was soll ich den noch tun, ausser dir code zu geben? Soll ich kommen und
> ihn eintippen? Mach ich glatt.

Dann könnte ich wenigstens sicher sein dass das funktioniert...

Josef :(

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:

> Leider hat sich Deine letzte Antwort mit meiner letzten überschnitten,

ok. ich hab nicht auf die Zeiten geachtet.
Mein Fehler.

von Josef F. (Gast)


Lesenswert?

Spricht eigentlich etwas dagegen in den Schleifen mit break und continue 
zu arbeiten? Oder wird das normal möglichst vermieden?
1
void Befehl()
2
{
3
  
4
  uint8_t bufferzaehler = 0;
5
  uint8_t string_complete=1;
6
  uint16_t c=0;
7
  
8
  do
9
  {
10
    c = uart_getc();
11
    if( ! (c & UART_NO_DATA)  )
12
    {
13
      if(c=='#')
14
      {       
15
       while(1) 
16
         {
17
        c = uart_getc();
18
        if(c & UART_NO_DATA)
19
        continue;
20
        if( (c=='\r') || (bufferzaehler==(sizeof(Befehlsbuffer)/sizeof(Befehlsbuffer[0]) )-1))
21
        {
22
        Befehlsbuffer[bufferzaehler] = '\0';
23
        break;
24
        }
25
       Befehlsbuffer[bufferzaehler++] = c;
26
27
       }      
28
            string_complete=0;
29
      }
30
    }
31
  }while(string_complete);
32
}

Vielen Dank

Josef

von Karl H. (kbuchegg)


Lesenswert?

Josef F. schrieb:
> Spricht eigentlich etwas dagegen in den Schleifen

Warum bist du so auf die Schleife erpicht?
Die braucht keiner!
Ganz im Gegenteil: du sollst dir solche Dinge abgewöhnen. Mit Schleifen 
kommst du auf lange Sicht nicht weiter. Genau sie sind es, die dir bei 
einem µC-Programm, welches mehrere Dinge 'gleichzeitig' machen soll, nur 
Prügel zwischen die Beine werfen.

Mit deinem Ansatz kommst du nicht weiter, wenn dein µC gleichzeitig die 
Temperatur überwachen soll, abhängig davon eine Heizung regeln muss und 
nebenher auch noch auf Befehle hören soll. Geh weg von diesen 
Warteschleifen! Der Ansatz in der µC Programmierung ist praktisch immer 
der, dass man nacheinander alle Ereignisquellen abklappert, feststellt, 
ob es etwas zu tun gibt und wenn ja, dann macht man das. Bei einer UART 
ist das leicht. Denn was bedeutet denn 'etwas zu tun'? Es gibt genau 
dann etwas zu tun, wenn an der UART ein Zeichen vorliegt. Dieses holt 
man sich und entscheidet dann was man mit dem Zeichen machen möchte. Das 
kann sein, dass man nichts damit macht, das kann auch sein, dass man es 
in einen Textstring anhängt. Und dann gibt es noch den Fall, dass im 
Textstring auf die Art ein komplettes Kommando entstanden ist. Dann wird 
das augewertet. Aber was du nicht machen willst, das ist ständig in der 
Schleife zu hocken und nur und ausschliesslich darauf zu warten, dass 
der Befehl dann irgendwann komplett ist. Wenn du Pech hast, dann hat der 
µC kurz zuvor im Aquarium die Heizung eingeschaltet, der µC wartet auf 
das Ende eines Befehls und weil der Benutzer zwischendurch sich noch 
einen Kaffee holt und aufs Klo muss, gibt es plötzlich Fischsuppe.
Das alles muss nicht sein. Die Technik dazu ist einfach und sie führt 
NICHT darüber, dass man in Schleifen auf irgendwelche Ereignisse wartet. 
Es gibt nur eine einzige Schleife (abgesehen von technisch notwendigen 
kleineren Schleifen): und das ist die Hauptschleife in main. Abgesehen 
von der gibt es keine Schleifen die auf irgendwas warten würden 
(zumindest nicht wenn es länger dauert).

Alles was du in deinem Fall noch brauchst, ist eine kleine Steuerung, 
dass ein Kommando erst nach einem '#' anfangen kann, weil da noch andere 
Dinge dazwischen sind. Das ist doch nicht weiter schwer:
1
#define DEBUG
2
3
uint8_t inCommand;
4
uint8_t lineLen;
5
char    lineBuff[20];
6
7
...
8
uint8_t getLine( void )
9
{
10
  uint16_t c = uart_getc();
11
12
  if( c == UART_NO_DATA )
13
    return 0;
14
15
#ifdef DEBUG
16
  uart_putc( '*' );
17
  uart_putc( c );
18
  uart_putc( '*' );
19
#endif
20
21
  if( c == '\n' ) {
22
    lineBuff[lineLen] = '\0';
23
    inCommand = 0;
24
    return 1;
25
  }
26
27
  if( c == '#' ) {
28
    inCommand = 1;
29
    return 0;
30
  }
31
32
  if( inCommand && lineLen < sizeof(lineBuff)-1 ) {
33
    lineBuff[lineLen] = c;
34
    lineLen++;
35
36
#ifdef DEBUG
37
  // zum debuggen, damit der String immer
38
  // gültig ist.
39
    lineBuff[lineLen] = '\0';
40
    uart_puts( '\n' );
41
    uart_puts( lineBuff );
42
#endif
43
  }
44
45
  return 0;
46
}
47
48
49
int main()
50
{
51
  ...
52
53
  inCommand = 0;
54
  while( 1 ) {
55
56
    // hole das nächste Zeichen von der UART wenn es einen gibt
57
    // und hänge es an ein potentielles Kommando hinten drann
58
    // wenn dadurch eine Befehl vollständig geworden ist, dann liefert
59
    // getLine TRUE ansonsten FALSE
60
61
    if( getLine() )
62
    {
63
      uart_puts( "Kommando: *" );
64
      uart_puts( lineBuff );
65
      uart_puts( "*\n" );
66
67
      if( strcmp( lineBuff, "ON" ) == 0 ) {
68
        // ON Kommando
69
      }
70
71
      else if( strcmp( lineBuff, "OFF" ) == 0 ) {
72
        // OFF Kommando
73
      }
74
75
      else
76
        uart_puts( "kenn ich nicht\n" );
77
78
      lineBuff[0] = '\0';
79
      lineLen = 0;
80
    }
81
82
    ....
83
  }

fertig ist die Laube. Das ist so einfach, wie einem Baby den Schnuller 
klauen. Ganz ohne komplizierte Schleifensteuerungen.

: Bearbeitet durch User
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.