Forum: Mikrocontroller und Digitale Elektronik Informationen aus String in Daten umwandeln


von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

Hallo C-Freunde,

ich habe ein Problem, möchte gerne ein Mikrocontroller-Netzteil bauen, 
ich bin auch schon fast fertig, und nun möchte ich das Ding auch über 
UART bedienen können.

Es kommt also ein String an der so aussieht:

"USET 12.00"
oder
"ISET 0.50"

so sieht das aus.


ich habe auch schon einen Code der mir den String aufteilt einmal in den 
String Befehl[]  (USET)   und einmal in den String Wert[]  (Zahl)
wenn man genauer hinsieht sieht man dass es *Befehl und *Wert heißt aber 
ich kenn mich mit dem Zeigern nicht so aus.  (ich habe das aus dem 
Internet entdeckt)
....
(bis hierher klappts)
.....
nun bekomme ich es nicht hin, dass ich z.b. per SWITCH CASE Funktion 
oder einfach mit IF den Befehl abfrage.

und die Zahl müsste noch umgewandelt werden in float

anbei ein Codeausschnitt
1
.......
2
3
char string[20];
4
char *wert, *befehl;
5
const char trennzeichen[] = " ";
6
7
......
8
9
10
11
12
13
14
void remote(void)      //Fernsteuerung über RS-232
15
{
16
        string[f] = puffer;
17
          f = f+1;
18
          rprintfStr(string);
19
        
20
        
21
            if(puffer == 13)               //Wenn puffer = RETURN/ENTER dann...
22
          {
23
           // initialisieren und ersten Abschnitt erstellen
24
           befehl = strtok(string, trennzeichen);    //String beim Trennzeichen (LEER) zerteilen
25
          
26
           rprintfCRLF();                //Ausgabe...
27
           rprintf("Befehl: ");
28
           rprintfStr(befehl);
29
           rprintfCRLF();
30
           // naechsten Abschnitt erstellen
31
           wert = strtok(NULL, trennzeichen);      //hier muss NULL stehen???
32
           rprintf("Wert: ");
33
           rprintfStr(wert);
34
           rprintfCRLF();
35
           puffer = 0;
36
         
37
             f=0;
38
             for(g=0;g<20;g++)              //string wird gelöscht
39
           string[g] = 0;
40
41
42
43
    rprintf("befehl: %d",befehl);
44
    rprintf("wert: %d",wert);
45
46
          }
47
48
           puffer = 0;                    //Variable puffer für RS232 leeren
49
50
    
51
/*
52
    if (befehl == "USET")
53
    {
54
     voltage = value * 1000;
55
     da_load(1, voltage);    //chipselect (CS):  1 = Spannung;  value = Analogwert in Millivolt mV
56
     _delay_ms(50);
57
    }    
58
59
60
  switch (befehl)
61
  {
62
    case USET:  spannung = wert;
63
          da_load(1, voltage);    //chipselect (CS):  1 = Spannung;  value = Analogwert in Millivolt mV
64
          _delay_ms(50);
65
          break;
66
67
    case ISET:  strom = wert;
68
          da_load(2, current);    //chipselect (CS):  2 = Strom;     value = Analogwert in Millivolt mV
69
          _delay_ms(50);
70
          break;
71
    
72
    case OUTPUT:   if(wert==OFF)
73
             {u_aus;}
74
            if(wert==ON)
75
            {u_ein;}
76
            break;
77
    
78
    case DISPLAY:  if(wert==OFF)
79
             {???;}
80
            if(wert==ON)
81
            {???;}
82
            break;
83
84
  }
85
*/
86
}

von Karl H. (kbuchegg)


Lesenswert?

Martin 567 schrieb:

> ich habe auch schon einen Code der mir den String aufteilt einmal in den
> String Befehl[]  (USET)   und einmal in den String Wert[]  (Zahl)
> wenn man genauer hinsieht sieht man dass es *Befehl und *Wert heißt aber
> ich kenn mich mit dem Zeigern nicht so aus.  (ich habe das aus dem
> Internet entdeckt)

