Re: Jak zjistit, že je hodnota stabilní
Napsal: 07 kvě 2019, 12:16
Pokud chceš "eventuálně čekat už jen pár sekund", tak prostě to pole 600 hodnot potřebuješ celé, ale určitě ho nemusíš pokaždé celé procházet.
Rozhodně bych ho bral jako kruhový buffer (a bez ujmy na obecnosti předpokládal, že začíná první hodnotou).
Na začátku vzít minimum a maximum, jak to máš, ale jako globální hodnoty, tedy deklarované mimo loop (stejně jako indexy začátku a konce).
Při každém měření se hodnota přidá na konec bufferu a stačí upravit to min a max jen podle poslední hodnoty, pokud jsou pořád v 3% toleranci tak jdeme dál, jakmile délka bufferu dosáhne 600, tak je stabilní.
Pokud to z tolerance vypadne, tak to prohlásit za nestabilní, nastavit min a max jako na začátku a projít to pole odzadu, s tím, že pokud by další hodnota (tedy s nižším indexem) měla způsobit vyskočení z rozsahu, tak se nastaví počátek bufferu tak, aby už tam ta hodnota nebyla (odřízne se začátek).
Pokud to někde divoce zakmitá, tak se ti ten buffer zkrátí na pár hodnot a procházení rychle skončí, protože dál nejdeš.
Pokud to pouze vytrvale pomalu roste/klesá, tak ho v nejhorším případě projdeš (skoro) celý.
A pokud bude ten buffer plný, a bude to pomalu driftovat (čili ti například vypadne minimální hodnota a ty to nebudeš vědět), tak ten zpětný chod najde nová správná minima/maxima a buffer se ti nemusí zkrátit a nedojde k falešné "nestabilitě" - přitom ten výpočet nových hodnot přez to pole nebude delší, než když to v neoptimalizované verzi jedeš pokaždé celé - a pokud se to moc nemění, tak nebude v každém průchodu.
Taky by se tomu by se dalo pomoci tím, že pro hledání začátku použiješ přísnější kritérium (třeba 2%), abys to při další hodnotě neprocházel zbytečně znova skoro celé (čili ho zkrátíš o trochu víc a budeš mít drobnou rezervu pro malá kmitání, za cenu o trochu víc měření - ale ono je pak velká šance, že pokud se to limitně blíží nějaké hodnotě z jedné strany, a ty se vracíš přez 500 hodnot, a jen to těsně nafituješ, tak se v dalším kroku budeš vracet zas, a pokud takhle dosáhneš 600 hodnot, tak by ti ta příští opět vyskočila. Když ten ocas uřízneš víc, tak to má rozumnou šanci se ustálit bez mnoha opakovaných dlouhých zpětných chodů).
A pokud bys chtěl optimalizovat za každou cenu, tak můžeš obejít výpočty v plovoucí čárce a dělení třeba takto:
případně v tom zpětném chodu používat ty long pro počítání rovnou.
---
Stejně budeš mít problém s čidly, které se ustálí na nízkých hodnotách - například při hodnotě 33 a míň dostaneš "stabilní" stav pouze pokud se hodnota nebude měnit vůbec - protože změna o +/-1 už je víc než změna o 3% - takže bych spíš doporučil upravit požadavek na něco jako že se to nemění o víc než 3% + 5 bodů, nebo tak, aby se to mohlo "ustálit" i v okolí nuly.
Rozhodně bych ho bral jako kruhový buffer (a bez ujmy na obecnosti předpokládal, že začíná první hodnotou).
Na začátku vzít minimum a maximum, jak to máš, ale jako globální hodnoty, tedy deklarované mimo loop (stejně jako indexy začátku a konce).
Při každém měření se hodnota přidá na konec bufferu a stačí upravit to min a max jen podle poslední hodnoty, pokud jsou pořád v 3% toleranci tak jdeme dál, jakmile délka bufferu dosáhne 600, tak je stabilní.
Pokud to z tolerance vypadne, tak to prohlásit za nestabilní, nastavit min a max jako na začátku a projít to pole odzadu, s tím, že pokud by další hodnota (tedy s nižším indexem) měla způsobit vyskočení z rozsahu, tak se nastaví počátek bufferu tak, aby už tam ta hodnota nebyla (odřízne se začátek).
Pokud to někde divoce zakmitá, tak se ti ten buffer zkrátí na pár hodnot a procházení rychle skončí, protože dál nejdeš.
Pokud to pouze vytrvale pomalu roste/klesá, tak ho v nejhorším případě projdeš (skoro) celý.
A pokud bude ten buffer plný, a bude to pomalu driftovat (čili ti například vypadne minimální hodnota a ty to nebudeš vědět), tak ten zpětný chod najde nová správná minima/maxima a buffer se ti nemusí zkrátit a nedojde k falešné "nestabilitě" - přitom ten výpočet nových hodnot přez to pole nebude delší, než když to v neoptimalizované verzi jedeš pokaždé celé - a pokud se to moc nemění, tak nebude v každém průchodu.
Taky by se tomu by se dalo pomoci tím, že pro hledání začátku použiješ přísnější kritérium (třeba 2%), abys to při další hodnotě neprocházel zbytečně znova skoro celé (čili ho zkrátíš o trochu víc a budeš mít drobnou rezervu pro malá kmitání, za cenu o trochu víc měření - ale ono je pak velká šance, že pokud se to limitně blíží nějaké hodnotě z jedné strany, a ty se vracíš přez 500 hodnot, a jen to těsně nafituješ, tak se v dalším kroku budeš vracet zas, a pokud takhle dosáhneš 600 hodnot, tak by ti ta příští opět vyskočila. Když ten ocas uřízneš víc, tak to má rozumnou šanci se ustálit bez mnoha opakovaných dlouhých zpětných chodů).
A pokud bys chtěl optimalizovat za každou cenu, tak můžeš obejít výpočty v plovoucí čárce a dělení třeba takto:
Kód: Vybrat vše
if ( 100 * (unsigned long)minimum < 97 * (unsigned long)maximum ) Serial.println ("Stabilni");
else Serial.println ("Nestabilni");
---
Stejně budeš mít problém s čidly, které se ustálí na nízkých hodnotách - například při hodnotě 33 a míň dostaneš "stabilní" stav pouze pokud se hodnota nebude měnit vůbec - protože změna o +/-1 už je víc než změna o 3% - takže bych spíš doporučil upravit požadavek na něco jako že se to nemění o víc než 3% + 5 bodů, nebo tak, aby se to mohlo "ustálit" i v okolí nuly.