Forum: Compiler & IDEs Wie Befehle via serieller Schnittstelle erkennen (mit scanf)


von Marc M. (macmek)


Lesenswert?

Ich möchte via serieller Schnittstelle Befehle an den uC (ATmega64) 
senden, im Format:
1
ServoA=1000
2
ServoB=1200
3
Lampe=0
4
Text=Hallo Welt!

Sobald im empfangenen Text ein "Enter" vorkommt wird dieser als String 
"SerialText" dem Programm übergeben. Soweit funktioniert alles 
einwandfrei.

Die Servoposition konnte ich vor rund einem Jahr damit heraus lesen:
1
sscanf(SerialText, "S=%d", &a);

Doch das scheint nicht mehr zu passen:
1
Test232.c: In function 'main':
2
Test232.c:337: warning: passing argument 1 of 'sscanf' discards qualifiers from pointer target type

Was stimmt nicht ?

Ich wollte darauf aufbauen:
1
int main(void)
2
{
3
  int a,b;
4
  char S1[30]="\0";
5
  char S2[30]="\0";
6
7
  for (;;)
8
   {
9
        if ( Enter == 1 )
10
        {
11
12
           sscanf(SerialText, "%s=%s", &S1, &S2);
13
14
           if (!strcmp(S1,"ServoA")) {
15
             sscanf(SerialText, "S=%d", &a);
16
             sprintf( s, "\n\rServo A = %i\n\r> ", a);
17
             Sende1String (s); //Echo an RS232
18
             Enter = 0;
19
           }//Servo A
20
21
          // weitere Abfragen...
22
        
23
        }//if Enter
24
    }//for
25
26
}//main

Geht das so oder gibt es einen besseren Weg ?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Welchen qualifier hat die Variable SerialText denn?

von Marc M. (macmek)


Lesenswert?

Global:
1
volatile char SerialText[50]="\0";

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, das isses doch. sscanf erwartet halt keinen volatile-Pointer.

Das ist bei Arrays eh' unnötig, die kann der gcc-Optimizer sowieso nicht 
in Prozessorregistern unterbringen.

Also:

Entweder "volatile" bei der Deklaration weglassen oder beim Aufruf von 
sscanf einen Typecast nach (char *) vornehmen.

von Marc M. (macmek)


Lesenswert?

Juhu es funktioniert ohne volatile !
Aber nur bis zum ersten Leerzeichen, dann ist Schluss.
1
sscanf(SerialText, "Text=%s", &S1);
2
sprintf( s, "\n\rText = %s\n\r> ", S1);

Ich habe keine Möglichkeit gefunden, das Trennzeichen zu verändern, oder 
etwas mit Nullterminiert zu machen, richtig ?

Sonst versuche ich den Ursprungsstring ab der 5. Stelle bis Null zu 
kopieren.

von Karl H. (kbuchegg)


Lesenswert?

Marc Mk wrote:
> Juhu es funktioniert ohne volatile !
> Aber nur bis zum ersten Leerzeichen, dann ist Schluss.
>
>
1
sscanf(SerialText, "Text=%s", &S1);
2
> sprintf( s, "\n\rText = %s\n\r> ", S1);
>
> Ich habe keine Möglichkeit gefunden, das Trennzeichen zu verändern, oder
> etwas mit Nullterminiert zu machen, richtig ?
>
> Sonst versuche ich den Ursprungsstring ab der 5. Stelle bis Null zu
> kopieren.

Das ist sicherlich die einfachere Lösung :-)

strcpy( SerialText, &S1[5] );

sscanf ist dafür wirklich mit Kanonen auf Spatzen geschossen.


von Klaus F. (kfalser)


Lesenswert?

Du solltes die strtok() Funktion verwenden um den String in 2 Teile mit 
'=' als Trennzeichen zu trennen.

%s liest immer bis zum nächsten Whitespace.

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.