Problém s přerušením (?) blikání LED časovačem, občas nejde

peknej :smiley:

Dobrej dravec :smiley: ale musim si rejpnout - máš špatně obutý kola :smiley:

Rejpej si, ale nevim co se ti nelíbí. Jestli myslíš to zadní levý kolo na fotce, tak to je obutý dobře. To kolo má na jedné straně takový vnější ráfek. Jinak ty všecky 3 kola pocházejí ze starých rozbitých hraček.
Ale to radši nechtějte vědít, jak mám udělanou převodovku :smiley:
O víkendu o tom něco podrobněji sepísnu na web, takže se můžete těšit na další zajmavá odhalení, o téhle šílené konstrukci.
Příště plánuju vyrobit miniaturního 6tinohého chodícího hmyzáka.

Myslím obě. Tak jak jsou by to mělo jezdit tím 1 kolem vzadu. Když jede stroj vpřed, měla by pneumatika vodu vytlačovat dostran, u tebe by ji hrnuly pod sebe :wink: Samozřejmě, že to asi vodou honit nebudeš a už vůbej né rychlostí 10 délek stroje za vteřinu. Ale víš jak :smiley:

to je ta poslední věc, která mě trápí :slight_smile:

Neviem, co si myslel pod slovnym spojenim “mode no 2” a “mode no. 6”
Dal som si dokonca vyhladat tento usek textu cez Ctrl+F a okrem tychto dvoch zapisov sa uz nikde nevyskytol. Ano po tretom prebehnuti zdojaku mi nebolo jasne, co Ti vlasnte nejde.

Velmi rad by som Ti poradil, ale zdrojak je dost neprehladny, aspon ze Piityy sa cez to cele prekusal a radi Ti. :slight_smile:

Pouzitie volatile je normalne, ak chcem povedat prekladacu, aby premennu neoptimalizoval (nepouzil ju iba ako registrovu premennu, pripadne aby ju uplne nevyhodil, ak zisti, ze sa da napr. pod interuptom nahradit konstatnou), lebo jej obsah moze menit este niekto iny. Tym volatile “zabranujeme” prekladacu, aby robil to, co od neho vacsinou chceme - teda optimalizoval. A este aj tak nam vadi, ze to neoptimalizuje tak, ako by sme si predstavovali. Tak mu to nezazlievajme. :slight_smile:

Rozhodne dat vsade volatile program nespomali o nic viac, ako keby si programoval v ASM a vsetky premenne by si mal v RAM a nie v registroch. Ak pred premennu volatile nedas, umoznis prekladacu, aby si premennu vytvoril po dobu potreby iba v registri. Typicky priklad je pouzitie

for (int8_t i = 0; i < 100; i++ ) {

}

To s tyka i Tvojej pripomienky k ENUM.
Pozri si ako enum funguje je a zistis, ze nie je najmensi dovod, aby pouzitie enum program 10x spomalilo. ENUM je len a len na to, aby bol program prehladnejsi.

ale nasiel som v Tvojom kode par pikosiek, ako napriklad

...
if (OCR1A > 0) OCR1A -= 10; 
...

alebo

...
else if (OCR1A < 250) OCR1A += 10;
...

Myslim, ze by mali byt napisane

...
if (OCR1A >= 10) OCR1A -= 10; 
...

...
else if (OCR1A <= 245) OCR1A += 10;
...

uz ked si sa rozhodol sledovat hranice, tak ich kontroluj dosledne. Mozno Ti je teraz jasne, ze sa nemoze stat, aby OCR1A mala hodnotu 4, ale neskor mozes kod modifikovat, spolahnes sa na to , ze tam mas kontrolu hranic a budes problem tyzden hladat.

áchjo. Přehlednějc ten kod napsat neumím, a nevím co je tam nepřehledného.
“mode no X” - myslim že všici to pochopile, proč ne ty? Je vidět že sis ten zdroják skoro ani nečetl. Máš tam uprostřewd hlavní smyčky switch, mkterý podle hodnoty v prom. “mode” pouští jednotlivé podprogramy. To je vše.