Genau hier liegt das Problem.
Programmieren kann man nicht lernen, indem man sich im 'Internet' 
irgendwelche Codestückchen zusammensucht.
Du brauchst Literatur oder wenigstens ein C-Tutorial!

Zur Überbrückung, kannst du dir auch das wichtigste hier rauslesen
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

> nun bekomme ich es nicht hin, dass ich z.b. per SWITCH CASE Funktion
> oder einfach mit IF den Befehl abfrage.

Das geht auch nicht bei Strings. switch-case kann man nur bei konstanten 
Zahlen benutzen. strcmp ist hier dein Freund.

> und die Zahl müsste noch umgewandelt werden in float

strtod()

von tip-geber (Gast)


Lesenswert?

Du schreibst
if (befehl == "USET")
das geht in VisualBasic, wenn befehl ein String ist.
In C geht das nicht.
Vorschlag, Funktion schreiben, die Zeichen für Zeichen
den empf. Befehl mit einem Befehlsarray im Flash vergleicht und Dir
die Befehlsnummer (Stelle in dem Array) zurückgibt. Der 
einfachheit-halber
legst Du dir noch ein ENUM an, was die Befehlsreihenfolge abbildet.
Mit der Befehlsnummer (enum) kannst du dann Deine switch-case abfrage
machen.

von Karl H. (kbuchegg)


Lesenswert?

tip-geber schrieb:
> Du schreibst
> if (befehl == "USET")
> das geht in VisualBasic, wenn befehl ein String ist.
> In C geht das nicht.
> Vorschlag, Funktion schreiben, die Zeichen für Zeichen
> den empf. Befehl mit einem Befehlsarray im Flash vergleicht und Dir
> die Befehlsnummer (Stelle in dem Array) zurückgibt. Der
> einfachheit-halber
> legst Du dir noch ein ENUM an, was die Befehlsreihenfolge abbildet.
> Mit der Befehlsnummer (enum) kannst du dann Deine switch-case abfrage
> machen.


Was noch Komplizierteres als das ist dir jetzt auf die Schnelle nicht 
eingefallen?

von tip-geber (Gast)


Lesenswert?

@ karl heinz Buchegger
was ist daran kompliziert, wenn man lieber 'ne selbstgeschriebene
Funktion benutzt, als fertige Stringfunktionen die der Compiler bietet.
Und zweitens ist es gleichzeitig noch eine schöne Übung.

von Karl H. (kbuchegg)


Lesenswert?

kompliziert ist es aus Strings einen enum zu machen und den dann in 
einen switch case zu stopfen, anstelle von
1
  if( strcmp( befehl, "USET" ) == 0 ) {
2
     // behandle den Befehl USET
3
  }
4
5
  else if( strcmp( befehl, "ISET" ) == 0 ) {
6
     // behandle den Befehl ISET
7
  }
8
9
  else if( strcmp( befehl, "OUTPUT" ) == 0 ) {
10
     // bahandle den Befehl OUTPUT
11
  }
12
13
  else if( strcmp( befehl, "DISPLAY" ) == 0 ) {
14
     // behandle den Befehl DISPLAY
15
  }
16
17
  else {
18
    // Fehler, kein bekannter Befehl
19
  }


wir reden hier von einer simplen Auswertung und nicht von einem 
Cmopiler-Parser, bei dem der String viele zig-male mit Keywords 
verglichen wird.

> wenn man lieber 'ne selbstgeschriebene
> Funktion benutzt

