Formatovany tisk pro 8bit

Pavel Hudeček edizon na seznam.cz
Neděle Duben 21 11:24:04 CEST 2024


Tak jsem si s tím pohrál, podařilo se, ale byl to porod, protože avr-g++ 
je asi nějaký nedodělaný.

Nějakou dobu to vypadalo, že v něm správně nefunguje ani přetížení funkcí
uartSendF(F("long  \1---\r\n"), 123456L, 2);
uartSendF(F("float \1---\r\n"), 98765.4321, 2);
funkce deklarována pro long a float
u řádku s 98765.4321 error, že overload je ambignous

Takže následovala laborace s templaty a detekcí typu
//#include <type_traits>
//#include <typeinfo>
File not found, takže normálně to nejde jedním ani druhým způsobem.

Nakonec jsem vytvořil:
template <typename T> class clDetTyp {
public:
     char det();
};

template <> char clDetTyp<unsigned int>::det() {
     return 'u';
}
template <> char clDetTyp<int>::det() {
     return 'i';
}
template <> char clDetTyp<long>::det() {
     return 'l';
}
template <> char clDetTyp<float>::det() {
     return 'f';
}
template <> char clDetTyp<double>::det() {
     return 'd';
}

a použil:

template<typename T>
void uartSendF(const char *t, T val, uint8_t mist) {
     clDetTyp<T> d;
     if (d.det()=='f' ...

To funguje.
Ale vedlejším produktem je zjištění, že *když napíšu 123.456 není to 
float, ale double*:-)
A teda ten "double" má sizeof 4 stejně jako float, což je na 8bitu 
očekávané.
Ale WTF proč z des. čísla dělá "double" a ne float?

Takže zpátky na stromy: *Funguje i normální overload*:-)
avr-g++ teda není až takovej krám

uartSendF(F("long  \1---\r\n"), 123456L, 2);
uartSendF(F("float \1---\r\n"), 98765.4321, 2);
uartSendF(F("text  \1---\r\n"), "blabla");
uartSendF(F("textF blablabla\r\n"));
uartSend("textR blablabla\r\n");

Teď normálně vyplivne:
long  1234,56---
float 98765,43---
text  blabla---
textF blablabla
textR blablabla

Jen je škoda, že ten *PSTR *(kterej jsem si předefinoval na F) *se nedá 
rozpoznat*, takže mám uartSend na texty v RAM a uartSendF na flash.
------------------------ #include <avr/pgmspace.h> #define UART_sendDT 
',' #define UART_sendPosChr 1 #define F PSTR // Poslat číslo na sériák, 
na konci oddělit mist desetinným oddělovačem void cisloDT(long x, 
uint8_t mist) { // ================================================= 
char t[10]; uint8_t n; if (x==0) {putchar2('0'); return;} for (n=0; n<10 
&& x>0; n++) { t[n]=x % 10 + '0'; x/=10; } //uint8_t dp = n-1-mist; for 
(n-=1; n<255; n--) { if (mist>0 && n==mist-1) putchar2(UART_sendDT); 
putchar2(t[n]); } } // Poslat char* na sériák void uartSend(char *c) { 
// ========================================= for (signed char n=0; 
c[n]!=0; n++) putchar2(c[n]); } // Poslat PSTR na sériák void 
uartSendF(const char *t) { // ---------------------------------- char c; 
for (signed char n=0; (c=pgm_read_byte(&t[n]))!=0; n++) putchar2(c); } 
// Poslat na sériák PSTR s vloženým char* void uartSendF(const char 
*tFlash, char *tRam) { // ----------------- char c; for (char n=0; 
n<255; n++) { c = pgm_read_byte(&tFlash[n]); if (c==0) break; else if 
(c==UART_sendPosChr) uartSend(tRam); else putchar2(c); } } // Poslat na 
sériák PSTR s vloženým cisloDT void uartSendF_(const char *t, long val, 
uint8_t mist) { // --------- char c; for (char n=0; n<255; n++) { c = 
pgm_read_byte(&t[n]); if (c==0) break; else if (c==UART_sendPosChr) 
cisloDT(val, mist); else putchar2(c); } } // post-test overload - taky 
funguje void uartSendFt(const char *t, float val, uint8_t mist) { float 
m = 1.0; for (uint8_t n=0; n<mist; n++) m*=10.0; uartSendF_(t, 
static_cast<long>(val*m), mist); } void uartSendFt(const char *t, double 
val, uint8_t mist) { float m = 1.0; for (uint8_t n=0; n<mist; n++) 
m*=10.0; uartSendF_(t, static_cast<long>(val*m), mist); } void 
uartSendFt(const char *t, long val, uint8_t mist) { uartSendF_(t, val, 
mist); } template <typename T> class clDetTyp { // 
=========================== public: char det(); }; template <> char 
clDetTyp<unsigned int>::det() { return 'u'; } template <> char 
clDetTyp<int>::det() { return 'i'; } template <> char 
clDetTyp<long>::det() { return 'l'; } template <> char 
clDetTyp<float>::det() { return 'f'; } template <> char 
clDetTyp<double>::det() { return 'd'; } template<typename T> void 
uartSendF(const char *t, T val, uint8_t mist) { // ============== 
clDetTyp<T> d; if (d.det()=='f' || d.det()=='d') { float m = 1.0; for 
(uint8_t n=0; n<mist; n++) m*=10.0; uartSendF_(t, 
static_cast<long>(val*m), mist); } else if (d.det()=='l') uartSendF_(t, 
val, mist); else uartSendF_(t, static_cast<long>(val), mist); } 
---------------------------------- cisloDT přejmenuju taky na uartSend. 
uartSendF_přejmenuju na uartSendF.
Mám radši nechat ten template s detekcí typů, nebo udělat jen overloady? PH
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20240421/43e8b53b/attachment.htm>


Další informace o konferenci Hw-list