<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    A ještě jsem voliteně přidal ty taby:<br>
    <br>
    putcharTabsPoss[0] = 8;<br>
    putcharTabsPoss[1] = 16;<br>
    putcharTabsPoss[2] = 24;<br>
    <br>
    uartSendF(F("tt \t1 \t2 \t 3\r\n"));<br>
    uartSendF(F("ttt \t1111 \t2222 \t333333\r\n"));<br>
    uartSendF(F("ttt \t1111111 \t2222222 \t333333333\n\n\r\n"));<br>
            <br>
    putcharTabsPoss[0] = 10;<br>
    putcharTabsPoss[1] = 20;<br>
    putcharTabsPoss[2] = 30;<br>
            <br>
    uartSendF(F("tt \t1 \t2 \t3\r\n"));<br>
    uartSendF(F("ttt \t1111 \t2222 \t333333\r\n"));<br>
    uartSendF(F("ttt \t1111111 \t2222222 \t333333333\n\n\r\n"));<br>
    <br>
    výsledek je:<br>
    <font face="monospace">tt     1       2        3<br>
      ttt    1111    2222    333333<br>
      ttt    1111111         2222222 333333333<br>
      <br>
      tt       1         2         3<br>
      ttt      1111      2222      333333<br>
      ttt      1111111   2222222   333333333</font><br>
    <br>
    a takhle vypadá putchar a související:<br>
    <br>
    ------------------------<br>
    <font face="monospace">#</font><font face="monospace">define
      UART_sendTabExt    3<br>
      <br>
      #ifndef UART_sendTabExt    // >0 Použít tabulku zadané
      velikosti, s pozicema pro \t v putcharu<br>
      #define UART_sendTabExt    0<br>
      #endif<br>
      <br>
      #if (UART_sendTabExt==0)<br>
      void putchar2(char c) { //
      ===============================================================<br>
          #if (UART_num == 1) // 0 DPS / 1 kit<br>
          while ((USART1.STATUS & USART_DREIF_bm) == 0);<br>
          USART1.TXDATAL=c;<br>
          #else<br>
          while ((USART0.STATUS & USART_DREIF_bm) == 0);<br>
          USART0.TXDATAL=c;<br>
          #endif<br>
      }<br>
      #else //(UART_sendTabExt==0)<br>
      <br>
      #ifndef putcharTabsPoss<br>
      uint8_t putcharTabsPoss[UART_sendTabExt];<br>
      #endif<br>
      <br>
      void putchar2(char c) { // ==============================<br>
          static volatile uint8_t lastPos = 0;<br>
          <br>
          <br>
          if (c=='\n' || c=='\r') lastPos=0;<br>
          else if (c=='\t') {<br>
              uint8_t n;<br>
              for (n=0; n<UART_sendTabExt; n++) if
      (putcharTabsPoss[n]>lastPos) break;<br>
              if (n<UART_sendTabExt) {<br>
                  while (lastPos < putcharTabsPoss[n]) putchar2(' ');<br>
              }<br>
              return;<br>
          }<br>
          <br>
          #if (UART_num == 1) // 0 DPS / 1 kit<br>
          while ((USART1.STATUS & USART_DREIF_bm) == 0);<br>
          USART1.TXDATAL=c;<br>
          if (c=='\n' || c=='\r') lastPos=0;<br>
          #else // (UART_num == 1)<br>
          while ((USART0.STATUS & USART_DREIF_bm) == 0);<br>
          USART0.TXDATAL=c;<br>
          #endif // (UART_num == 1)<br>
          lastPos++;<br>
      }<br>
      <br>
      #endif //(UART_sendTabExt==0)</font><br>
    ----------------------<br>
    <br>
    Poznámka:<br>
    Zajímavé je, že na PORTA, PORTB, ... funguje define, ale USART0,
    USART1, ... přes define nefunguje, tak je tam vopičárna s <font
      face="monospace">UART_num.<br>
      <br>
      PH<br>
    </font><br>
    <div class="moz-cite-prefix">Dne 21.04.2024 v 11:24 Pavel Hudeček
      napsal(a):<br>
    </div>
    <blockquote type="cite"
      cite="mid:ba85baab-6331-4641-9242-c4c584f3e3c3@seznam.cz">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      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ý.<br>
      <br>
      Nějakou dobu to vypadalo, že v něm správně nefunguje ani přetížení
      funkcí<br>
      <font face="monospace">uartSendF(F("long  \1---\r\n"), 123456L,
        2);<br>
        uartSendF(F("float \1---\r\n"), 98765.4321, 2);</font><br>
      funkce deklarována pro long a float<br>
      u řádku s 98765.4321 error, že overload je ambignous<br>
      <br>
      Takže následovala laborace s templaty a detekcí typu<br>
      <font face="monospace">//#include <type_traits><br>
        //#include <typeinfo></font><br>
      File not found, takže normálně to nejde jedním ani druhým
      způsobem.<br>
      <br>
      Nakonec jsem vytvořil:<br>
      <font face="monospace">template <typename T> class clDetTyp
        {<br>
        public:<br>
            char det();<br>
        };<br>
        <br>
        template <> char clDetTyp<unsigned int>::det() {<br>
            return 'u';<br>
        }<br>
        template <> char clDetTyp<int>::det() {<br>
            return 'i';<br>
        }<br>
        template <> char clDetTyp<long>::det() {<br>
            return 'l';<br>
        }<br>
        template <> char clDetTyp<float>::det() {<br>
            return 'f';<br>
        }<br>
        template <> char clDetTyp<double>::det() {<br>
            return 'd';<br>
        }</font><br>
      <br>
      a použil:<br>
      <br>
      <font face="monospace">template<typename T><br>
        void uartSendF(const char *t, T val, uint8_t mist) {<br>
            clDetTyp<T> d;<br>
            if (d.det()=='f' ...</font><br>
      <br>
      To funguje.<br>
      Ale vedlejším produktem je zjištění, že <b>když napíšu 123.456
        není to float, ale double</b>:-)<br>
      A teda ten "double" má sizeof 4 stejně jako float, což je na 8bitu
      očekávané.<br>
      Ale WTF proč z des. čísla dělá "double" a ne float?<br>
      <br>
      Takže zpátky na stromy: <b>Funguje i normální overload</b>:-)<br>
      avr-g++ teda není až takovej krám<br>
      <br>
      <font face="monospace">uartSendF(F("long  \1---\r\n"), 123456L,
        2);<br>
        uartSendF(F("float \1---\r\n"), 98765.4321, 2);<br>
        uartSendF(F("text  \1---\r\n"), "blabla");<br>
        uartSendF(F("textF blablabla\r\n"));<br>
        uartSend("textR blablabla\r\n");<br>
      </font><br>
      Teď normálně vyplivne:<br>
      <font face="monospace">long  1234,56---<br>
        float 98765,43---<br>
        text  blabla---<br>
        textF blablabla<br>
        textR blablabla</font><br>
      <br>
      Jen je škoda, že ten <b>PSTR </b>(kterej jsem si předefinoval na
      F) <b>se nedá rozpoznat</b>, takže mám uartSend na texty v RAM a
      uartSendF na flash.<br>
      <span style="white-space: pre-wrap">
