<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Jsem zvyklĂ˝ spĂš pouĹľĂvat float a teprve kdyĹľ nenĂ mĂsto, se floatu
zbavit za cenu zesložitěnà programu. Třeba na ATtiny416 je float
skoro nereálnej, na ATmega32, nebo AVR64DD32 s nĂm nenĂ problĂ©m. Ono
to hodnÄ› nabÄ›hne prvnĂm pouĹľitĂm, ale pak uĹľ moc nepĹ™ibĂ˝vá. A
pĹ™ehlednost vĂ˝poÄŤtĹŻ se dramaticky zlepšĂ.<br>
<br>
A ano, pĹ™i zobrazovánĂ ÄŤi odesĂlánĂ postupnÄ› dÄ›lĂm deseti, to snad
ani jinak nejde:-)<br>
Tzn. z mist se udÄ›lá násobitel, napĹ™. ze 2 je 100, tĂm se floatovĂ˝
vstup vynásobà a předhodà se funkci cislo(long). Ale důležitý je, že
se to stane aĹľ v uartSend.<br>
<br>
Pro mÄ› je dĹŻleĹľitĂ©, Ĺľe mezi změřenĂm a odeslánĂm jsou floatovĂ©
vĂ˝poÄŤty. KdyĹľ se vejdou, zmizĂ veškerĂ© starosti s pĹ™etĂ˝kánĂm, co
nastávajĂ pĹ™i celoÄŤĂselnĂ˝ch vĂ˝poÄŤtech a snaze o zachovánĂ pĹ™esnosti.<br>
takže pak máme třeba:<br>
<br>
#define AD_samples (1024.0)<br>
#define AD_uInDiv  (1 + 110.0/10.0)<br>
#define AD_uOutDiv (1 + 110.0/22.0)<br>
#define AD_ref      (4.096)<br>
...<br>
<br>
kde ve funkci cekej je:<br>
<br>
if (adSync==1) {<br>
   adSync=0;<br>
   adUin = (adData[AD_first] - offset) * násobitel<br>
   ...<br>
přičemž offset a násobitel jsou z těch definů, nebo z EEPROM float
eCalConst..., kde je výchozà hodnota z těch definů.<br>
A zajĂmavÄ›jšà je, kdyĹľ je vĂ˝stup tĹ™eba teplota z termistoru s
charakteristikou B3950, nebo konduktometr, kde je ale z EMC a
dalšĂch dĹŻvodĹŻ na vstupu ještÄ› sĂ©riovej a paralaelnĂ R.<br>
<br>
Tabulky mĂvám na grafickĂ©m displeji, na to je pak tab(x), která
posune přÚtà psanà na požadovanou pozici, font je třeba i
proporcionálnĂ. Nebo jsem mÄ›l pole dispTabs, kde byly začátky na
kterĂ˝ skoÄŤĂ \t. A to se dá zrovna celkem dobĹ™e pouĹľĂt i na sĂ©riáku,
dělá to pak až putchar2, když mu přijde \t a on và kolik bylo od
poslednĂho \n.<br>
Ale vizuálnĂ tabulky na sĂ©riáku moc nemĂvám, vÄ›tšinou max. takovĂ˝
napůl, kde se jen normálně použije \t. Až když to začne vadit,
přidám uartTabs[].<br>
<br>
PH<br>
<br>
<div class="moz-cite-prefix">Dne 20.04.2024 v 14:01 Martin Záruba
napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:07035d67-bd13-4ca5-8b45-c6fcaf944dee@volny.cz">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<p><font face="Arial">Nojo, jenĹľe pak s tĂm neudÄ›láte tabulku. Je
potĹ™eba, aby napĹ™Ăklad pokud je hodnota 3753, napsalo to
|3753mV| ale pokud je 53, napsalo to |Â 53mV| a ne |53mV|.
Tedy aby celĂ˝ Ĺ™etÄ›zec (vÄŤetnÄ› toho mV) byl stále (napĹ™Ăklad) 6
znakĹŻ.<br>
</font></p>
<p><font face="Arial">Zkusil jste, kolik to zabere paměti? Podle
toho, co pĂšete to dÄ›lá pĹ™evod na float. To ale na osmibitu je
hrĹŻza. Já si hraju jen s "grafikou". ÄŚĂslo stále dÄ›lĂm deseti,
to je i na osmibitu snadnĂ©. A vypisuji zbytek po dÄ›lenĂ. No a
nÄ›kam vrazĂm jakoukoli "vĂ˝plĹ", tĹ™eba tu teÄŤku. Pak to vypadá
jako desetinnĂ© ÄŤĂslo, kterĂ© ale je v celoÄŤĂselnĂ©m formátu
uloĹľeno tĹ™eba 10x 100x nebo jak se chce vÄ›tšĂ, coĹľ je myslĂm
ten nejefektivnějšà způsob, jak na malinkém procesoru zobrazit
desetinnĂ© ÄŤĂslo.</font></p>
<p><font face="Arial">Zkoušel jsem takĂ© pouĹľĂt ultoa(). Ale je to
vÄ›tšà a stejnÄ› musĂte vĂ˝sledek formátovat.</font></p>
<p><font face="Arial">Napadlo mě ještě nejprve prvnà smyčkou
zjistit délku masky a pak nadefinovat pole buf pomocà malloc.
A na konci ho uvolnit. Pak by většinou bylo malinké. Co si
myslĂte o tomto nápadu? <br>
</font></p>
<pre class="moz-signature" cols="72">Martin Záruba</pre>
<div class="moz-cite-prefix">Dne 20.4.2024 v 12:29 Pavel HudeÄŤek
napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:674463bf-438e-4e67-88aa-34cf0e2f0c10@seznam.cz">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
Ne, v mĂ©m pĹ™Ăkladu je pĹ™eci stav uBat1=3753,
tak uartSend("\1mV", adUbat1, 0); vypĂše 3753mV<br>
Pokud by adUbat bylo 53, vypĂše 53mV<br>
a pokud by bylo zadáno uartSend("\1mV", adUbat1, 3);<br>
vyleze 3753,000mV<br>
nebo třeba 3753,001, pokud float hodnota nevyšla přesně 3753,000<br>
<br>
Nějak tak to fungovalo, už je to dlouho.<br>
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Ă.<br>
<br>
PH<br>
<br>
<div class="moz-cite-prefix">Dne 20.04.2024 v 11:27 Martin
Záruba napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:62da3616-1d24-431d-9cf0-0c397e03b07f@volny.cz">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<p><font face="Arial">Jen dotaz: Co vypĂše:</font></p>
<p><font face="Arial">uBat1 je 53</font></p>
<p><font face="Arial">uartSend("\1mV",adUbat1,0);<br>
</font></p>
<p><font face="Arial">nevypĂše to</font></p>
<p><font face="Arial">53mVÂ Â Â Â Â ?</font></p>
<pre class="moz-signature" cols="72">Martin Záruba</pre>
<div class="moz-cite-prefix">Dne 20.4.2024 v 10:36 Pavel
HudeÄŤek napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:cafe8589-63d8-448f-9f19-eb19f16669d4@seznam.cz">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
Tady asi došlo k mĂrnĂ©mu nedorozumÄ›nĂ:<br>
Oba umĂme zobrazit jen jednu hodnotu.<br>
Oba umĂme poĹľadovanĂ˝ poÄŤet des. mĂst.<br>
Oba umĂme text pĹ™ed nĂm i po nÄ›m.<br>
Já nemám formátovánĂ tisĂcĹŻ, ale zas mĹŻĹľu ve vĂ˝stupnĂm textu
pouĹľĂt #.<br>
Zas to formátovánàs # se asi dá ohackovat, že zobrazà třeba
2 ÄŤĂsla zakĂłdovanĂ˝ do jednoho longu?<br>
<br>
// adUin je 12,3456Â uBat1 je 3753<br>
// UART_sendDT je ','Â UART_sendPosChr je '\1'<br>
uartSend("Uin=\1 V\n", adUin, 2);<br>
uartSend("\1mV", adUbat1, 0);<br>
výsledek je:<br>
Uin=12,34 V<br>
3753mV<br>
<br>
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.<br>
<br>
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.<br>
takĹľe poslednÄ› to bylo ve stylu<br>
text("Uin="); cislo(static_cast<long>(1000.0*adUin));
text(" mV\r\n");<br>
<br>
Buffer je na zásobnĂku, takĹľe sám vznikne a sám zmizĂ.<br>
Ale 100 B, to je 20 % RAMky na ATtiny816, coĹľ je hodnÄ›,
pĹ™ĂpadnÄ› 1,25 % na AVR64DD32, to uĹľ by bylo v pohodÄ›.<br>
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..<br>
Takže mám snahu takové buffery nedělat.<br>
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.<br>
<br>
Ovšem to s F a PSTR je pro mÄ› novinka, za to dĂky.<br>
<br>
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.<br>
A v pĹ™ĂpadÄ› GCC jsem si myslel, Ĺľe nic uĹľ takhle elegantnÄ›
nepĹŻjde.<br>
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.<br>
Tak aspoĹ snad zas mĹŻĹľu mĂt texty ve flash:-)<br>
<br>
PH<br>
<br>
<div class="moz-cite-prefix">Dne 19.04.2024 v 21:23 Martin
Záruba napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:ab12d61f-7c9b-4434-9138-43db4d9875b4@volny.cz">
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<p><font face="Arial">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?</font></p>
<p><font face="Arial">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.<br>
</font></p>
<pre class="moz-signature" cols="72">Martin Záruba</pre>
<div class="moz-cite-prefix">Dne 19.4.2024 v 20:50 Pavel
HudeÄŤek napsal(a):<br>
</div>
<blockquote type="cite"
cite="mid:b4bb63a0-c0e8-4e00-bb0f-836ae08e652c@seznam.cz">Moc pěkný. <br>
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. <br>
<br>
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). <br>
<br>
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. <br>
<br>
PH <br>
<br>
Dne 19.04.2024 v 19:23 Martin Záruba napsal(a): <br>
<blockquote type="cite">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: <br>
<br>
VĂ˝pis na poĹľadovanĂ˝ poÄŤet mĂst s moĹľnostĂ textu pĹ™ed i
za ÄŤĂslem. <br>
<br>
Potlačenà nevýznamných nul. <br>
<br>
Co nejĂşspornÄ›jšà kĂłd jak funkce, tak volánĂ, vhodnĂ˝
pro malinky procesor. <br>
<br>
PĹ™ĂmĂ˝ tisk bez nutnosti psanĂ Serial.print(); <br>
<br>
Vyrobil jsem toto, posuÄŹte a navrhnÄ›te prosĂm co by
ještÄ› šlo lĂp. <br>
<br>
<br>
void pr(int32_t h, const char* f) { <br>
 char buf[100]; <br>
 uint8_t i = 0xFF; <br>
 int32_t x = abs(h); <br>
 do { <br>
   i++; <br>
   buf[i] = f[i]; <br>
 } while (f[i] != 0); <br>
<br>
 do { <br>
   i--; <br>
   if (buf[i] == '#') { <br>
     if (x != 0) { <br>
       buf[i] = x % 10 + (uint8_t)'0'; <br>
       if (h < 0 && x < 10) { <br>
         i--; <br>
         buf[i] = '-'; <br>
       } <br>
     } else { <br>
       buf[i] = ' '; <br>
     } <br>
     x /= 10; <br>
   } <br>
 } while (i != 0); <br>
 Serial.print(buf); <br>
} <br>
<br>
<br>
Funkce má jediný formátovacà znak # <br>
<br>
PĹ™Ăklady: <br>
<br>
int32_t napetimV = 5432; <br>
pr(napetimV, "Pokus1=###.###V\n"); <br>
pr(-21, Â Â Â "Pokus2=### zaporne cislo\n"); <br>
pr(9876543, "Pokus3=# ### ### cislo s mezerami po
1000\n"); <br>
float a = 54.3; <br>
pr(a*10,    "Pokus4=####.# vypis float na 1 desetinne
misto\n"); <br>
<br>
Výsledek vypadá takto: <br>
<br>
Pokus1=Â 5.432V <br>
Pokus2=-21 zaporne cislo <br>
Pokus3=9 876 543 cislo s mezerami po 1000 <br>
Pokus4=Â Â 54.3 vypis float na 1 desetinne misto <span
style="white-space: pre-wrap">
</span></blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</blockquote>
</body>
</html>