Mám tady řídící prográmek na Arduino Pro mini na řízení generátoru Si5351. Zobrazení na OLED 1,3" I₂C, knihovna pro řadič SH1106G.
V Setup mám skok do podprogramu void statup_text(), kterej zobrazí úvodní kecy:
Výpisová prkotina, takhle je to funkční. Ale pokud aktivuju komentovaný řádky, tak se zobrazí "úvodní výpis", pak se počká 3 sekundy, smaže displej, vypíše "výpis vstupů" ale už se neprovede výmaz displeje na konci a zůstane to zakouslý nejspíš v delay(3000).
Když zruším ve Void Setup() skok do Void Startup_text(), tak řízení generátoru za tímhle Startup_textem vše maká jak má.
Ovšem nyní začíná záhada. Pokud jsou odkomentované řádky viz výše, tak se to nekouše. Stačí ale abych jeden výpis přidal a už se to zase kouše. No a nejzajímavější je, že stačí do kódu nahoře přidat do textu pár znaků navíc a zase se to kouše.
Měl jsem podezření, jestli není chyba na nějaký adrese flešky v 328P ale jiná deska to dělá taky. Po kompilaci je ještě 6KB ve flešce volno a proměnný je ještě 1300 byte volno.
Zkusil jsem obsah Void Startup_text zkopírovat do Void Setup() aby se vyloučil problém se zásobníkem a vůbec žádna změna.
Netuším, v čem může být problém. Připadá mi, že pokud se má vypsat víc, než určitej počet znaků, tak se to hryže. Nějaká chyba v knihovně? Divný je, že grafickej test displeje s touhle knihovnou jede bez problémů mimo jiný plnej displej ASCII znaků. _________________ Jirka
Založen: Apr 02, 2011 Příspěvky: 18320 Bydliště: Nový Bydžov
Zaslal: pá duben 28 2023, 21:43 Předmět:
Jo, o knihovně u8glib od Oli Krause vím, je tam definice pro tenhle řadič:
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI
Ale je to monstrum 13KB, co zabere půlku flešky 328P a navíc proti Adafruit OLED knihovnám dost šílený ovládání. Ale v nejhorším zkusím. Díky! _________________ Jirka
Založen: Aug 16, 2022 Příspěvky: 465 Bydliště: Roztoky
Zaslal: so duben 29 2023, 6:11 Předmět:
Já bych řekl, že to je problém s přetečením stacku nebo heapu (podle toho, jak knihovna alokuje paměť). Přesun z jedné funkce do jiné nemá skoro žádný vliv. Protože je práce s řadičem dost pomalá, asi by mohlo pomoci, vložit mezi výpisy menší delay, aby se stihl přesun zchroustaných dat do řadiče. Taky by mohlo pomoci použít ve výpisech makro "F", aby se řetězce ukládaly do flešky a nezabíraly míso v RAMce. Jinak bez možnosti debugování se tenhle problém bude hledat dost blbě.
Založen: Apr 02, 2011 Příspěvky: 18320 Bydliště: Nový Bydžov
Zaslal: ne duben 30 2023, 0:45 Předmět:
Takže se asi zbouchne proti sobě stack, co ukládá směrem dolů a heap, co ukládá směrem nahoru? Nebo datovka vleze do heap?
Jde nějak nastavit velikosti stack a heap?
Koukal jsem na net, co s tím. Vyházet globální definice a nahradit je lokálníma, kouknout jestli int nepůjde předefinovat na char.
Potom jsem ještě četl něco o Static a Dynamic json.Buffer ale vůbec netuším, vo co go. _________________ Jirka
Založen: Aug 16, 2022 Příspěvky: 465 Bydliště: Roztoky
Zaslal: ne duben 30 2023, 6:42 Předmět:
Můžeš si to představit tak, že dolní oblast RAM je alokována pro globální proměnné a její velikost se určí v okamžiku překladu a je neměnná. Nad ní začíná heap, ze kterého se přiděluje RAM dynamicky za chodu ,třeba funkcí malloc, new, a přiděluje se taky proměnným v nově vytvářených objektech. Stack začíná úplně nahoře a jede směrem dolů. Přes něj se předávají data při volání funkcí a vytvářejí se jejich lokální proměnné. Taky na rozdíl od heapu, má stack hardware registr v MCU a mohou s ním manipulovat přímo instrukce assembleru, protože se tam strkají i různé data při přerušeních. Správa heapu bývá většinou v kompetenci OS, nebo u MCU ji řeší překladač.
Definicí static řekneš kompiléru, že ta proměnná bude alokována permanentně v dolní cásti paměti. To se hodí třeba u funkcí, kde je třeba znát stav z minulého volání, což přes hodnoty na zásobníku není možné. Globální proměnné jsou všechny static.
Tvůj problém asi bude v nedostatku paměti MCU. S knihovnou nic neuděláš, takže musíš skrouhnout svoje nároky. Použitm makra F v printech, donutíš kompilátor, aby ty textové řetězce uložil do flash paměti, místo do RAM a tak získáš nějakou RAM (výměnnou za výkon). Pokud je práce s řadičem přes I2C pomalá, můžeš vložením delay nechat knihovnu ať zpracuje aktuální data a neprodlužuje dynamické buffery příjmem dalších řetězců, atd...
Založen: Jan 01, 2023 Příspěvky: 1888 Bydliště: Česká Lípa
Zaslal: ne duben 30 2023, 12:40 Předmět:
Nejprve vyzkoušejte co zde navrhoval ondraN tj. řetězce ukládat do flešky a ne do RAMky.
Takže například namísto
display.print("Si5351");
použijte
display.print(F("Si5351"));
a stejně tak u dalších volání display.print s různými řetězci textu.
Arduino Pro mini, které zmiňujete má 2kB RAM (tj. pouze 2048 bajtů), a to není mnoho.
Vývojové prostředí Arduino IDE vypisuje využití rozsahu globálních alokací paměti při překladu projektu.
Pokud je to blízko hranice těch 2048 bajtů pak máte v projektu příliš globálních alokací, které bývají v části na počátku zdrojáku, kde bývají deklarovány různé proměnné, pole atd. a z části to může být ukryto i v knihovnách zejména pokud se používají různé objekty jako třeba pro řízení displeje apod.
S knihovnami asi nim moc nenaděláte jak zmínil ondraN leda, že byste použil třeba pro řízení toho displeje nějakou jinou variantu knihovny, která by byla méně náročná na paměť (pokud pro daný účel existuje).
Pokud máte v programu deklarovány nějaké globální pole, které byste mohl zkrátit tak je udělejte pokud možno kratší.
Jakou spotřebu paměti vám při překladu toho projektu vypisuje překladač?
Založen: Apr 02, 2011 Příspěvky: 18320 Bydliště: Nový Bydžov
Zaslal: ne duben 30 2023, 14:46 Předmět:
Valdano napsal(a):
Jakou spotřebu paměti vám při překladu toho projektu vypisuje překladač?
Píšu to hned v úvodním příspěvku, proměnný mají 1300 byte volných. Pole nejsou použitý, stringy taky ne. Právě proto je mi divný, co by mělo zapatlat RAMku. Navíc tyhle výpisy jsou hned na začátku programu ve Void setup(). Přerušení pro n-codér se spouští až po tomhle výpisu. Tady je začátek toho mýho projektu:
Takže globální proměnný zabírají nějakých 32 byte. Určitě to bude víc, ale víc jich jinde definováno opravdu není.
Zkusil jsem přestěhovat texty v startup_text do flešky a je to naprosto stejný. Jakmile je poslaných víc znaků na displej, hryzne se to. Pokud před texty dám string, tak se to zase chová stejně. Stačí ubrat stejnej počet znaků a maká, pár jich přidám a zase se žvejkne.
Podle mě je problém v knihovně. _________________ Jirka
Založen: Jan 01, 2023 Příspěvky: 1888 Bydliště: Česká Lípa
Zaslal: ne duben 30 2023, 17:08 Předmět:
Chyba může být v knihovně Adafruit SH110X. Když to někam hrábne tak to pak může a nemusí padat v závislosti na tom co a kde to při tom hrábnutí přepsalo. Někdy se může chyba zdánlivě ukrýt tím, že se změní zdroják a po překladu se to v paměti trochu jinak uspořádá a chyba se přestane projevovat což neznamená, že by tam nebyla dál, ale hrabe někam do místa kde to prostě shodou okolností nevadí a tak se to neprojevuje. Takové chyby se velmi špatně hledají. Seznam různých verzí zmíněné knihovny v čase je viz tento odkaz. Pokud máte starší verzi té knihovny tak zkuste použít tu nejnovější verzi 2.1.8. Jestli to bude dělat i s ní.
Aha tak to se omlouvám. Já to sice četl, ale přehlédl jsem že to je zrovna ono.
Jinak mám ty Adafruit knihovny otevřené ve vedlejších tabech, byl jsem odhodlán že se na to mrknu, ale Valdano má pravdu, jakou verzi té knihovny jsi použil? Resp můžeš zkust novější a dát vědět… (a ještě můžeš zkusit proházet mezi sebou ty include na začátku programu, i když by to teoreticky mělo být jedno, někdy to může zabrat… pokud by to přestalo, pořád by to odpovídalo tomu co napsal Valdano - "chyba sice je, ale hrábne někam kde to nevadí", a pořád se bude blbě hledat )
Založen: Apr 02, 2011 Příspěvky: 18320 Bydliště: Nový Bydžov
Zaslal: ne duben 30 2023, 18:11 Předmět:
Koukal jsem do manažéru knihoven a mám poslední 2.1.18. GFX, která s displejem taky souvisí mám poslední, 1.11.5. Takže buď zkusit starší nebo nevím...
Ale je to zajímavější. Vyměnil jsem ten 1,3" OLED za 0,96" s SSD1306. Má to knihovnu SSD1306 a stejnou GFX. No a co by jste řekli? Je to stejný!!! Tak buď je bordel v GFX a nebo je v těch knihovnách stejná chyba. Mají stejný příkazy, nejspíš stejnej autor a obojí Adafruit.
Ještě to zkusím přepsat na U8GLIB ale to je na delší dobu, jinak se s ní pracuje.
Když to bude neřešitelný, tak se na ten úvodní výpis prostě vykašlu. S další částí zobrazení v obsluze VF generu Si5351 žádnej problém není. A to tam je i grafika, několik velikostí fontu a pod. Ale je to opravdu divný, taková celkem jednoduchá věc jako blbej výpis na displej jedním typem fontu.
Ještě mě napadlo vyházet z obsluhy toho SI5351 některý části, co nejsou vyloženě prioritně potřeba , třeba ukládání do EEprom, zobrazování grafiky, dát kmitočtovej krok natvrdo a zkrátit tak o pár KB program. Jestli se něco změní na těch výpisech. _________________ Jirka
Založen: Jan 01, 2023 Příspěvky: 1888 Bydliště: Česká Lípa
Zaslal: ne duben 30 2023, 18:42 Předmět:
Celeron napsal(a):
Píšu to hned v úvodním příspěvku, proměnný mají 1300 byte volných.
Problém je v tom, že překladač vám vypíše jen spotřebu paměti globálních pevně deklarovaných proměnných, ale pokud knihovna alokuje paměť z haldy dynamicky tak to se samozřejmě děje až za běhu programu a tuto spotřebu vám překladač při překladu nezobrazí.
Díval jsem se do základní knihovny Adafruit_GFX, a ta si alokuje pro celou kreslící plochu paměťový bafr (tj. pole) dynamicky funkcí malloc v konstruktoru tj. ještě před voláním těch funkcí pro výpisy textu
kód:
velikost v bajtech = ((sirka + 7) / 8) * vyska;
Takže pokud máte pro ten displej deklarovánu šířku 128 a výšku 64 pixelů, tak se funkcí malloc alokuje dynamicky datový bafr o velikosti
kód:
1024 = ((128 + 7) / 8) * 64;
Když odečteme ten překladačem oznámený zbytek 1300 - 1024 tak najednou zbývá už jen 276 bajtů, a pokud jsou tam ještě nějaké další dynamické alokace třeba v knihovně Wire tak může paměť na haldě lehce dojít a pak se nelze divit tomu, že se někam hrábne a program jak se říká "lehne" a nebo se začne chovat nevyspytatelně.
Pro tyto knihovny by to zkrátka asi chtělo verzi Arduina, která má k dispozici víc paměti RAM tj. zvážit použit namísto Arduino Pro Mini, které má jen 2kB RAM třeba nové Arduino Nano Every, které má 6kB RAM a navíc ještě výkonnější procesor. Pokud máte doma Arduino Mega 2560 tak to zkuste s ním jen na vyzkoušení. Pokud je ten problém způsoben tím, že díky dynamickým alokacím dochází paměť haldy při velikost RAM jen 2kB tak při velikosti 8kB, které má verze Mega 2560 by se ty problémy neměly projevovat vůbec.
Časy uváděny v GMT + 1 hodina Jdi na stránku 1, 2, 3Další
Strana 1 z 3
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.