Forum: Mikrocontroller und Digitale Elektronik itoa in sprintf


von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Hallo @all,

Ich komme mal wieder nicht weiter :(

Ich möchte gerne in Radigs Net IO "http.c" das Ausgabeformat "itoa" in 
"sprintf" ändern, da ich bei einem Sensor Probleme mit dem Ausgabewert 
habe, d.h. der Wert wird mir komplett falsch ausgegeben und nach langem 
suchen und probieren bin ich darauf gekommen, dass die Funktion "itoa" 
mir einen Strich durch mein Vorhaben macht.

Die betreffende Stelle wäre diese:


--------------schnipp-------------


      if (strncasecmp_P("VA@",http_entry[index].new_page_pointer,3)==0)
      {
        b = (pgm_read_byte(http_entry[index].new_page_pointer+3)-48)*10;
        b +=(pgm_read_byte(http_entry[index].new_page_pointer+4)-48);
        itoa (var_array(b),var_conversion_buffer,10);
        str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
        memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
        a = a + (str_len-1);


--------------schnipp-------------



Wer würde mir dabei kurz helfen?

Danke im Vorraus

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:

> suchen und probieren bin ich darauf gekommen, dass die Funktion "itoa"
> mir einen Strich durch mein Vorhaben macht.

Wenn dir itoa hier einen Strich durch die Rechnung macht, dann ist 
irgendwas anderes faul. Da hilft dir auch sprintf nicht weiter. Ganz im 
Gegenteil, da sprintf wesentlich mehr Resourcen braucht, ist die Chance 
sogar höher, das alles nur noch schlimmer wird.

IM Prinzip ist das einfach
1
  b = (pgm_read_byte(http_entry[index].new_page_pointer+3)-48)*10;
2
  b +=(pgm_read_byte(http_entry[index].new_page_pointer+4)-48);
3
4
  sprintf( conversion_buffer, "%d", (int)var_array(b) );
5
6
  str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);

aber wie gesagt: es wird dein Problem nicht lösen. Was du siehst sind 
nur die Symptome, die dich zu itoa führen. Das eigentliche Problem sitzt 
ganz woanders.

Was hast du denn sonst noch in den Sourcen geändert?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

> Sensor Probleme mit dem Ausgabewert habe, d.h. der Wert wird mir komplett falsch 
ausgegeben

Kannst du das näher spezifizieren?

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Hi Karl Heinz,

danke erstmal.....

ich habe ein Atmega Testboard mit nem Atmega328p drauf. Ich habe echt 
eeewig gebraucht, bis ich darauf kam. Auf dem Testboard habe ich das 
gleiche Sensorprogramm laufen wie auf dem Net IO. Dort gibt es exakt das 
gleiche Problem mit der Ausgabe. Der Wert ist/war komplett daneben und 
zwar wird/wurde mir exakt der gleiche falsche Wert wie auf dem Net IO 
angezeigt. Dann itoa zu sprintf geändert und der Wert passte.

Ich betreibe das Net IO mit einem LCD. Für die LCD-Ausgabe benutze ich 
sprintf und der richtige Wert wird mir so angezeigt. Nur die 
Html-Ausgabe funktioniert auf dem itoa-Prinzip und da habe ich totale 
Probleme mit der Änderung.

Ich bin guter Hoffnung, dass das mit sprintf funzt.


Ich habe es jetzt mal so geändert.....


----------------schnipp---------------

    //Müssen Variablen ins Packet eingesetzt werden? ===> %VA@00 bis 
%VA@19
    if (b == '%')
    {
      if (strncasecmp_P("VA@",http_entry[index].new_page_pointer,3)==0)
      {
        b = (pgm_read_byte(http_entry[index].new_page_pointer+3)-48)*10;
        b +=(pgm_read_byte(http_entry[index].new_page_pointer+4)-48);
//        itoa (var_array(b),var_conversion_buffer,10);


                sprintf( conversion_buffer, "%d", (int)var_array(b) );


        str_len = strnlen(var_conversion_buffer,CONVERSION_BUFFER_LEN);
        memmove(&eth_buffer[TCP_DATA_START+a],var_conversion_buffer,str_len);
        a = a + (str_len-1);
        http_entry[index].new_page_pointer=http_entry[index].new_page_pointer+5;
      }
----------------schnapp---------------



Allerdings erhalte ich jetzt folgende Errors:

httpd.c:697: error: 'conversion_buffer' undeclared (first use in this 
function)
httpd.c:697: error: (Each undeclared identifier is reported only once
httpd.c:697: error: for each function it appears in.)
make.exe: *** [httpd.o] Error 1


Ähhm, zu Deiner Frage...Ich habe paar Sachen geändert, z.B. noch einen 
SHT75 eingefügt sowie einiges an der Optik in der HTML-Ausgabe.

Das, was ich mittlererweile zu 100% sagen kann ist, dass der Sensor mit 
itoa total daneben liegende Werte ausspuckt und mit sprintf richtige.

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Ich habe Anfang des Monats schonmal einen Beitrag hier gestartet:

Beitrag "GY-65/BMP085 zeigt falschen Druck"

Und seitdem habe ich nach diesem Fehler gesucht.....

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:

> Allerdings erhalte ich jetzt folgende Errors:
>
> httpd.c:697: error: 'conversion_buffer' undeclared (first use in this
> function)

und das mit recht
Wenn man sich das Original mal genauer ansieht, dann heisst die Variable
var_conversion_buffer

Genau aus dem Grund hasse ich Ullrichs Geschreibsel, alles ist so dich 
an dicht gepackt, da muss man überall 3 mal schauen, ehe man erst mal 
nur die einzelnen Wörter findet :-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

strncasecmp_P brauch doch einen Zeiger zu einem String im Flash, was 
"VA@" nicht ist?

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Ich habe Anfang des Monats schonmal einen Beitrag hier gestartet:
>
> Beitrag "GY-65/BMP085 zeigt falschen Druck"
>
> Und seitdem habe ich nach diesem Fehler gesucht.....


Na ja gut. Das hat aber einen anderen Grund

int32_t pressure = 0;

dafür ist ein itoa nun mal die falsche Funktion.

i  wie int
l  wie long

für einen uint32_t wäre ein Aufruf von ultoa die passende Funktion. Das 
du da mit sprintf über die Runden gekommen bist, war Zufall, weil am 
Stack zufällig die richtigen Bytes lagen, bzw. man kann aus dem dort 
angegebenen Codeaussschnitten nicht das richtige Erkennen, weil die 
lcd_print fehlt


Es ist recht unwahrscheinlich, dass es einen Wert gibt, für den itoa das 
falsche ausgibt. Dazu ist die Funktion zu trivial.
Viel wahrscheinlicher ist es, dass irgendwo in den Datentypen geschlampt 
wurde.

von Karl H. (kbuchegg)


Lesenswert?

Johann L. schrieb:
> strncasecmp_P brauch doch einen Zeiger zu einem String im Flash, was
> "VA@" nicht ist?

Das _P ist die Kennung dafür, dass das ein Makro ist, welches 
seinerseits wieder ein PSTR auf das erste Argument einfügt.
Keine ahnung ob das heute noch gebräuchlich ist. Ich habs das erste mal 
bei P.Fleury gesehen.

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Ups, das habe ich auch übersehen.

Compilieren gings jetz. Ich werde es in den nächsten 60 Minuten mal 
einspielen.

Ich danke Dir erstmal für Deine Hilfe.

Ich hoffe, dass es jetz funktioniert.

Gruss

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Viel wahrscheinlicher ist es, dass irgendwo in den Datentypen geschlampt
> wurde.

Das, zusammen mit dem anderen Link bringt mich auf eine Vermutung.

Du hast nicht rein zufällig das Array var_array von int auf long 
hochgehoben?

: Bearbeitet durch User
von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> für einen uint32_t wäre ein Aufruf von ultoa die passende Funktion. Das
> du da mit sprintf über die Runden gekommen bist, war Zufall, weil am

Ich ärgere mich immer wieder, dass ich kein Programmierer geworden 
bin....

Das hätte mir eeeeiniges an Zeit bei der Fehlersuche erspart.

Ich habe mal utoa ausprobiert, aber ich glaube mich zu erinnern, dass es 
da garnichts anzeigte. Aber das war halt kein ultoa :)

Ich werde heute nochmal ein paar Sachen ausprobieren. Mein Programmer 
ist nur leider grade bei meinem Vermieter, der sich zwar mit Bascom 
auskennt, aber mit C nicht. Sobald ich den Programmer wieder habe, teste 
ichs mal.

Ich danke Euch erstmal für die super und hoffentlich erfolgreichen 
Tipps.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Johann L. schrieb:
>> strncasecmp_P brauch doch einen Zeiger zu einem String im Flash, was
>> "VA@" nicht ist?
>
> Das _P ist die Kennung dafür, dass das ein Makro ist, welches
> seinerseits wieder ein PSTR auf das erste Argument einfügt.
> Keine ahnung ob das heute noch gebräuchlich ist. Ich habs das erste mal
> bei P.Fleury gesehen.

Halt.
Kommando retour.
Stimmt nicht. Ist kein Makro.

Gute Frage. Warum geht das überhaupt?

Ah, hier
1
int   strncasecmp_P (const char *, PGM_P, size_t) __ATTR_PURE__
der erste Pointer ist wohl kein Pointer ins Flash.

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Karl Heinz schrieb:
>> für einen uint32_t wäre ein Aufruf von ultoa die passende Funktion. Das
>> du da mit sprintf über die Runden gekommen bist, war Zufall, weil am
>
> Ich ärgere mich immer wieder, dass ich kein Programmierer geworden
> bin....
>
> Das hätte mir eeeeiniges an Zeit bei der Fehlersuche erspart.
>
> Ich habe mal utoa ausprobiert, aber ich glaube mich zu erinnern, dass es
> da garnichts anzeigte. Aber das war halt kein ultoa :)