Ještě zachvilku něco dopíšu k těm “pikosiekam” co jsi našel. Obávám se totiž, že to mám napsané správně.
EDIT:
Takže, celý ten “mode 3” jsem zkontroloval, a nikde nevidím chybu. Stejně tak, to vždy fungovalo bez chyby.
Ten podprogram dělá tohle:
na robotovi mám dvě tlačítka, up/down. Těmi můžu ručně regulvoat otáčky i směr motoru. Budič motoru je udělaný tak, že zvyšováním vuzení na OCR1B jede motor vpřed (OCR1A =0), a obráceně, kdy v OCR1A je kladná hodnota (OCR1B = 0) jede motor vzad.
Ten podprogram dělá to, že na začátku motor stojí. Mačkáním up se zvyšuje postuně hodnota v OCR1B až do maxima (250). Mačkáním down, se OCR1B snižuje, až dosáhne nuly. Další stisknutí DOWN způsobí to, že se motor rozjede na opačnou stranu (zvyšuje se zase hodnota OCR1A).
Ty podmínky jsou tam vskutku správně.
EDIT2:
Chápu kam míříš těmi radami jak upravit ty podmínky, ale ne, tohle nepotřebuji. Tenhle podprogram už se upravovat nebude, bylo to jen na otestování. To že hodnota v OCR1x dosáhne max 250 místo plných 255 mi vůbec nevadí. znaménka >= nebo <= komplikují spíš přeložený kod. Komplikace se tomu říct úplně nedá, ale mám slušnou zkušenost s progamováním AVR v ASM, takže jak se tyhle znaménka interpretují vím, a neni to zrovna příjemné. Ale když to řeší překladač, je to vlastně jedno.

Pokial som si vsimol, k samotnemu zdrojaku sa vyjadruje iba Piityy. Odkial teda beries istotu, ze to vsetci pochopili, iba ja nie?
Toho switch v strede som si samozrejme vsimol. Ale mas tam jasne v komentari napisane

void preved_na_dis(void) // obsah cisla promenne mode prevede na cislo na displej 

Takze podla popisu rutina prevedie nejake cislo na nejake ine. Ako mam dojst na to (bez hlbsieho skumania), ze sa od toho spustaju nejake podprogramy? Tu nikde nevidim suvis s nejakym konkretnym programom, v ktorom by mohol byt udajny problem.

Tak to aspon do prispevku napis, tuto a tuto nastavujem cislo a volam tu a tu rutinu, v ktorej je asi problem. A nie, ze mi nejde to “mode no 2”. Lebo to “mode no 2”. V tom switche NESPUSTAS ziadne jednotlive podprogramy (mnozne cislo) ale iba funkciu display(). Taketo ciastocne vyjadrenia, naznacenia a nepresnosti robia zdrojovy kod (hlavne pre inych) neprehladnym.

To, ze to prehladnejsie napisat nevies, vobec nevadi. Nikto z pokrocilejsich to na zaciatku lepsie nevedel. Ale bez upozorneni inych by na to ani nedosiel. Tak preto som si dovolil ten predchadzajuci prispevok. Myslim, ze sa snazis prist na koren svojho problemu. My ostatni sa Ti budeme snazit pomoct, pokial to nase vedomosti, skusenosti a cas dovolia. No a prehladnost ma velmi velky vplyv na polozku “cas”.

Tak, ty jsi mě dokonale dostal teďka. Je vidět, že ten program oravdu totálně nechápeš.

Jdu ještě připsat pár komentářů do toho programu, ale myslim si, že ví již nemohu.

preved_na_dis(void) dělá to, že vezme proměnnou mode, a její obsah mi zobrazí na displej, se spouštěním něčeho nemá souvislost, na tohle jak jsi přišel fakt nevim.

tím “podprogram” myslím jednu větev toho switch ve fci main. Pokud vím, je to tam i v komentářích nazvané podprogram. Asi sem měl zvolit lepší název na to, protože je vidět že podprogram všichni chápou jako rutinu/další funkce. Tomu se nedivím.

EDIT: Nevím, kdes vzal to, že preved_na_dis něco spouští. Jasně u toho máš komentář, co to dělá:

preved_na_dis(); //aktualni "mode" se zobrazi na displej

Martin: Těma “podporgramama” myslí vždy tu sadu instrukcí v každym case. On mu totiž main spolupracuje s přerušením, takže mezi přiřazením hodnoty a delay mu nějakou dobu maká přerušení. Ty “mode” jsou jednotlive větve switche (switchuje se “mode”)

Jan: S tou kontrolou hranic má martin pravdu. Ikdyž se ti tam v praxi třeba nemůže vyskytnout hodnota 246 (protořže krokuješ po 10ti), tak v případě že by se dam nějakou náhodou dostala ti OCRR přeteče a přitom to podmínce vyhovuje. Stejná situace nastane při OCRR = 9.
podmínky by tedy měly být
if (OCR1A > 9) OCR1A -= 10; // prakticky to samé co napsal martin
a v případě maxima 250 pak
else if (OCR1A < 241) OCR1A += 10;

