PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ausgabe von absoluten Float-Werten aud Display



VolkerB
26.02.2018, 18:36
Hallo an die NodeMCU-Spezialisten,

Ich brauche mal Hilfe.
Beschäftige mich seit einiger Zeit mit dem Arduino Pro Mini und habe dort einen Datenlogger für Temperaturen realisiert.

Jetzt hat mich die Lust gepackt das Gleiche mal auf der NodeMCU zum Laufen zu bringen.
Das funktioniert auch schon weitestgehend, aber eben noch nicht komplett.

Etwas überraschend war für mich das die Ausgabe der Temperaturwerte auf dem OLED anders erfolgt als mit dem Pro Mini.
Ich hänge hier mal einen Codeteil an, um das genauer zu beschreiben:

33308

Der Codeteil hat jetzt nicht direkt mit dem Logger zu tun, nur Testcode.
Grün sind die Ausgaben wie sie auf dem OLED erscheinen.
Die vordere Spalte bei der NodeMCU und im Gegensatz die hintere Spalte (nur die Werte in Zeile 32 u. 33) bei dem Pro Mini.
Für mich sind die Werte bei der NodeMCU nicht plausibel.

Hat jemand eine Idee warum die so falsch dargestellt werden.

Gruß Volker

HaWe
26.02.2018, 21:26
hallo,
vorweg: ich weiß es nicht, vermute aber einen Bug.

Bekannter Hintergrund:
Oftmals verwenden die esp8266 libs für mathematische Funktionen nicht die Arduino-Libs (die oftmals auch nicht C/++ math.h kompatibel sind), sondern stattdessen std C++ Definitionen.
Arduino hingegen verwendet êigene (verunstaltende) Makros, was vielen Nutzern (zu Recht) widerstrebt. Dies gilt u.a. auch für min, max, ceil, floor und round.
Dieser Teil bis hier hin erklärt zumindest, warum Nano und esp sich unterschiedlich verhalten.

esp8266 sollte daher eigentlich std::abs() aus <cmath> verwenden, welches an sich eine "overoloaded" Funktion ist (bzw. ein template), und daher "sollte" eigentlich ein float als Argument auch wieder ein float zurück geben, während ein int wieder ein int zurückgibt. Scheint aber nicht zu funktionieren.

Wäre die esp-abs()-Funktion allerdings die ANSI-C-Funktion abs(), so würde sie IMMER ein int zurückgeben ( da diese ausschließlich in <stdlib.h> und hier ausschließlich auf int definiert ist): das könnte hier teilweise (bei < 0) der Fall sein, dürfte aber bei > 0 nicht anders passieren.

Daher meine Vermutung, es könnte ein Bug sein.

Workaround:

definiere deine eigene abs-"Funktion" als _abs()

#define _abs(x) x>=0?x:-x // eigentlich ein "verpöntes" Makro

Außerdem könntest du auch mal die alternative funktion fabs() verwenden, die auf float definiert ist.

Und melde dochmal diesen Fehler im esp-github-repo an - mal gucken, was die Spezialisten sagen!
https://github.com/esp8266/Arduino/issues

VolkerB
27.02.2018, 08:46
Guten Morgen HaWe,

Danke für deine hilfreiche Stellungnahme.
Ich habe es mit fabs() probiert, funktioniert super.

Trotzdem noch eine Frage an dich: Wo genau kann man denn die erlaubten Befehle für die NodeMCU nachsehen?
Für Arduino schaue ich immer auf Arduino.cc, dort ist alles umfassend dokumentiert.
Gibt es sowas auch für die NodeMCU?
Ich wäre jetzt ohne dich garnicht auf die Idee gekommen das es den fabs()-Befehl überhaupt gibt.

Man kann ja auch nicht immer davon ausgehen das ein Neueinsteiger umfassend mit C oder C++ vertraut ist.

Ich selbst komme aus der Industrie-Automatisierung und habe mit Prozeß-Leitsystemen zu tun gehabt. Da sind eher proprietäre Systeme im Einsatz.
Ansonsten kenne ich von früher noch Basic und Turbo-Pascal.

Im Ruhestand macht es mir aber Spaß noch was Neues dazu zu lernen.

Gruß Volker

HaWe
27.02.2018, 09:32
Ich habe es mit fabs() probiert, funktioniert super.
...
Trotzdem noch eine Frage an dich: Wo genau kann man denn die erlaubten Befehle für die NodeMCU nachsehen?
Für Arduino schaue ich immer auf Arduino.cc, dort ist alles umfassend dokumentiert.
Gibt es sowas auch für die NodeMCU?
Ich wäre jetzt ohne dich garnicht auf die Idee gekommen das es den fabs()-Befehl überhaupt gibt.

Man kann ja auch nicht immer davon ausgehen das ein Neueinsteiger umfassend mit C oder C++ vertraut ist.


moin!
stimmt, ist sehr verwirrend mit den nodeMCU-Sonderfällen. Ich kenne auch keine spezielle Referenz, die nodeMCU-devs kochen da ganz im Stillen ihr eigenes Süppchen. Immerhin sind immer für alle Arduino API Libs C++(11) (und sicher auch C99) die Basis, auch für die "spezielleren".

Aber auch wenn der nodeMCU IMO nichts für Anfänger ist, finde ich es doch extrem verwirrend, dass die sich nicht 100% an Arduino-Standards halten, auch wenn vieles bei Arduino ziemlich schwachsinnig gelöst ist. Immerhin fangen sie bei Arduino aber langsam an, #define-Makros durch Templates zu ersetzen...
Arduino wird sich auch höchstens extrem langsam bewegen, um blödsinnige Uralt-Standards zu ändern, aus Rückwärts-Kompatibilitäts-Gründen, und ich denke, das stört die nodeMCU devs auch gewaltig.

Ich selber kenne mich in C auch deutlich besser aus als in C++ (tbh, ich HASSE OOP! ;) ), von daher war mir das mit abs() für int und fabs() für float dunkel erinnerlich - ein Blick in die C99-Sprachdefinitionen für abs() hat das auch schnell bestätigt.


abs
int abs (int n);

Absolute value
Returns the absolute value of parameter n ( /n/ ).

In C++, this function is also overloaded in header <cmath> for floating-point types (see cmath abs), in header <complex> for complex numbers (see complex abs), and in header <valarray> for valarrays (see valarray abs).

In C, only the int version exists.
For the long int equivalent see labs.
For the long long int equivalent see llabs.

See also
labs
Absolute value (function )
fabs
Compute absolute value (function )


Was also den Sprachumfang angeht, würde ich mich bei nodeMCU auf gängige C++(11) Standards verlassen, teilweise C99 als Untermenge (siehe fabs), und das tue ich - mit wechselndem Erfolg - auch bei "normalen" Arduinos:
http://www.cplusplus.com/reference/
http://www.cplusplus.com/reference/clibrary/
http://www.cplusplus.com/reference/cstdlib/abs/?kw=abs

Und wenn was nicht nach den Standards funktioniert: an die devs melden, entweder Arduino-github oder esp8266-github, je nachdem.
Von daher empfehle ich dir dringend, deinen Fehler (vermutlich ist es ja einer!) über die github-esp8266-issues zu melden, denn so etwas wie bei dir darf eigentlich nicht passieren!
https://github.com/esp8266/Arduino/issues