ArduinoJson - overflow float na ESP8266

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

ArduinoJson - overflow float na ESP8266

Příspěvek od martinius96 » 05 led 2021, 18:33

Ahoj, našiel by sa tu niekto znalý ku knižnici ArduinoJson?

Vvyužívam knižnicu ArduinoJson vo verzii 6.17.2 (posledný release) z 20. Novembra 2020.
Mám projekt Ethernet / WiFi termostat, ktorý som si sám navrhol.
Mikrokontróler, ktorý funguje ako termostat beží v režime webservera, kde má rôzne HTML stránky, ktoré poskytujú frontend používateľovi a ich súčasťou je aj jednoduchý backend (v jazyku C - Wiring) pre spracovanie dát z HTML formuláru, ktoré slúžia ako riadiace dáta.
Jednou z bežiacich stránok je aj /get_data.json, ktorej výstupom sú JSON data o nastavených riadiacich hodnotách termostatu --> Cieľová teplota, hysteréza a aktuálne nameraná teplota senzorom DS18B20.

Výstup stránky /get_data.json vyzerá napríklad takto:

Kód: Vybrat vše

{
"Hysteresis":0.25,
"Target_Temperature":21.25,
"Actual_Temperature":20.81
}
Tento výstup načítavam mikrokontrolérom, nazvime ho JSON client.
K dispozícii mám Arduino s Ethernet shieldom Wiznet W5100, i modulom W5500. Taktiež ESP8266 (NodeMCU v3 Lolin) a ESP32 (DevKit V1).
Čo sa týka časti clienta, je totožný u všetkých platforiem. Som schopný pripojiť sa na IP adresu, kde beží termostat, prečítať HTTP header, Content-type: application/json a nakoniec aj payload.

Fragment zdrojového kódu pre pripojenie a vyparsovanie dát z načítaného reťazca - rovnaký u všetkých platforiem:

Kód: Vybrat vše

    client.stop();
    if (client.connect(host, httpPort)) {
      String url = F("/get_data.json");
      Serial.println(F("Pripojenie uspesne, nacitavam JSON data"));
      client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: W5100\r\n" + "Connection: close\r\n\r\n");
      while (client.connected()) {
        String line = client.readStringUntil('\n'); //HTTP HEADER
        //Serial.println(line);
        if (line == "\r") {
          break;
        }
      }
      DynamicJsonDocument doc(128);
      String line = client.readString(); //PAYLOAD
      Serial.println(line);
      deserializeJson(doc, line);
      JsonObject obj = doc.as<JsonObject>();
      float hystereza = obj[String("Hysteresis")];
      float cielova_teplota = obj[String("Target_Temperature")];
      float actual_temperature = obj[String("Actual_Temperature")];
      Serial.print(F("Hystereza: "));
      Serial.println(hystereza);
      Serial.print(F("Cielova teplota: "));
      Serial.println(cielova_teplota);
      Serial.print(F("Namerana (aktualna) teplota: "));
      Serial.println(actual_temperature);
Následne načítam odpoveď servera (Response), ktorá je tvorená práve predmetným výstupom.
Následne si urobím cez funkcie knižnice ArduinoJson deserializáciu reťazca a následne si viem na základe kľúča vytiahnuť hodnotu, ktorá mu prislúcha.

Pre lepšie pochopenie UART výstup všetkých platforiem:
  • Platforma vypíše aj načítaný payload z response webservera, viem tak verifikovať, že som načítal celý reťazec z webservera s JSON dátami
Obrázek

Funguje to pri všetkých použitých platformách okrem ESP8266. Všetky hodnoty sú typu float, tie očakávam a premennej s takýmto dátovým typom priradím hodnotu. U ESP8266 je hodnota premenných vždy ovf (overflow). Prekvapuje ma najmä to, že u Arduina i ESP32 to funguje bezproblémovo a dáta získam, je tam nejaký rozdiel pri dátovom type float, alebo treba použiť iný spôsob získania údajov z .json súboru? Napadá niekoho, ako problém vyriešiť?
Celé zdrojové kódy pre všetky platformy pre JSON clienta, ktorý využívam sú dostupné na: https://github.com/martinius96/WiFi-ter ... n/examples
Ďakujem za odpovede

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: ArduinoJson - overflow float na ESP8266

Příspěvek od martinius96 » 06 led 2021, 11:34

Tak nateraz vyriešené.
Použil som makro - ukladá hodnoty ako double()

Kód: Vybrat vše

#define ARDUINOJSON_USE_DOUBLE 1
Dáta sa dajú načítať ako float, double, výpis na UART v poriadku.

Pri použití makra, ktoré má hodnoty ukladať ako float()

Kód: Vybrat vše

#define ARDUINOJSON_USE_DOUBLE 0
Je hodnota v Serial monitore vždy ovf.

Chyba ako taká nie je v ArduinoJson, ale vo výpise hodnoty, teda vo funkcii Serial.print, nemalo to priamu spojitosť s ArduinoJson knižnicou.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 30 hostů