------------------------
<font face="monospace">#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);
}</font>
----------------------------------

</span><span style="white-space: pre-wrap"><font face="monospace">cisloDT </font></span><span
      style="white-space: pre-wrap">přejmenuju taky na uartSend.
</span><span style="white-space: pre-wrap"><font face="monospace">uartSendF_</font></span><span
      style="white-space: pre-wrap"> přejmenuju na </span><span
      style="white-space: pre-wrap"><font face="monospace">uartSendF.</font></span><br>
      <span style="white-space: pre-wrap">
Mám radši nechat ten template s detekcí typů, nebo udělat jen overloady?

PH



</span>
      <blockquote type="cite"
        cite="mid:b01b7f84-7e73-407b-b567-dbd0f77e05e7@seznam.cz">
        <blockquote type="cite"
          cite="mid:07035d67-bd13-4ca5-8b45-c6fcaf944dee@volny.cz">
          <blockquote type="cite"
            cite="mid:674463bf-438e-4e67-88aa-34cf0e2f0c10@seznam.cz">
            <blockquote type="cite"
              cite="mid:62da3616-1d24-431d-9cf0-0c397e03b07f@volny.cz">
              <blockquote type="cite"
cite="mid:cafe8589-63d8-448f-9f19-eb19f16669d4@seznam.cz">
                <blockquote type="cite"
cite="mid:ab12d61f-7c9b-4434-9138-43db4d9875b4@volny.cz">
                  <blockquote type="cite"
cite="mid:b4bb63a0-c0e8-4e00-bb0f-836ae08e652c@seznam.cz"> </blockquote>
                </blockquote>
              </blockquote>
            </blockquote>
          </blockquote>
        </blockquote>
      </blockquote>
      <span style="white-space: pre-wrap">
</span></blockquote>
    <br>
  </body>
</html>