Co místo String? 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
NCPlyn
Příspěvky: 7
Registrován: 03 led 2019, 19:33
Reputation: 0

Co místo String? ESP8266

Příspěvek od NCPlyn » 19 srp 2019, 21:18

Ahoj, mám program na NodeMCU ESP8266, který každou minutu přečte z spiffs až 750 bajtů a dá je do stringu.

Kód: Vybrat vše

File file = SPIFFS.open("/times.txt", "r");
  while (file.available()) {
    String line = file.readStringUntil('n');
    Serial.print(line);
    if(line.indexOf(nowtime) >= 0) {
      file.close();
      digitalWrite(5, LOW);
      delay(60000);
      digitalWrite(5, HIGH);
    } else {
      file.close();
    }
  }
Jelikož jsem někde zaslechl, že String není dobrá volba pro používání, protože zabírá vždy novou část paměti a místo přepsání. Chtěl bych teda na toto použít něco jiného... kam se to vejde, nemusím určovat specifickou velikost protože se může obsah měnit a můžu v tom najít jiný string (line.indexOf(nowtime)).

Nevím jestli něco takového by se dalo udělat, napadl mě char nebo EEPROM, ale ani s jedním nemám nějaké dobré zkušenosti.

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Co místo String? ESP8266

Příspěvek od pavel1tu » 20 srp 2019, 06:13

1) EEPROM - pokud si v manuálu přečteš, kolikrát jde přepsat - jistě pochopíš, že častým přepisováním ji odepíšeš
2) CHAR - ukládá jen jeden znak, musel by jsi použít pole znaků CHAR[] - pokud použiješ třeba CHAR[10] pro 10 znaků, asi na tom vyděláš při vícenásobném použití proti STRINGu.
3) STRING - způsob použití, místo kde jej deklaruješ se mi zdá nevýhodné, pokud ti mizí paměť, může to být tím, že "String line" znovu a znovu deklaruješ za běhu programu. Nevím jak to pak funguje doopravdy, ale já bych tu deklaraci dal na začátek kam patří.

Ale z C++ vím, že STRING obsadí jen 256 bajtů, pokud do něj pošleš delší text, nepřeteče, nic se nestane. CPU za tebe spravuje paměť.
Pokud použiješ CHAR[] neboli pole znaků, při poslání delšího textu než je deklarace pole, data přetečou do dalších paměťových buněk, způsobí t neplechu - v poli jsi zodpovědný za svá data sám.

Je to popsáno již v základních příručkách, ale nevím co platí u CPU ATmega a dalších.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Co místo String? ESP8266

Příspěvek od pavel1tu » 20 srp 2019, 09:11

Já dost věcí čerpám z těchto stránek, i když moc neumím anglicky.

lekce String/char
https://www.tweaking4all.com/hardware/a ... ng-part-7/

Ještě doplním ...
Problém je v tom, že operace String přidělují paměť dynamicky a způsobem, který je těžké předvídat, když jsou vstupy do programu proměnné, v kombinaci se skutečností, že Arduinos mají velmi omezené množství paměti RAM (2 kB na Arduino Uno). Dynamické přidělování paměti obvykle způsobuje fragmentaci paměti. To znamená, že váš program může pracovat správně pro některé vstupy nebo na krátkou dobu, ale dojde k selhání s jinými vstupy nebo po delší době v důsledku vyčerpání paměti.
Pokud tedy ukládáš do String různě dlouhé "data", ATMega si musí tyto nové pole uložit v paměti na jiné místo a paměť se mu začíná "fragmentovat".
Já o tom někde četl (a opustil jsem pro daný projekt klasické ATMega CPU)
https://critical.eschertech.com/2010/07 ... d-systems/

Já začal používat pole, ale stejně jsem dojel na množství paměti + nebezpečí "přetečení", které za tebe CPU ani kompilátor asi nehlídá.
Máš char[100] - pole 100 znaků a na pozici char[95] uložíš text "Nove data z mereni" - je jasné, že už "data z mereni" přetečou v paměti někam neznámo kam. Osobně to nemohu prokázat, nevím jestli mi ATMega dojela na nedostatek paměti nebo tím přetečením - vždy se kousla.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

KarelBrno
Příspěvky: 40
Registrován: 05 kvě 2019, 15:12
Reputation: 0

Re: Co místo String? ESP8266

Příspěvek od KarelBrno » 20 srp 2019, 09:27

NCPlyn:
Tak jak máš ten program napsaný, tak to skutečně bude žrát zbytečně moc paměti - s každým novým řádkem v souboru se alokuje v paměti další nová instance Stringu + k ní paměť se samotným textovým řetězcem, takže při dostatečném množství řádků může paměť dojít. Deklaruj ten String ještě před cyklem, tak bude paměť zabírat jen jeden String + text aktuálního řádku.

Jinak obecně se Stringy je problém hlavně na Arduinech, ty mají jen 2kB RAM a když si to člověk nehlídá, tak může dojít hodně rychle. ESP8266 má řádově více RAM (desítky kB), takže tam to tak horké není.

Kdyžtak v tvém případě, pokud skutečně čteš vždy max. 750 bajtů, tak místo stringu možná můžeš použít char[751] (ten jeden znak navíc tam asi bude potřeba pro ukončovací znak 0).

Odpovědět

Kdo je online

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