Die Stringfunktionen in C gibt es ja auch nur deshalb, damit dann doch 
wieder jeder sein eigenes Süppchen kocht. Wäre ja auch zu einfach, wenn 
jeder andere C Programmierer den Code auf Anhieb lesen kann ohne erst 
die 'Sonderfunktionen' zu analysieren und sich zu fragen warum in 3 
Teufels Namen da eigene Varianten geschrieben wurden, anstatt die in C 
vorgesehenen Funktionen zu verwenden. :-) Schreibst du dir eigentlich 
einen Sinus auch selbst?

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo

das mit strcmp hab ich vorher schon selbst probiert, da ich mir nicht 
"alles" aus dem internet hole!

  if( strcmp( befehl, "USET" ) == 0 ) {
     // behandle den Befehl USET
  }

genau wies da steht, aber anscheinend hängt es auch mit den zeiger 
*Befehl und *Wert zusammen, aber ich bekomme nicht 0 raus sondern 
irgendeinen wert wie 83 oder so
und der ist bei jeder eingabe der selbe.

hm.
ich probier morgen mal noch ein paar stringfunktionen durch

trotzdem danke
servus martin

von Karl H. (kbuchegg)


Lesenswert?

Martin 567 schrieb:
> hallo
>
> das mit strcmp hab ich vorher schon selbst probiert, da ich mir nicht
> "alles" aus dem internet hole!
>
>   if( strcmp( befehl, "USET" ) == 0 ) {
>      // behandle den Befehl USET
>   }
>
> genau wies da steht, aber anscheinend hängt es auch mit den zeiger
> *Befehl und *Wert zusammen, aber ich bekomme nicht 0 raus sondern
> irgendeinen wert wie 83 oder so
> und der ist bei jeder eingabe der selbe.

Dann hast du nicht richtig zerlegt :-)
Oder aber deine Ausgabe des Ergebnisses ist nicht richtig
(zb das hier:     rprintf("befehl: %d",befehl); bringt mich auf diese 
Idee)

Gross/Kleinschreibung hast du beachtet?

von tip-geber (Gast)


Lesenswert?

@ karl heinz Buchegger

mist, ich bekomme es nicht hin.
Wie geht das mit der Code-formatierung?
Einfach durch [c] und [\c] einfassen ?
Danke, schon mal im voraus.

von Karl H. (kbuchegg)


Lesenswert?

tip-geber schrieb:
> @ karl heinz Buchegger
>
> mist, ich bekomme es nicht hin.
> Wie geht das mit der Code-formatierung?
> Einfach durch [c] und [\c] einfassen ?

Ganz genau

von tip-geber (Gast)


Lesenswert?

würde es so machen:

[c]
befehl = GetBefehl();

switch(befehl)
   {
   case USET:
              break;
   case OUTP:
              break;
   default:
              break;
   }
[\c]

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:
> tip-geber schrieb:
>> @ karl heinz Buchegger
>>
>> mist, ich bekomme es nicht hin.
>> Wie geht das mit der Code-formatierung?
>> Einfach durch [c] und [\c] einfassen ?
>
> Ganz genau

Tschuldigung  der \ muss ein / sein

(Steht aber auch in der Box über dem Eingabefeld unter Formatierungen)

von tip-geber (Gast)


Lesenswert?

Formatierung geht nicht, wieso nicht ???
Gibbed doch nid!

von Karl H. (kbuchegg)


Lesenswert?

tip-geber schrieb:
> würde es so machen:

