Sériové řazení proměnných

Cmrnda
Příspěvky: 31
Registrován: 25 dub 2024, 17:58

Sériové řazení proměnných

Příspěvek od Cmrnda » 24 lis 2024, 22:40

Dobrej,
po optimalizaci kódu pro rychlost se mi stává že ESP32 se samovolně restartuje, stačí zadat "Delay(1)" a už je vše OK. Jenže použití zastavení programu koresponduje negativně s onou optimalizací pro rychlost. Je to vysvětlitelný protože smyčka proběhne v kratší čas, tak asi nějaká knihovna tomu brání.

Otázka:
má seriové řazení vliv na rychlost procedůr? Nezáleží na kapacitě RAM, ale na rychlosti vyhledání/uložení.

Příklad sériové zdrženlivosti:

Kód: Vybrat vše

  
   Soucasny_Cas_4 = millis();
  if (Soucasny_Cas_4 - Minuly_Cas_4 >= Doba_resetu_ctvrtecni) 
  {
    Minuly_Cas_4 = Soucasny_Cas;
    // Akce I.
    Soucasny_Cas_2 = millis();
    if (Soucasny_Cas_2 - Minuly_Cas_2 >= Doba_resetu_polovicni) 
    {
      Minuly_Cas_2 = Soucasny_Cas_2;
      // Akce II.
      Soucasny_Cas_2 = millis();
      if (Soucasny_Cas - Minuly_Cas >= Doba_resetu_zakladni) 
      {
        Minuly_Cas = Soucasny_Cas;
        // Akce III.
      } 
    } 
  }
   
No, paralelní myslím to napsat pod sebe.

Kód: Vybrat vše

  Soucasny_Cas_4 = millis();
  if (Soucasny_Cas_4 - Minuly_Cas_4 >= Doba_resetu_ctvrtecni) 
  {
    Minuly_Cas_4 = Soucasny_Cas_4;
    // Akce I.
  }

  Soucasny_Cas_2 = millis();
  if (Soucasny_Cas_2 - Minuly_Cas_2 >= Doba_resetu_polovicni) 
  {
    Minuly_Cas_2 = Soucasny_Cas_2;
    // Akce II.
  } 

  Soucasny_Cas = millis();
  if (Soucasny_Cas - Minuly_Cas >= Doba_resetu_zakladni) 
  {
    Minuly_Cas = Soucasny_Cas;
    // Akce III.
  }
   

Logicky vzato, sériové musí být časově úspornější, ale je tomu opravdu tak?
Nemůžu se doměrit.

Uživatelský avatar
Caster
Příspěvky: 434
Registrován: 11 zář 2019, 09:02

Re: Sériové řazení proměnných

Příspěvek od Caster » 25 lis 2024, 09:32

Bez důkladnějšího zkoumání mě napadá, zda nemůže přetéct nějaká optimalizovaná proměnná pro měření času. V programu bych ji definoval natvrdo se správným a dostatečný velkým typem např. 8 bytů.

Další zdrojem problémů může být např. přetečení zásobníku, haldy apod. Zkusil bych ho zvětšit, zda dojde k nějaké změně.

Možná, že také ESP nestíhá nějaké výpočty, z časové smyčky to ale nepoznám. Prověřil bych také, zda program po optimalizaci správně počítá ty milis.

Jinak není důvod, proč by to nemělo fungovat.

Uživatelský avatar
Caster
Příspěvky: 434
Registrován: 11 zář 2019, 09:02

Re: Sériové řazení proměnných

Příspěvek od Caster » 25 lis 2024, 18:02

Co radí ChatGPT:

K pádu kódu může dojít v důsledku kombinace problémů, včetně možného přetečení zásobníku, nesprávného použití proměnných a logických chyb. Zde je postupná analýza a opravená verze vašeho kódu:

Chybný název proměnné: V názvech proměnných je potenciální překlep. Ve třetím příkazu if používáte Soucasny_Cas, což by pravděpodobně mělo být Soucasny_Cas_4 nebo jiná definovaná proměnná.

Potenciál nekonečné smyčky: Zkontrolujte, zda hodnoty Doba_resetu_zakladni, Doba_resetu_polovicni a Doba_resetu_ctvrtecni nejsou nastaveny tak, aby podmínky byly vždy pravdivé, což by způsobilo rychlé opakované spuštění a potenciální přetečení zásobníku.

Vnořené problémy s časováním: Vnoření příkazů if by mohlo způsobit problémy, pokud by nebylo správně řízeno. Vnitřní příkazy if se spoléhají na proměnné, které nemusí být určeny k vynulování v rámci vnějších bloků.

