Formatovany tisk pro 8bit

Martin Záruba swz na volny.cz
Sobota Duben 20 11:27:38 CEST 2024


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
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20240420/8f3599b0/attachment.htm>


Další informace o konferenci Hw-list