Wenn ich es für mich mache, würde ich das ganz anders machen, das ist 
mir nämlich zu unübersichtlich :-)
1
struct command {
2
  char * Name;
3
  void (*Function)( const char* );
4
}
5
6
void HandleUset( const char* argument )
7
{
8
}
9
10
void HandleIset( const char* argument )
11
{
12
}
13
14
void HandleOutput( const char* argument )
15
{
16
}
17
18
void HandleDisplay( const char* argument )
19
{
20
}
21
22
struct command commands[] = 
23
{
24
  {  "USET",    HandleUset },
25
  {  "ISET",    HandleIset ),
26
  {  "OUTPUT",  HandleOutput ),
27
  {  "DISPLAY", HandleDisplay ),
28
};
29
30
void CallFunction( const char* FunctionName, const char* Argument )
31
{
32
  size_t i;
33
  for( i = 0; i < sizeof( commands ) / sizeof( *commands ); ++i ) {
34
    if( strcmp( commands[i].Name, FunctionName ) == 0 ) {
35
      commands[i].Function( Argument );
36
      return;
37
    }
38
  }
39
}
40
41
int main()
42
{
43
  .....
44
45
  CallFunction( befehl, wert );
46
47
  ....

Neues Kommando?
Kein Problem:
Eine Behandlungsfunktion dafür geschrieben und ein neuer Eintrag ins 
Array und schon wird die Funktion angesprungen, wenn das Kommando 
erkannt wird.

Wenn schon afwändig, dann wenigstens so, dass sich in Zukunft eine 
Zeitersparnis ergibt :-)

von tip-geber (Gast)


Lesenswert?

danke,
wer lesen kann ist klar im Vorteil!
1
befehl = GetBefehl();
2
3
switch(befehl)
4
   {
5
   case USET:
6
              break;
7
   case OUTP:
8
              break;
9
   default:
10
              break;
11
   }

tschüss ;-)

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

tut mir leid karl heinz, deine gedanken schnall i noch nicht.
was ist überhaut ein struct
werde mich mal noch ein bisschen schlauer machen müssen
da ich eigentlich schon ein ziemlicher anfänger bin und das geb ich auch 
zu.

aba so insgesamt sieht es schon sehr vielversprechend aus


hm
danke dafür

von Karl H. (kbuchegg)


Lesenswert?

Martin 567 schrieb:
> tut mir leid karl heinz, deine gedanken schnall i noch nicht.

LOL

> was ist überhaut ein struct

OK.
Vergiss es wieder.
Da liegen dann noch ein paar andere Feinheiten dahinter :-)

(Ein struct ist eine Struktur.
Daten die zusammen gehören, werden in einen gemeinsamen neuen Datentyp 
gepackt.
zb ein Datum. Ein Datum besteht immer aus Tag, Monat, Jahr. Immer? 
Immer! Spricht man von einem Datum dann ist das immer dieses Trippel. 
Also ist es naheliegend mir für ein Datum eine Struktur zu bauen, die 
genau das ausdrückt
1
struct Date {
2
  uint8_t  day;
3
  uint8_t  month;
4
  uint16_t year;
5
};

Damit kann ich mir dann Funktionen bauen, die zb mit einem Datum 
operieren
zb
1
void printDate( struct Date* date )
2
{
3
  printf( "%02d.%02d.%04d" date->day, date->month, date-year );
4
}

oder ich habe eine 'Datenbank' in der Personen gespeichert sind, die zb 
an einem bestimmten Tag ja Geburtstag haben. Was ist ein Geburtstag ... 
datentypmässig. Genau ... es ist ein Datum
1
struct Person {
2
  char        firstName[30];
3
  char        lastName[30];
4
  struct Date birthDay;
5
};

Hab ich jetzt eine Person
1
 struct Person Bob;
und ist die richtig initialisiert, dann hat die natürlich auch 
irgendwann Geburtstag. Will ich den ausgeben:
1
  printDate( &Bob.birthday );

Ich hample hier also nicht mehr mit Tag/Monat/Jahr rum sondern betrachte 
ein Datum als eine Einheit. Ein neuer Datentyp, der alles beinhaltet was 
ein Datum ausmacht.
Und natürlich beinhaltet der Datentyp für Person alles was eine Person 
ausmacht. Habe ich also ein struct Person Objekt, dann ist da alles mit 
dabei: sein Vorname, Nachname und sein Geburtstag (als Tag/Monat/Jahr)


In dem Beispiel hab ich eine Struktur gebaut aus dem Kommandonamen und 
der Funktion die dafür zuständig ist, dieses Kommando zu bearbeiten.


Ich habe mit LOL angefangen, weil dieser Aufbau natürlich für die 4 
Kommandos um die es hier geht völliger Overkill ist. Und wenn tip-geber 
ehrlich ist, ist auch seine Variante overkill. Denn um die strcmp kommt 
er nicht herum, selbst dann nicht, wenn er sie in einer Funktion 
GetBefehl() versteckt :-) Durch den vorgeschlagenen enum hat er einfach 
nur ein zusätzliches Element ins Spiel gebracht, welches bei Änderungen 
nachgezogen werden muss.