Der springende Punkt ist: das muss zusammenpassen!
Du musst da sehr aufpassen, dass du die richtige Funktion abhängig vom 
Datentyp nimmst.

Ich denke immer noch, dass das Problem was anderes ist.

Hast du im HTML Code aufgepasst, dass da die Variabelen-Nummer 2-stellig 
stehen muss? Das ist mir nämlich beim Spielen mit dem Radig-Web Server 
passiert. Da muss zb @VA06 stehen. Der Code will genau 2 Zeichen haben, 
um die Variablennummer zu bestimmen.
Das sind die beiden Anweisungen hier
1
  b = (pgm_read_byte(http_entry[index].new_page_pointer+3)-48)*10;
2
  b +=(pgm_read_byte(http_entry[index].new_page_pointer+4)-48);

b hat dann den Wert 6 (und natürlich gibt es im Code auch keine 
Absicherung gegen Fehler :-)

: Bearbeitet durch User
von Stefan B. (sibbl) Benutzerseite


Angehängte Dateien:

Lesenswert?

Karl Heinz schrieb:
> Hast du im HTML Code aufgepasst, dass da die Variabelen-Nummer 2-stellig
> stehen muss? Das ist mir nämlich beim Spielen mit dem Radig-Web Server
> passiert. Da muss zb @VA06 stehen. Der Code will genau 2 Zeichen haben,
> um die Variablennummer zu bestimmen.