piityy - chápu kam tim míříte, ale tohle bych tu nerad pitval. Vim že to neni správně jak by mělo, už jsem s tím jednou i problém měl, ale jen proto, že jsem do tohohle “podprogramu” vstoupil když v těch registrech OCR už byly nějaké malé hodnoty, které mi to rozhodily. TO jse mjednoduše ošetřil tím, že jsem na začátek podprogramu přidal vynulování obou OCR, pro jistotu, že je tam nula. Potom tyhle podmínky co tam mám napsané jsou správné, a vyhovují, protože jiná hodnota se tam nedostane.

no tak sa pozrime, odkial som na to prisiel

Je pravda, ze slovo “pousti” a “spoustenim neceho” je trochu rozdielne, ale vzhladom i na ine preklepy som tieto slova stotoznil. :slight_smile:

to Piityy: To by ma nenapadlo, ale dakujem za vysvetlenie. Uz sa v tom orientujem o nieco lepsie.

Martin: teda jestli se chcete vymlouvat na moje preklepy, ze diky nim jste to nepechopil, to prominte, ale tohle neberu.

Tohle jsem vám psal já:
tím “podprogram” myslím jednu větev toho switch ve fci main. Pokud vím, je to tam i v komentářích nazvané podprogram. Asi sem měl zvolit lepší název na to, protože je vidět že podprogram všichni chápou jako rutinu/další funkce. Tomu se nedivím.

Tohle vám pak napsal piityy, je to v podstatě to samé:
Těma “podporgramama” myslí vždy tu sadu instrukcí v každym case. On mu totiž main spolupracuje s přerušením, takže mezi přiřazením hodnoty a delay mu nějakou dobu maká přerušení. Ty “mode” jsou jednotlive větve switche (switchuje se “mode”)

Ještě k těm kontrolám hranic. Určitě ti to tady u autíčka i jinde bude fungovat, ale tou volnější podmínkou dáváš prostor pro případný poruchy a nepřípustný chování. Tady to nevadí - maximálně se ti splaší autíčko. Ovšem v průmyslových zařízeních se občas stane, že se do mcu prokmitá rušení, který ti i může změnit hodnotu registru - obzvlášť takovýho, kterej visí přímo na periferii. Teď si představ na tvym pwmku pojezd soustruhu, kterej pomalu dojíždí k hlavě. Už je na nejnižší hodnotě, další má bejt 0 aby zastavil. Během práce mu do OCR něco našumí a místo zastavení mu podteče registr, pustí tam plnou šťávu. Rozlámanej upínák, stůl, univrzála… Prostě stroj (v ceně několik set tisíc) na odpis :wink: (V lepším případě jen stroj). Samozřejmě trochu přehánim, ale je lepší takovýhle zárodky eliminovat co nejdřív.

to Martin:
je sice pravda ze ten zdrojovej kod je napsanej dost neprehledne ale jeho funkci jsem z nej napoprve vycetl, dokonce jsem i pocopil proc tam ma switch a co je podprogram, tohle tema sleduju od zacatku a porad vim ze “podprogram” je jedna vetev switche

fridlik: Moje řeč :slight_smile:

ahoj chtel jsem se zeptat, jestli kdyz nastavujes registry, tak jestli v nekterych prikladech nemas chybu, napr. TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
nejsem si jisty, proto se ptam, jestli nema nahodou byt TCCR1A |= a pak jednotlivz bitz jak to mas ty

jde tam dát obojí. Ale správnější formulace si myslim je to jak to mám já s tím “=”. A to z toho důvodu, že kdyby byl nastavený nějaký další bit, tak by tak zůstal, a já chci nastavit jen ty co jsem napsal, proto to rovnáse.

Neřekl bych “správnější”, ale pokud je to úmyslné, tak “vpořádku”. Dával bych si na to ovšem pozor. Když je totiž v nějakém registru nastavený nějaký bit, má to obvykle svůj důvod. Je lepší manipulovat jen tím, co tě skutečně zajímá. V jednom registru se můžou sejít bity více periferií, které navíc nejsou popsány spolu a při psaní programu tě nemusí hned trknout, že s tím konkrétním bitem nesmíš hnout. A zjišťuj pak proč ti nejde procesor probudit externím přerušením ze spánku, když jsi ho přeci před tím správně nastavil :wink:

piityy s tím tak úplně nesouhlasím. Když něco zapisuju do registru co něco řídí, tak v DS si VŽDY najdu co který bit přesně znamená, tedy pokud nenstavím něco co nemám (něco lidově neposeru), tak je to OK, a nikdy jsme s tím neměl problém. Jak se říká, dělejte v programu co nejmenší prostor na chyby.
Ale jinak samozřejmě do registrů když požaduju akci nastavení bitu , tak samozřejmě to dělám přes ANDI, nebo ORI.