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