mikrocontroller.net

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


Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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
.......

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
          
           rprintfCRLF();                //Ausgabe...
           rprintf("Befehl: ");
           rprintfStr(befehl);
           rprintfCRLF();
           // naechsten Abschnitt erstellen
           wert = strtok(NULL, trennzeichen);      //hier muss NULL stehen???
           rprintf("Wert: ");
           rprintfStr(wert);
           rprintfCRLF();
           puffer = 0;
         
             f=0;
             for(g=0;g<20;g++)              //string wird gelöscht
           string[g] = 0;



    rprintf("befehl: %d",befehl);
    rprintf("wert: %d",wert);

          }

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

    
/*
    if (befehl == "USET")
    {
     voltage = value * 1000;
     da_load(1, voltage);    //chipselect (CS):  1 = Spannung;  value = Analogwert in Millivolt mV
     _delay_ms(50);
    }    


  switch (befehl)
  {
    case USET:  spannung = wert;
          da_load(1, voltage);    //chipselect (CS):  1 = Spannung;  value = Analogwert in Millivolt mV
          _delay_ms(50);
          break;

    case ISET:  strom = wert;
          da_load(2, current);    //chipselect (CS):  2 = Strom;     value = Analogwert in Millivolt mV
          _delay_ms(50);
          break;
    
    case OUTPUT:   if(wert==OFF)
             {u_aus;}
            if(wert==ON)
            {u_ein;}
            break;
    
    case DISPLAY:  if(wert==OFF)
             {???;}
            if(wert==ON)
            {???;}
            break;

  }
*/
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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_fu...

> 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()

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kompliziert ist es aus Strings einen enum zu machen und den dann in 
einen switch case zu stopfen, anstelle von
  if( strcmp( befehl, "USET" ) == 0 ) {
     // behandle den Befehl USET
  }

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

  else if( strcmp( befehl, "OUTPUT" ) == 0 ) {
     // bahandle den Befehl OUTPUT
  }

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

  else {
    // Fehler, kein bekannter Befehl
  }


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?

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
würde es so machen:

[c]
befehl = GetBefehl();

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Formatierung geht nicht, wieso nicht ???
Gibbed doch nid!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)
struct command {
  char * Name;
  void (*Function)( const char* );
}

void HandleUset( const char* argument )
{
}

void HandleIset( const char* argument )
{
}

void HandleOutput( const char* argument )
{
}

void HandleDisplay( const char* argument )
{
}

struct command commands[] = 
{
  {  "USET",    HandleUset },
  {  "ISET",    HandleIset ),
  {  "OUTPUT",  HandleOutput ),
  {  "DISPLAY", HandleDisplay ),
};

void CallFunction( const char* FunctionName, const char* Argument )
{
  size_t i;
  for( i = 0; i < sizeof( commands ) / sizeof( *commands ); ++i ) {
    if( strcmp( commands[i].Name, FunctionName ) == 0 ) {
      commands[i].Function( Argument );
      return;
    }
  }
}

int main()
{
  .....

  CallFunction( befehl, wert );

  ....

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 :-)

Autor: tip-geber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke,
wer lesen kann ist klar im Vorteil!
befehl = GetBefehl();

switch(befehl)
   {
   case USET:
              break;
   case OUTP:
              break;
   default:
              break;
   }

tschüss ;-)

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
struct Date {
  uint8_t  day;
  uint8_t  month;
  uint16_t year;
};

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

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
struct Person {
  char        firstName[30];
  char        lastName[30];
  struct Date birthDay;
};

Hab ich jetzt eine Person
 struct Person Bob;
und ist die richtig initialisiert, dann hat die natürlich auch 
irgendwann Geburtstag. Will ich den ausgeben:
  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.

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

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

            strcat( befehl, "\0" );
           strcat( wert, "\0" );



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


          }

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


    strvergleich = strcmp(befehl, "USET");
    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!!!!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ohhh ok ich probiers.....

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Entschuldigung!!!!
hier nochmal mit C-Formatierung

hier ist die funktion "remote", die ich bei UART-Interrupt aufrufe.
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

}


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

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry
jetzt geht es,

hatte vergessen die libm.a  hinzuzufügen.

jezt läufts

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ICH HABE LEIDER EIN WEITERES PROBLEM.

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

also mache ich wieder folgendes:
else if  (strcmp(befehl, "OUTPUT") == 0)      //Befehl 3
              {
               
              if (strcmp(wert, "ON") == 0)              
                {rprintf("scharf");
                 led_rt_on;              //LED 'Spannung ein' leuchtet
                 writetext("*", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
                 u_ein;                //Transistor ein
                }
            
              if (strcmp(wert, "OFF") == 0)
                {led_rt_off;            //LED 'Spannung ein' leuchtet
                 writetext(" ", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
                 u_aus;                //Transistor ein};
                }
              }

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem dürfte hier bereits vorliegen:
void remote(void)      //Fernsteuerung über RS-232
{
        string[f] = puffer;
          f = f+1;
          rprintfStr(string);


            if(puffer == 13)               //Wenn puffer = RETURN/ENTER
dann...
          {

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
          rprintfStr(string);
ist ein netter Versuch. Aber dich interessieren eben auch die nicht 
sichtbaren Zeichen
          rprintfStr( "&" );
          rprintfStr( string );
          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.
void remote( void )
{
  if( puffer != '\n' ) {       // bei einem Return beginnt die Auswertung
                               // solange kein Return kommt, werden die Zeichen
                               // einfach nur gesammelt

    string[f] = puffer;
    f++;
    return;
  }

  // Ein Return ist eingetroffen. Damit ist der String vollständig
  string[f] = '\0';         // erst mal einen sauberen C-String daraus machen

  rprintfStr( "&" );        // zu Kontrollzwecken ausgeben
  rprintfStr( string );
  rprintfStr( "&" );


  befehl = strtok(string, " \t");    // dann zerteilen
  wert = strtok(NULL, " \t");

  if     (strcmp(befehl, "USET") == 0)
  {
     ....
  }

  ...
  else if  (strcmp(befehl, "OUTPUT") == 0)
  {
    if (strcmp(wert, "ON") == 0)              
    {
      rprintf("scharf");
      led_rt_on;              //LED 'Spannung ein' leuchtet
      writetext("*", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
      u_ein;                //Transistor ein
    }
            
    if (strcmp(wert, "OFF") == 0)
    {
      led_rt_off;            //LED 'Spannung ein' leuchtet
      writetext(" ", 1, 1, 0, u, 2);    //Spannung-aus-Anzeige im Display
      u_aus;                //Transistor ein};
    }
  }
  
  else if( strcmp( befehl, "
  {
    ..

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke es geht jetzt!!!!

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.