Close

Arduino Json a analyza stringu

Úvodní stránka Fórum Vaše projekty Arduino Arduino Json a analyza stringu

  • Toto téma obsahuje celkem 21 odpovědí. Do diskuze (3 diskutující) se naposledy zapojil uživatel Profilový obrázekbebeno28 a poslední změna proběhla před 3 roky a 4 měsíci.
Aktuálně je na stránce zobrazeno 7 příspěvků - 16. až 22. (celkem z 22)
  • Autor
    Příspěvky
  • #11712
    Zbyšek VodaZbyšek Voda
    Správce

    Ještě bych doplnil Vojtu.

    Funkce client.read() vrátí jeden byte (tedy i znak), který přečte z dat, které klientovi přicházejí. Vy chcete dosáhnout toho, že budete tyto přečtené znaky postupně načítat a někam ukládat.

    K tomu se hodí právě pole – to je vyhrazené místo v paměti, ve kterém je možné se pohybovat pomocí indexu, tedy čísla v hranatých závorkách.

    Definici pole v kódu máte:
    char c[1024];
    říká – v paměti bude pole složené z datového typu char a bude mít 1024 položek.

    Když chcete nastavit hodnotu počátečního znaku pole, provedete to následovně:
    c[0] = 30;
    popřípadě
    c[0] = 'A'; – tímto do pole uložíte znak A (ve skutečnosti jeho číselnou hodnotu v ASCII tabulce

    Pozor, pole v jazyce C jsou indexované od 0, tedy první prvek pole má index 0, druhý 1 a v tomto případě poslední znak má index 1023.

    Pomocí cyklu while tedy budete číst znaky přicházející klientu a ukládat je do pole c. Podmínka client.available() platí, dokud jsou nějaké znaky k přečtení. Po každém průchodu navýšíte počitadlo i o jedna, tedy v dalším průchodu budete zapisovat na následující pozici v poli. Dovolil jsem si rozšířit Vojtův návrh:

    int i = 0;
    
    while (client.available()) {
        c[i] = client.read();
        i++;
    }
    
    c[i] = '\0'
    
    Serial.println(c);
    i = 0;

    Na konec načtených dat jsem ještě přidal znak nula. Tímto jsem z načteného pole znaků vytvořil řetězec, tedy text. Řetězce jsou způsob, jak se dá uložit v kódu text. V jazyku C/C++ jsou uložené jako pole znaků, která jsou ukončená znakem nula. Potom funkce jako Serial.println() ví, kdy přestat s vypisováním (vypisují znak po znaku, dokud nenarazí na 0). Je možné, že i ten JSON parser, který používáte vyžaduje na vstupu validní řetězec a ten musí být ukončený nulou.

    Také by možná bylo dobré do cyklu přidat podmínku, aby došlo k načtení maximálně 1023 znaků – více by se nevešlo do pole (poslední znak je právě 0). Také by bylo rozumné zvětšit velikost pole.

    Napadlo mě, že budete mít ještě asi problém s HTTP hlavičkou. Přijatá data totiž neobsahují pouze JSON, který chcete parsovat, ale také HTTP hlavičku. Ta vypadá třeba takto:

    HTTP/1.x 200 OK
    Transfer-Encoding: chunked
    Date: Sat, 28 Nov 2009 04:36:25 GMT
    Server: LiteSpeed
    Connection: close

    Po hlavičce následují dva znaky zalomení řádku a až poté obsah web stránky – ve vašem případě pravděpodobně právě JSON. S tím se taky budete muset vypořádat :)

    #11715
    Profilový obrázekbebeno28
    Účastník

    Zbysku Dakujem.
    Vcera som sa s tym zaoberal a prisiel som presne na to ako pisete.
    Presne rovnakym sposobol nacitavam retazec. Takze to som uz pochopil.
    Na nete som nasiel jeden projekt kde sa tiez nacitava json tak som si ten kod krok po kroku lustil a snazil sa prist na to co to robi.

    Teraz nie som pri pc kde mam ten kod ale je tam este jedna vec ktorej som neporozumen. Pripadne sa dodatocne opytam ak to nebude robit problem.

    a co sa tika velkosti pola tak toho sa neobavam. ten vystup nema ani 20 znakov vratane hlavicky.
    Skor ma zaujima ci samotny json string mze obsahovat entery . je ich tam pozehnane. Najlepsie by bolo vediet presne ako ta json kniznica pracuje len nie je k tomu popis.

    Ale sna sa mi to podari spojazdnit.

    Teraz nebudem mat par dni moc casu ale ja sa potom ozvem a dam vediet ako som pokrocil.

    Kazdopadne Dakujem za rady a pomoc.

    Pomohlo

    #11716
    Zbyšek VodaZbyšek Voda
    Správce

    Není zač, kdyžtak se ozvěte :)

    K té knihovně je dokumentace zde: https://bblanchon.github.io/ArduinoJson/doc/index.html

    popřípadě kdybyste chtěl zabrousit i do kódu, tak mrkněte sem:
    https://github.com/bblanchon/ArduinoJson/tree/master/src/ArduinoJson
    ale to už je celkem zběsilé.

    #11721
    Profilový obrázekbebeno28
    Účastník

    Ahojte. Ale predsa sa este opytam. Cely den som nad tym rozmyslal a teraz mam troska casu tak skusam.
    V prilohe je foto vystupu z terminalu.
    Samozrejme moze byt ze mi hodi parse faild preto lebo je tam tam hlavicka aj ked si nemyslim pretoze priklad ktory som nasiel vcera , co som tu uz spomynal to mal tiez a v kode sa to neriesilo.

    Ked som pouzil ArduinoJson assistant tak tam mi vyhodilo ze ak ako priklad pouzijem tento rad zankov tak parsing prejde a aj tak bolo. Chybu nedalo.

    const char* json = „{\“TaskName\“:\“Voda\“,\“Temp-voda\“:21.81}“;

    Prosim Vas co znamenaju tie opacne lomitka ?

    A ked to porovnate z vystupem co dostavam, co tam chyba alebo prevysuje ?

    Inak v kode mam zapisane aj to aby pridalo na koniec znak 0 ale dako ho tam v tom vystupe nevidim. Alebo som to zle pochopil?

    Dakujem

    #11725
    Profilový obrázekbebeno28
    Účastník

    Tak pani, podarilo sa . Huraaaa.

    Tak nakoniec bol fakt problem s tou hlavickou.

    Takto som to napisal a ide to

    while (client.available()) {
        c[i] = client.read();
        if (c[i] == '{') {
          pokracuj = 1;
        }
        if (pokracuj == 1) {
          i++;
        }
      }
      client.stop(); //stop client
      pokracuj = 0;
      c[i] = '\0';
      i = 0;
    
      StaticJsonBuffer<1024> json_buf;
      JsonObject &root = json_buf.parseObject(c);
      if (!root.success())
      {
        Serial.println("parseObject() failed");
      }
    
      float Temp = root["Temp-voda"];

    Dakujeeeem. Potom cely projek ked bude hotovy sen dam ako priklad.

    Attachments:
    #11728
    Zbyšek VodaZbyšek Voda
    Správce

    Jsem rád, že se zadařilo :)

    K tomu zápisu:
    const char* json = “{\”TaskName\”:\”Voda\”,\”Temp-voda\”:21.81}”;

    V C/C++ se řetězce zapisují třeba takto:
    char *s = "Ahoj Karle!";

    Kdybyste ale chtěl v rámci řetězce mít znak uvozovek, nemůžete to zapsat takto:
    char *s = "Ahoj "Karle!"";
    kompilátor by totiž měl při analýze problém a v kódy by se nevyznal.

    Musíte mu proto pomoct, a to právě napsáním zpětného lomítka před znak uvozovek. Tomuto se říká escapování a je díky němu možné zpasat znaky, které normálně zapsat nelze – třeba i znak s hodnotou 0 zapíšete \0. Dále jsou to třeba znak tabulátor -\t, nový řádek – \n a další – viz https://en.wikipedia.org/wiki/Escape_sequences_in_C.

    #11729
    Profilový obrázekbebeno28
    Účastník

    Aha. Tak uz to chapem. Super vysvetlene. Dakujem

Aktuálně je na stránce zobrazeno 7 příspěvků - 16. až 22. (celkem z 22)
  • Pro reakci na toto téma se musíte přihlásit.