Jupp, da habe ich drauf geachtet:

----------schnipp-------------

  "<tr><td>BMP085</td><td>Luftdruck</td><td 
align=\"right\">%VA@33</td><td align=\"left\">Pa</td><td>  </td><td> 
</td></tr>\r\n"
  "<tr><td>BMP085</td><td>Hoehe</td><td align=\"right\">%OW@34</td><td 
align=\"left\">m</td><td>  </td><td>  </td></tr>\r\n"

----------schnapp-------------

also das mit VA und OW ist noch Testerei, die müssen letztendlich OW 
sein.

Ich habe das jetzt mit sprintf getestet. Der Wert ist immernoch falsch 
:((

siehe Fotos....

Im blauen LCD ist P so, wie der Druck momentan ist und das ist 
akzeptabel und auf dem zweiten Bild ist die HTML-Ausgabe und da ist P 
total daneben.
Es ist echt fürchterlich, dass die beiden Ausgaben total unabhängig 
fungieren.

von holger (Gast)


Lesenswert?

>und da ist P total daneben.

Und entspricht durch reinen Zufall deiner maximalen Helligkeit.
Ich glaube nicht an Zufälle;)

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

holger schrieb:
>>und da ist P total daneben.
>
> Und entspricht durch reinen Zufall deiner maximalen Helligkeit.
> Ich glaube nicht an Zufälle;)

:)

In der maximalen Helligkeit ist die Variable des Druckes drin, man kann 
auch sagen, die maximale Helligkeit ist falsch deklariert.....

Ich habs vorhin gesehen, da war der Post aber leider schon gesendet....

von holger (Gast)


Lesenswert?

unsigned int var_array[]

Werte in var_array können nicht grösser 65535 werden.

Nimmt man mal deine 94832 und schneidet bei 16 Bit ab
kommen 29296 raus. Da ist dein Problem.

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Ich hab das jetzt mal auf:

uint32_t var_array[]

geändert.

Immernoch der falsche Wert :(

von holger (Gast)


Lesenswert?

sprintf( var_conversion_buffer, "%ld", var_array(b) );

Die runden Klammern bei var_array in eckige ändern.
Die Forensoftware meint das ich sonst S P A M sende;)

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

holger schrieb:
> sprintf( var_conversion_buffer, "%ld", var_array(b) );
>
> Die runden Klammern bei var_array in eckige ändern.
> Die Forensoftware meint das ich sonst S P A M sende;)

Yeees, i have it :)

Ich habs jetz auf "unsigned long int var_array(MAX_VAR_ARRAY)" geändert 
und dazu "ultoa (var_array(b),var_conversion_buffer,10);" benutzt.

Das mit den eckigen Klammern hatte ich auch, deswegen sind bei mir auch 
runde....

Spitzenmäßig.....an dem Fehler suche ich echt schon 3 Wochen.... :(

Ich danke Euch vielmals.....

von Stefan B. (sibbl) Benutzerseite


Angehängte Dateien:

Lesenswert?

Und geht :)

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.