Ich sags nochmal ausdrücklich:
Vergiss das mit der struct wieder.
Mach eine ganz stinknormale if/else-if Kette die mit strcmp den 
richtigen Zweig raussucht.

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

Hallo,

ich möchte das ja gern machen mit dem strcmp();

code:
1
            if(puffer == 13)               //Wenn puffer = RETURN/ENTER dann...
2
          {
3
           // initialisieren und ersten Abschnitt erstellen
4
           befehl = strtok(string, trennzeichen);    //String beim Trennzeichen (LEER) zerteilen
5
          
6
           rprintfCRLF();                //Ausgabe...
7
           rprintf("Befehl: ");
8
           rprintfStr(befehl);
9
           rprintfCRLF();
10
           // naechsten Abschnitt erstellen
11
           wert = strtok(NULL, trennzeichen);      //hier muss NULL stehen???
12
           rprintf("Wert: ");
13
           rprintfStr(wert);
14
           rprintfCRLF();
15
           puffer = 0;
16
17
            strcat( befehl, "\0" );
18
           strcat( wert, "\0" );
19
20
21
22
             f=0;
23
             for(g=0;g<20;g++)              //string wird gelöscht
24
           string[g] = 0;
25
26
27
          }
28
29
           puffer = 0;                    //Variable puffer für RS232 leeren
30
31
32
    strvergleich = strcmp(befehl, "USET");
33
    rprintf("strvergleich: %d", strvergleich);

Hyperterm:
--------------------------
Befehl: USET
Wert: 5.00
strvergleich: -85
--------------------------


aba das läuft nicht, ich wäre jemandem dankbar wenn er mir vll eine 
einfache funktion zeigen könnte wo der String anständig getrennt wird, 
da das anscheinden der Fehler ist.

danke martin!!!!

von Karl H. (kbuchegg)


Lesenswert?

Mach mal folgendes

           rprintfCRLF();                //Ausgabe...
           rprintf("Befehl: &");
           rprintfStr(befehl);
           rprintf("&");

um zu sehen, ob sich im Befehlsstring noch Leerzeichen verstecken.
Die AUsgabe muss sein
Befehl: &USET&

Zwischen den & und dem Buchstaben daneben darf kein Leereum sein, auch 
kein Zeilenumbruch.

und schmeiss die
             strcat( befehl, "\0" );
           strcat( wert, "\0" );

raus. Die Strings sind schon 0-terminiert.

von Karl H. (kbuchegg)


Lesenswert?

Ähm

             for(g=0;g<20;g++)              //string wird gelöscht
           string[g] = 0;



das ist zu früh.
Du darfst den String hier noch nicht löschen.
befehl und wert sind Pointer in diesen String! Der wird noch gebraucht!

Kein Wunder, dass dir kein strcmp funktioniert.

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hallo



genaue Eingabe:   USET 5.00    [ENTER]

--------Hyperterm---------
Befehl: &USET&
Wert: 5.00
------------------------


also keine leerzeichen versteckt oder?

ich weis es nicht mehr :)
kann es nicht sein dass es mit dem *befehl was zu tun hat, das ist ein 
Zeiger oder, aber ich die hab i ehrlichgesagt noch nie ganz begriffen.

danke

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

ohhh ok ich probiers.....

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

KARL HEINZ DU BIST ECHT SUPER!!!