Zde je revidovaná verze kódu s opravami a přidanými bezpečnostními kontrolami:

Kód: Vybrat vše

unsigned long Soucasny_Cas_4;
unsigned long Minuly_Cas_4;
unsigned long Soucasny_Cas_2;
unsigned long Minuly_Cas_2;
unsigned long Soucasny_Cas;
unsigned long Minuly_Cas;

unsigned long Doba_resetu_ctvrtecni = 10000; // Example value in milliseconds
unsigned long Doba_resetu_polovicni = 5000;  // Example value in milliseconds
unsigned long Doba_resetu_zakladni = 1000;   // Example value in milliseconds

void setup() {
  Serial.begin(115200); // Initialize serial communication for debugging
  Minuly_Cas_4 = millis();
  Minuly_Cas_2 = millis();
  Minuly_Cas = millis();
}

void loop() {
  Soucasny_Cas_4 = millis();
  if (Soucasny_Cas_4 - Minuly_Cas_4 >= Doba_resetu_ctvrtecni) {
    Minuly_Cas_4 = Soucasny_Cas_4;
    // Akce I.
    Serial.println("Akce I executed");

    Soucasny_Cas_2 = millis();
    if (Soucasny_Cas_2 - Minuly_Cas_2 >= Doba_resetu_polovicni) {
      Minuly_Cas_2 = Soucasny_Cas_2;
      // Akce II.
      Serial.println("Akce II executed");

      Soucasny_Cas = millis();
      if (Soucasny_Cas - Minuly_Cas >= Doba_resetu_zakladni) {
        Minuly_Cas = Soucasny_Cas;
        // Akce III.
        Serial.println("Akce III executed");
      }
    }
  }
}
Hlavní změny a úvahy:

Opravy názvů proměnných: Třetí příkaz if nyní správně používá Soucasny_Cas, jak bylo zamýšleno. Zajistěte, aby byly proměnné Minuly_Cas a Soucasny_Cas správně spárovány.

Inicializace v nastavení: Inicializujte proměnné Minuly_Cas ve funkci setup, abyste se vyhnuli nedefinovanému chování.

Ladění výtisků: Přidány příkazy Serial.println pro usnadnění ladění a zjištění, které akce se provádějí.

Kontrola konzistence: Zkontrolujte, zda jsou funkce Doba_resetu_ctvrtecni, Doba_resetu_polovicni a Doba_resetu_zakladni vhodně nastaveny a konzistentní s očekávaným chováním, aby se zabránilo rychlému zacyklení, které může způsobit pád.

Pokud problém přetrvává, může být způsoben jinými faktory, například poškozením paměti, problémy s hardwarem nebo jinými částmi vašeho kódu, které zde nejsou uvedeny. Ujistěte se, že vám nedochází paměť, zejména na systému ESP32, který má omezenou velikost zásobníku a haldy.

Uživatelský avatar
kiRRow
Příspěvky: 1266
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Sériové řazení proměnných

Příspěvek od kiRRow » 25 lis 2024, 19:19

obojí jak máš, není moc dobře ... tím, že neustále aktualizuješ millis tak dostáváš program do možného nestabilního stavu ... načti millis jako aktuální hodnotu jen jednou na začátku loopu a po celý loop pracuj s tímto neměnícím se časem

zápis zásadně potom "paralerně" ... nezanořovat if do ifu v ifu

Cmrnda
Příspěvky: 31
Registrován: 25 dub 2024, 17:58

Re: Sériové řazení proměnných

Příspěvek od Cmrnda » 25 lis 2024, 20:07

Caster píše:
25 lis 2024, 18:02
Co radí ChatGPT:

void setup() {
Serial.begin(115200); // Initialize serial communication for debugging
Minuly_Cas_4 = millis();
Minuly_Cas_2 = millis();
Minuly_Cas = millis();
}
Tak tohle mě dostalo, teda... :lol: Proč bych si deklaroval do setupu millis a ještě k tomu na rozdílné proměnné. :lol:
Jinak samo, že se rozjíždí millis, čím víc toho tam napíšu, tím delší odezva.
Na CHatgpt se budu muset někdy zaměřit! :D
kiRRow píše:
25 lis 2024, 19:19
obojí jak máš, není moc dobře ... tím, že neustále aktualizuješ millis tak dostáváš program do možného nestabilního stavu ... načti millis jako aktuální hodnotu jen jednou na začátku loopu a po celý loop pracuj s tímto neměnícím se časem

