Hi zusammen,
kurz & knapp:
Sketch:
#include <ArduinoJson.h>
void setup() {
Serial.begin(115200);
delay(2000);
float test_1 = 0.28;
float test_2 = 3.43;
StaticJsonDocument<96> test_arr;
test_arr[0]["test_1"] = test_1;
test_arr[0]["test_2"] = test_2;
String jsonString;
serializeJson(test_arr, jsonString);
Serial.println(jsonString);
}
void loop() {
}
Ausgabe am Serial Monitor:
[{"test_1":0.280000001,"test_2":3.430000067}]
Ich hab weder getrunken, noch stand ich zu lange in der Sonne.
Warum macht es das?
Wo kommen die ganzen zusÀtzlichen Nullen her.
Hilfe!
Das hier dagegen funktioniert:
#include <ArduinoJson.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(2000);
StaticJsonDocument<96> test_arr;
test_arr[0]["test_1"] = 0.28;
test_arr[0]["test_2"] = 3.43;
String jsonString;
serializeJson(test_arr, jsonString);
Serial.println(jsonString);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ich bin verwirrt ... wieder mal
Und nochmal ein Nachschlag:
Das hier funktioniert auch, kommt mir aber extrem dÀmlich vor:
#include <ArduinoJson.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(2000);
float test_1 = 0.28;
float test_2 = 3.43;
StaticJsonDocument<96> test_arr;
test_arr[0]["test_1"] = ((int)(test_1 * 100))/100.0;
test_arr[0]["test_2"] = ((int)(test_2 * 100))/100.0;
String jsonString;
serializeJson(test_arr, jsonString);
Serial.println(jsonString);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ausgabe:
[{"test_1":0.28,"test_2":3.43}]
Ich verstehs wieder mal echt nicht.
Auf einen originalen ARDUINO UNO kompiliert und ĂŒbertragen:
Der Sketch verwendet 6908 Bytes (21%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 252 Bytes (12%) des dynamischen Speichers, 1796 Bytes fĂŒr lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
/home/user1/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude -C/home/user1/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino_build_559971/sketch_aug23e.ino.hex:i
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/home/user1/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
User configuration file is "/home/user1/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : /dev/ttyACM0
Using Programmer : arduino
Overriding Baud Rate : 115200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : Arduino
Description : Arduino
Hardware Version: 3
Firmware Version: 4.4
Vtarget : 0.3 V
Varef : 0.3 V
Oscillator : 28.800 kHz
SCK period : 3.3 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "/tmp/arduino_build_559971/sketch_aug23e.ino.hex"
avrdude: writing flash (6908 bytes):
Writing | ################################################## | 100% 1.24s
avrdude: 6908 bytes of flash written
avrdude: verifying flash memory against /tmp/arduino_build_559971/sketch_aug23e.ino.hex:
avrdude: load data flash data from input file /tmp/arduino_build_559971/sketch_aug23e.ino.hex:
avrdude: input file /tmp/arduino_build_559971/sketch_aug23e.ino.hex contains 6908 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.98s
avrdude: verifying ...
avrdude: 6908 bytes of flash verified
avrdude done. Thank you.
Ausgabe:
20:59:43.092 -> [{"test_1":0.28,"test_2":3.43}]
der Sketch aus #1 ? Echt jetzt?
Ich verwende einen ESP32 von AZDelivery, die machen eigentlich schon gute QualitÀt.
Ist ja echt skurril. Dann test ich das auch mal auf einem anderen ESP oder einem Arduino.
Ja. Darum habe ich das Protokoll mitgeliefert.
Hat das dann was damit zu tun, dass der ESP32 besser mit Integers kann?
Muss gleich auch mal auf einem ESP8266 testen.
TatsÀchlich:
Auf dem Arduino Nano funktionierts, auf dem ESP8266 und dem ESP32 kommen die Kommastellen dazu. Was soll das
Hab ne Lösung gefunden:
Wenn ich die floats in double Ànder, funktionierts auch mit den ESPs
Ich ahne was....
Mach mal:
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
Serial.println(F("VariablengröĂe in Byte"));
Serial.print(F("float: "));
Serial.println(sizeof(float));
Serial.print(F("double: "));
Serial.println(sizeof(double));
}
void loop()
{}
Start...
VariablengröĂe in Byte
float: 4
double: 8
Hab auch grad auf der ArduinoJson.org Seite gesehen, dass da double anscheinend die bessere Wahl ist.
Aaaaber: Der Spuk geht weiter
#include <ArduinoJson.h>
uint32_t wert_eins=3;
uint32_t wert_zwei=100;
uint32_t wert_drei=10300;
uint32_t wert_vier=9178;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(2000);
double wert_fuenf = wert_eins * (wert_zwei/10000.0) * (wert_drei/10000.0) * (wert_vier/10000.0);
Serial.println("wert_fuenf ist hier:");Serial.println(wert_fuenf);
StaticJsonDocument<96> test_arr;
test_arr[0]["wert_fuenf"] = wert_fuenf;
String jsonString;
serializeJson(test_arr, jsonString);
Serial.println("Und hier:");
Serial.println(jsonString);
}
void loop() {
// put your main code here, to run repeatedly:
}
Ausgabe am Serial-Monitor:
wert_fuenf ist hier:
0.03
Und hier:
[{"wert_fuenf":0.02836002}]
Wie krieg ich das jetzt wieder im JSON-Array gerundet auf 2 Nachkommastellen?
Was mich auch irritiert:
Wenn ich am Taschenrechner eintipp:
3 * 0,01 * 10,3 * 0,9178 bekomm ich als Ergebnis genau diese Zahl 0,2836002
D.h. hier hat der JSON-Array Recht und ich frag mich, warum der Serial-Monitor hier die gerundete Version ausgibt.
combie
August 23, 2022, 8:03pm
14
Und was ist, wenn du statt float double verwendest?
Hier schau dir mal Pi an:
Ich hatte ja zuerst float.
Aber da hatte ich ja dann das Problem, dass die Zahlen im JSON-Array zu viele Nachkommastellen hatten (siehe #1 ).
Auf der ArduinoJSON.org-Seite fand ich dann dass (Auszug aus dem Troubleshooter):
fony
August 23, 2022, 8:06pm
16
Standard fĂŒr SerMon sind zwei Nachkomma stellen
fony
August 23, 2022, 8:12pm
18
Neue Variablere anlegen runden weg ist der Spuck
22:14:06.916 -> wert_fuenf ist hier:
22:14:06.916 -> 0.0283600187
22:14:06.916 -> Und hier:
22:14:06.916 -> [{"wert_fuenf":0.02836}]
Serial.println("wert_fuenf ist hier:");Serial.println(wert_fuenf,10);
OK.... bei mir warens zwei Nachkommastellen. Evtl. kann man das ja einstellen oder das Verhalten ist beim ESP32 wieder anders wie beim Arduino?
Was mich aber immer noch verwirrt und vorhin bissl aus der Bahn geworfen hat:
float test_1 = 0.28 wird im JSON-Array als "0.2800001" angezeigt, jedoch
double test_1=0.28 korrekt als "0.28" --> Warum? Egal. Jetzt weiĂ ichs ja
Ah - grad erst gelesen.
Da war ich zu schnell