ok bis hierher gehts ich hab  "0"

ich berichte wieder wenn ich den code wieda ein bisschen gradegerückt 
hab.

daanke

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

Hallo

sodala...

hier ist die funktion "remote", die ich bei UART-Interrupt aufrufe.

[c]
float spannung=0, strom=0, umess=0, imess=0, upwm=0, power;
char puffer=0;

char string[20];
char *wert, *befehl;
const char trennzeichen[] = " ";



void remote(void)      //Fernsteuerung über RS-232
{
        string[f] = puffer;
          f = f+1;
          rprintfStr(string);


            if(puffer == 13)               //Wenn puffer = RETURN/ENTER 
dann...
          {
           // initialisieren und ersten Abschnitt erstellen
           befehl = strtok(string, trennzeichen);    //String beim 
Trennzeichen (LEER) zerteilen
                  rprintf("Befehl: ");
                  rprintfStr(befehl);
           rprintfCRLF();
           // naechsten Abschnitt erstellen
           wert = strtok(NULL, trennzeichen);      //hier muss NULL 
stehen???
           rprintf("Wert: ");
           rprintfStr(wert);
           rprintfCRLF();
           puffer = 0;


             if     (strcmp(befehl, "USET") == 0)      //Befehl 1
            {
            spannung = atof(wert);
             rprintf("Spannung-Soll = ");
            rprintfFloat(5, spannung);
            voltage = spannung * 100.0;
            da_load(1, voltage);    //chipselect (CS):  1 = Spannung; 
value = Analogwert in Millivolt mV
            _delay_ms(50);
            }

            else if  (strcmp(befehl, "ISET") == 0)
            {
            }

            else if  (strcmp(befehl, "OUTPUT") == 0)
            {
            }

            else if  (strcmp(befehl, "DISPLAY") == 0)
            {
            }

            else if  (strcmp(befehl, "UOUT?") == 0)
            {
            }

            else if  (strcmp(befehl, "IOUT?") == 0)
            {
            }

            else if  (strcmp(befehl, "POUT?") == 0)
            {
            }


             f=0;
             for(g=0;g<20;g++)              //string wird gelöscht
           string[g] = 0;

          }

           puffer = 0;                    //Variable puffer für RS232 
leeren

}
[\c]


aber leider funktioniert die atof() funktion nicht wie gewollt, der 
compiler bringt mir folgende fehlermeldung:

\libc.a(cmpsf2.o): In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_eq_sf.o):(.t 
ext+0x0):  first defined here
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr51\li 
bc.a(cmpsf2.o):  In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_lt_sf.o):(.t 
ext+0x0):  first defined here
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr51\li 
bc.a(cmpsf2.o):  In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_le_sf.o):(.t 
ext+0x0):  first defined here


komisch!!

die atof funktion ist ja dafür geegnet oder.
ich will den String Wert, der ja eine Kommazahl ist, in eine Float-zahl 
umwandeln.

vll weis jemand was
danke
martin!!!

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

Hallo

Entschuldigung!!!!
hier nochmal mit C-Formatierung

