Formatovany tisk pro 8bit
Pavel Hudeček
edizon na seznam.cz
Sobota Duben 20 12:29:27 CEST 2024
Ne, v mém příkladu je přeci stav uBat1=3753, tak uartSend("\1mV",
adUbat1, 0); vypíše 3753mV
Pokud by adUbat bylo 53, vypíše 53mV
a pokud by bylo zadáno uartSend("\1mV", adUbat1, 3);
vyleze 3753,000mV
nebo třeba 3753,001, pokud float hodnota nevyšla přesně 3753,000
Nějak tak to fungovalo, už je to dlouho.
Ale jak se tu o tom teď diskutuje a ještě jsme na kroužku došli k
sériáku, tak si asi konečně udělám tu knihovnu, kde tohle bude jedno z
přetížení.
PH
Dne 20.04.2024 v 11:27 Martin Záruba napsal(a):
>
> Jen dotaz: Co vypíše:
>
> uBat1 je 53
>
> uartSend("\1mV",adUbat1,0);
>
> nevypíše to
>
> 53mV ?
>
> Martin Záruba
> Dne 20.4.2024 v 10:36 Pavel Hudeček napsal(a):
>> Tady asi došlo k mírnému nedorozumění:
>> Oba umíme zobrazit jen jednu hodnotu.
>> Oba umíme požadovaný počet des. míst.
>> Oba umíme text před ním i po něm.
>> Já nemám formátování tisíců, ale zas můžu ve výstupním textu použít #.
>> Zas to formátování s # se asi dá ohackovat, že zobrazí třeba 2 čísla
>> zakódovaný do jednoho longu?
>>
>> // adUin je 12,3456 uBat1 je 3753
>> // UART_sendDT je ',' UART_sendPosChr je '\1'
>> uartSend("Uin=\1 V\n", adUin, 2);
>> uartSend("\1mV", adUbat1, 0);
>> výsledek je:
>> Uin=12,34 V
>> 3753mV
>>
>> Ten uartSend byl trochu prasáckej, mist nakopíruje do globální
>> uartSendMist a pak zavolá cislo((long)(v * m)), kde m je třeba 1000
>> pro mist=3. A cislo pak do požadovaného místa vnutí oddělovač a
>> uartSendMist vynuluje. Tohle jsem už někde měl i na ty tisíce, jen se
>> to nevypínalo samo.
>>
>> Chystám se že bych si z těhle věcí konečně udělal nějakou knihovnu,
>> zatím to jen kopíruju mezi projekty a nejčastějc si vystačím s
>> putchar2, text na poslání textu a cislo na poslání longu.
>> takže posledně to bylo ve stylu
>> text("Uin="); cislo(static_cast<long>(1000.0*adUin)); text(" mV\r\n");
>>
>> Buffer je na zásobníku, takže sám vznikne a sám zmizí.
>> Ale 100 B, to je 20 % RAMky na ATtiny816, což je hodně, případně 1,25
>> % na AVR64DD32, to už by bylo v pohodě.
>> Mě se to obecně nelíbí, protože rád používám děje na pozadí. Funkce
>> cekej(uint32_t ms) je i víc než půlka programu a pokud možno všechno
>> čekání volá aspoň cekej(0). No a když se těch čekání sejde více
>> takových, kde mezitím vzniknul buffer..
>> Takže mám snahu takové buffery nedělat.
>> Další věc je, že mám snahu minimalizovat místa, kde je potřeba
>> omezovat velikost stringu. Takže mě stačí buffer na 10B celej vstup
>> může mít 254, výstup až 264 a ve verzi s txtPred + txtPo můžou klidně
>> oba texty mít do 254.
>>
>> Ovšem to s F a PSTR je pro mě novinka, za to díky.
>>
>> Byl jsem zvyklý na codevision, tam se daly deklarovat proměnné do
>> RAM, EEPROM i Flash, "text" byl ve flash a všechno fungovalo do velké
>> míry samo, včetně toho, že v EEPROM je pointer do flash. Super věc,
>> pokud se po kompilaci k binárce sprostě přikopírujou UTF8 texty ve 4
>> jazycích a za ně bitmapa fontů. Při prvním spuštění program ve flash
>> najde "Tady>>>", pak dohledá začátky jazyků, hlášky v default jazyku
>> a nakonec font. Pointery hodí do EEPROM a odteď se může na displeji
>> 10 ms po zapnutí objevit třeba normální čeština.
>> A v případě GCC jsem si myslel, že nic už takhle elegantně nepůjde.
>> Vlastně opravdu nejde, protože si sice můžu nadeklarovat proměnnou v
>> EEPROM, ale nemůžu jí přímo používat, jen přes funkce na čtení a
>> zápis EEPROM, který maj navíc hrozně dlouhý názvy. "Super" do vzorce
>> se 3 kalibračníma konstantama.
>> Tak aspoň snad zas můžu mít texty ve flash:-)
>>
>> PH
>>
>> Dne 19.04.2024 v 21:23 Martin Záruba napsal(a):
>>>
>>> Já to tak původně dělal, jenže byl to mnohem složitější a vlastně
>>> můžete takto udělat jen část než narazíte na první formátovací znak.
>>> Pak už je to stejně jen odeslání čísla. protože nevíte, zda nebude
>>> následovat další formátovací znak po libovolné počtu "výplní". Tvar
>>> text,val, míst se mi nelíbil, protože s ním neuděláte třeba 10mV.
>>> Takto je text kdekoli, dokonce je kdekoli i třeba \n, takže nemá
>>> smysl println. A varinta txtPred, val, míst, txtPo to sice umí, ale
>>> jsou 4 parametry a stejně nejde udělat třeba odskočené tisíce. Taky
>>> se mi líbí, že to sežere i float. Předpokládím, že buffer se vytvoří
>>> na zásobníku a po opuštění funkce zmizí. Je to tak?
>>>
>>> Ještě to chci doplnit o možnost mít formátovací řetězec ve flash.
>>> Není mi ale jasné, jaký je rozdíl mezi PSTR("V paměti flash") a F("V
>>> paměti flash"). Asi se mi víc líbí F(" "), je to kratší zápis a
>>> dovoluje přetížení funkce. Ale možná má nějakou nevýhodu, na kterou
>>> jsem nepřišel.
>>>
>>> Martin Záruba
>>> Dne 19.4.2024 v 20:50 Pavel Hudeček napsal(a):
>>>> Moc pěkný.
>>>> Já bych teda akorát nekopíroval celý text do velkého bufferu a
>>>> místo toho text před číslem rovnou odesílal v prvním do/while, pak
>>>> převed a odeslal číslo a nakonec odeslal zbytek vstupního textu.
>>>>
>>>> Už jsem taky kdysi použil variantu, kdy se zadávají parametry
>>>> (text, val, mist) a v textu je pak znak pro umístění čísla a des.
>>>> míst se odešle podle hodnoty mist. Častějc mám ale (txtPred, val,
>>>> mist, txtPo).
>>>>
>>>> Odesílání mám teda téměř vždy rovnou průběžně po znacích a
>>>> odesílací funkce čeká jen na dokončení předchozího znaku, takže
>>>> konverze na výstupní text probíhá paralelně s odesíláním.
>>>>
>>>> PH
>>>>
>>>> Dne 19.04.2024 v 19:23 Martin Záruba napsal(a):
>>>>> Už jsem se Vás dost natrápil na toto téma a měl jsem pocit, že nic
>>>>> moc úsporného a jednoduše použitelného není. Jenže jsem paličatý a
>>>>> zkusil jsem přece něco vymyslet. Požadavek byl:
>>>>>
>>>>> Výpis na požadovaný počet míst s možností textu před i za číslem.
>>>>>
>>>>> Potlačení nevýznamných nul.
>>>>>
>>>>> Co nejúspornější kód jak funkce, tak volání, vhodný pro malinky
>>>>> procesor.
>>>>>
>>>>> Přímý tisk bez nutnosti psaní Serial.print();
>>>>>
>>>>> Vyrobil jsem toto, posuďte a navrhněte prosím co by ještě šlo líp.
>>>>>
>>>>>
>>>>> void pr(int32_t h, const char* f) {
>>>>> char buf[100];
>>>>> uint8_t i = 0xFF;
>>>>> int32_t x = abs(h);
>>>>> do {
>>>>> i++;
>>>>> buf[i] = f[i];
>>>>> } while (f[i] != 0);
>>>>>
>>>>> do {
>>>>> i--;
>>>>> if (buf[i] == '#') {
>>>>> if (x != 0) {
>>>>> buf[i] = x % 10 + (uint8_t)'0';
>>>>> if (h < 0 && x < 10) {
>>>>> i--;
>>>>> buf[i] = '-';
>>>>> }
>>>>> } else {
>>>>> buf[i] = ' ';
>>>>> }
>>>>> x /= 10;
>>>>> }
>>>>> } while (i != 0);
>>>>> Serial.print(buf);
>>>>> }
>>>>>
>>>>>
>>>>> Funkce má jediný formátovací znak #
>>>>>
>>>>> Příklady:
>>>>>
>>>>> int32_t napetimV = 5432;
>>>>> pr(napetimV, "Pokus1=###.###V\n");
>>>>> pr(-21, "Pokus2=### zaporne cislo\n");
>>>>> pr(9876543, "Pokus3=# ### ### cislo s mezerami po 1000\n");
>>>>> float a = 54.3;
>>>>> pr(a*10, "Pokus4=####.# vypis float na 1 desetinne misto\n");
>>>>>
>>>>> Výsledek vypadá takto:
>>>>>
>>>>> Pokus1= 5.432V
>>>>> Pokus2=-21 zaporne cislo
>>>>> Pokus3=9 876 543 cislo s mezerami po 1000
>>>>> Pokus4= 54.3 vypis float na 1 desetinne misto
>>
>>
>> _______________________________________________
>> HW-list mailing list - sponsored bywww.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>
> _______________________________________________
> HW-list mailing list - sponsored bywww.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20240420/3ce142a9/attachment.htm>
Další informace o konferenci Hw-list