zápis zásadně potom "paralerně" ... nezanořovat if do ifu v ifu
No já si právě myslím, že když první IF neprojde, tak se nenačítají ty další. Takhle stavím if vždy první co má nejméně četnější průchodnost z níže připravených. Ale kdo ví jak to ten program vůbec překládá.

Zápis 1x millis na celou smyčku, to by šlo, ale... , bylo by to k ničemu, nedávno jsem to měl naprogramovaný tak že pod smyčka běžela v hlavní smyčce i 10 minut. Proč? Protože příkaz "goto" nahoru je nadevše zdržující a s vytížením. :lol: To nemyslím moc vážně, ale používám ho, ikdyž by to mohlo jít jinak, třeba "for" nebo "whille". :lol:

Pro ten paralelní "if" máš nějakej důkaz? Je na to nějaký měření?

Cmrnda
Příspěvky: 31
Registrován: 25 dub 2024, 17:58

Re: Sériové řazení proměnných

Příspěvek od Cmrnda » 25 lis 2024, 20:30

Ještě mě napadlo jestli neexistuje v IDE něco jako "DoEvents" ve VB? Vím že se používá "tik" a tím se zjistí zda je dokončená nějaká událost.

Uživatelský avatar
Caster
Příspěvky: 434
Registrován: 11 zář 2019, 09:02

Re: Sériové řazení proměnných

Příspěvek od Caster » 25 lis 2024, 22:22

Pokud chceš provádět 3 různé akce z nichž každá probíhá s různou periodicitou, použil bych jako "profík" FreeRTOS, který je na takovéto věci primárně určen a neřešil bych to s milis. Ve FreeRTOS si můžes určit prioritu každé akce, předávat mezi nimi parametry přes frontu, vyvolat mimořádnou akci z přerušení aj.

Getting Started with STM32 - Introduction to FreeRTOS

Cmrnda
Příspěvky: 31
Registrován: 25 dub 2024, 17:58

Re: Sériové řazení proměnných

Příspěvek od Cmrnda » 25 lis 2024, 22:53

Caster píše:
25 lis 2024, 22:22
Pokud chceš provádět 3 různé akce z nichž každá probíhá s různou periodicitou, použil bych jako "profík" FreeRTOS, který je na takovéto věci primárně určen a neřešil bych to s milis. Ve FreeRTOS si můžes určit prioritu každé akce, předávat mezi nimi parametry přes frontu, vyvolat mimořádnou akci z přerušení aj.
Jo, FreeRTOS, ten už je ale podle dostupných informací zapracován ve firmware ESP32, možná né aktuální verze, ale je. Na jiném ESP 32 používám více asynchronních smyček, jenže to prakticky nikam časově nevede, zejména přeliv dat, to nejde předat, nebo si skákat z jedný smyčky do druhý, musí se použít, jak píšeš, přes "frontu", tj. buffer.
Tohle nechci. Na tomto ESP záleží především na blížení se "realtime" práci.

Uživatelský avatar
Caster
Příspěvky: 434
Registrován: 11 zář 2019, 09:02

Re: Sériové řazení proměnných

Příspěvek od Caster » 26 lis 2024, 00:17

Jak píšeš, FreeRTOS už by měl být zabudován ve FW ESP32. Díky tomu je napsání FreeRTOS programu v Arduinu jednoduché viz příklady v odkazu.

Using FreeRTOS with ESP32 and Arduino

Cmrnda
Příspěvky: 31
Registrován: 25 dub 2024, 17:58

Re: Sériové řazení proměnných

Příspěvek od Cmrnda » 26 lis 2024, 12:34

A ještě mě ukaž smysluplný příklad abych mohl říct, óóóóóó ... Na blikání LEDek není potřeba multitasking, a ještě jsou ovládány s "Delay()". Jediný co jsem na tom jel jsou teploměry "Dallas". Ty jsou ale tak pomalé, cca 600ms na jedno měření a pomalé je i měření teploty samotného integráče, protože je zalitý v obyčejném plastu. Když si vezmu obyč termistor + analog.měření, tak u 16 Bit DAC mám nastaveno 475 měření/sec.(default 128). Jestli dobře počítám, tak to bude zhruba 230x rychlejší. :D A ještě přesnost, 25,34, 25,95, 25,34, 25,95 ....., jo, asi takhle... :roll:

Jinak stejně jsem musel nandat smyčky na stejný jádro jako jsou knihovy, jinak to nešlo, nebo moc pomalu. I u těch Dallasů se mi stává že měření neproběhne, když není proiorita na "1". Při prioritě "2" už nejde ani na dálku flešovat, atd. Těch stupňů priorit je tam asi dvacet. :o

Odpovědět

Kdo je online

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