hier ist die funktion "remote", die ich bei UART-Interrupt aufrufe.
1
float spannung=0, strom=0, umess=0, imess=0, upwm=0, power;
2
char puffer=0;
3
4
char string[20];
5
char *wert, *befehl;
6
const char trennzeichen[] = " ";
7
8
9
10
void remote(void)      //Fernsteuerung über RS-232
11
{
12
        string[f] = puffer;
13
          f = f+1;
14
          rprintfStr(string);
15
16
17
            if(puffer == 13)               //Wenn puffer = RETURN/ENTER
18
dann...
19
          {
20
           // initialisieren und ersten Abschnitt erstellen
21
           befehl = strtok(string, trennzeichen);    //String beim
22
Trennzeichen (LEER) zerteilen
23
                  rprintf("Befehl: ");
24
                  rprintfStr(befehl);
25
           rprintfCRLF();
26
           // naechsten Abschnitt erstellen
27
           wert = strtok(NULL, trennzeichen);      //hier muss NULL
28
stehen???
29
           rprintf("Wert: ");
30
           rprintfStr(wert);
31
           rprintfCRLF();
32
           puffer = 0;
33
34
35
             if     (strcmp(befehl, "USET") == 0)      //Befehl 1
36
            {
37
            spannung = atof(wert);
38
             rprintf("Spannung-Soll = ");
39
            rprintfFloat(5, spannung);
40
            voltage = spannung * 100.0;
41
            da_load(1, voltage);    //chipselect (CS):  1 = Spannung;
42
value = Analogwert in Millivolt mV
43
            _delay_ms(50);
44
            }
45
46
            else if  (strcmp(befehl, "ISET") == 0)
47
            {
48
            }
49
50
            else if  (strcmp(befehl, "OUTPUT") == 0)
51
            {
52
            }
53
54
            else if  (strcmp(befehl, "DISPLAY") == 0)
55
            {
56
            }
57
58
            else if  (strcmp(befehl, "UOUT?") == 0)
59
            {
60
            }
61
62
            else if  (strcmp(befehl, "IOUT?") == 0)
63
            {
64
            }
65
66
            else if  (strcmp(befehl, "POUT?") == 0)
67
            {
68
            }
69
70
71
             f=0;
72
             for(g=0;g<20;g++)              //string wird gelöscht
73
           string[g] = 0;
74
75
          }
76
77
           puffer = 0;                    //Variable puffer für RS232
78
leeren
79
80
}


aber leider funktioniert die atof() funktion nicht wie gewollt, der
compiler bringt mir folgende fehlermeldung:

\libc.a(cmpsf2.o): In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_eq_sf.o):(.t 
ext+0x0):
first defined here
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr51\li 
bc.a(cmpsf2.o):
In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_lt_sf.o):(.t 
ext+0x0):
first defined here
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr51\li 
bc.a(cmpsf2.o):
In function `__lesf2':
c:/winavr-20090313/bin/../lib/gcc/avr/4.3.2/avr51\libgcc.a(_le_sf.o):(.t 
ext+0x0):
first defined here


komisch!!

die atof funktion ist ja dafür geegnet oder.
ich will den String Wert, der ja eine Kommazahl ist, in eine Float-zahl
umwandeln.

vll weis jemand was
danke
martin!!!

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

sorry
jetzt geht es,

hatte vergessen die libm.a  hinzuzufügen.

jezt läufts

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

ICH HABE LEIDER EIN WEITERES PROBLEM.

der string "wert" soll auch z.b. ON/OFF annehmen können.

also mache ich wieder folgendes:
1
else if  (strcmp(befehl, "OUTPUT") == 0)      //Befehl 3
2
              {
3
               
4
              if (strcmp(wert, "ON") == 0)              
5
                {rprintf("scharf");
6
                 led_rt_on;              //LED 'Spannung ein' leuchtet
7
                 writetext("*", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
8
                 u_ein;                //Transistor ein
9
                }
10
            
11
              if (strcmp(wert, "OFF") == 0)
12
                {led_rt_off;            //LED 'Spannung ein' leuchtet
13
                 writetext(" ", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
14
                 u_aus;                //Transistor ein};
15
                }
16
              }

leider geht es nur wenn ich ins Hyperterminal schreibe "OUTPUT ON "

-> d.h. ich muss das LEERZEICHEN am schluss irgendwie weglöschen, hört 
sich einfach an aber ich kanns nicht

bitte karl-heinz ich brauche dich ein letztes mal
danke!!!!!!!!!!

von Karl H. (kbuchegg)


Lesenswert?

Das Problem dürfte hier bereits vorliegen:
1
void remote(void)      //Fernsteuerung über RS-232
2
{
3
        string[f] = puffer;
4
          f = f+1;
5
          rprintfStr(string);
6
7
8
            if(puffer == 13)               //Wenn puffer = RETURN/ENTER
9
dann...
10
          {

Was passiert alles, wenn ein Return reinkommt?
Nun, du hängst den Return genauso an den String an wie jedes andere 
Zeichen und dann kommt er dir bei der Auswertung in die Quere :-)

Der erste Schritt besteht immer darin, dass man überprüft, ob das was 
reinkommt auch dem entspricht was man erwartet. Dazu ist es sinnvoll, 
wenn du Kontrollausdrucke machst. Aber du musst das richtig machen: Vor 
und hinter den String kommt irgendein Sonderzeichen, dass normalerweise 
nicht im Text vorkommen wird (wenn es vorkommt ist das auch kein 
Beinbruch). Wichtig ist: Das du siehst, ob vor deinem Text ein 
Leerzeichen, Tabulator oder sonst irgendein Zeichen sitzt, welches in 
einem Leerraum ausartet. Den übersieht man nämlich sehr gerne, wenn man 
nicht weiß, wo der Text anfängt. Dassselbe gilt auch für das Stringende: 
Mach dir ein Sonderzeichen hin, so dass du siehst, ob hinter deinem Text 
noch Leerzeichen, Tabulator oder, besonders gemein, Zeilenumbrüche 
kommen. Das Begrenzungszeichen muss direkt an deinen Text anschliessen! 
Wenn nicht, dann hat sich da ein nicht sichtbares Zeichen 
eingeschmuggelt.


Das hier
1
          rprintfStr(string);
ist ein netter Versuch. Aber dich interessieren eben auch die nicht 
sichtbaren Zeichen
1
          rprintfStr( "&" );
2
          rprintfStr( string );
3
          rprintfStr( "&" );

jetzt hast du dir eine Möglichkeit geschaffen, wie du auch solche 
Zeichen sehen kannst.
Wenn die Ausgabe an dieser STelle lautet
&OUTPUT ON
&
dann hat sich da ein Zeilenvorschub eingeschlichen :-) Die Ausagbe muss 
so aussehen
&OUTPUT ON&


Und ich denke genau das ist dein Problem.
Verändere das Zeichensammeln, so dass der \n (der Return) nicht im 
String landet.
1
void remote( void )
2
{
3
  if( puffer != '\n' ) {       // bei einem Return beginnt die Auswertung
4
                               // solange kein Return kommt, werden die Zeichen
5
                               // einfach nur gesammelt
6
7
    string[f] = puffer;
8
    f++;
9
    return;
10
  }
11
12
  // Ein Return ist eingetroffen. Damit ist der String vollständig
13
  string[f] = '\0';         // erst mal einen sauberen C-String daraus machen
14
15
  rprintfStr( "&" );        // zu Kontrollzwecken ausgeben
16
  rprintfStr( string );
17
  rprintfStr( "&" );
18
19
20
  befehl = strtok(string, " \t");    // dann zerteilen
21
  wert = strtok(NULL, " \t");
22
23
  if     (strcmp(befehl, "USET") == 0)
24
  {
25
     ....
26
  }
27
28
  ...
29
  else if  (strcmp(befehl, "OUTPUT") == 0)
30
  {
31
    if (strcmp(wert, "ON") == 0)              
32
    {
33
      rprintf("scharf");
34
      led_rt_on;              //LED 'Spannung ein' leuchtet
35
      writetext("*", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
36
      u_ein;                //Transistor ein
37
    }
38
            
39
    if (strcmp(wert, "OFF") == 0)
40
    {
41
      led_rt_off;            //LED 'Spannung ein' leuchtet
42
      writetext(" ", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
43
      u_aus;                //Transistor ein};
44
    }
45
  }
46
  
47
  else if( strcmp( befehl, "
48
  {
49
    ..

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

ok danke es geht jetzt!!!!

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.