IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Wemos : Formatage de nombres


Sujet :

Arduino

  1. #1
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut Wemos : Formatage de nombres
    Bonjour à tous

    toujours en rapport avec le post précédent , je dois afficher une température
    que j'élabore de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    int   raw_temp;
    char *temp = "000.000 C";
     
    ../..
     
    if(ds18b20_read(&raw_temp))
          {
            Serial.printf("Temperature = %8.4f°C\r\n", (float)raw_temp / 16);
     
            if(raw_temp & 0x8000)                         // Si la température est négative
            {
              temp[0] = '-';                              // Mettre le signe moins (-)
              raw_temp = ~raw_temp + 1;         // Changer la valeur de la température en forme positive
            }
            else
            {
              if((raw_temp >> 4) >= 100)          // Si la température >= 100 °C
                temp[0] = '1';                          // Mettre 1 parmi des centaines
              else                                         // autrement
                temp[0] = ' ';                          // mettre un espace ' '
            }
     
            // Mettre les deux premiers chiffres ( pour les dizaines et les uns)
            temp[1] = ( (raw_temp >> 4) / 10 ) % 10 + '0';      // Mettre le chiffre des dizaines
            temp[2] =   (raw_temp >> 4)        % 10 + '0';      // Mettre un chiffre
     
            // Mettre les 4 chiffres de la fraction (chiffres après le point)
            // Pourquoi 625 : parce que nous travaillons avec une résolution de 12 bits (résolution par défaut)
            temp[4] = ( (raw_temp & 0x0F) * 625) / 1000 +       '0';    // Mettre le chiffre des milliers
            temp[5] = (((raw_temp & 0x0F) * 625) / 100 ) % 10 + '0'; // Mettre le chiffre des centaines
            temp[6] = (((raw_temp & 0x0F) * 625) / 10 )  % 10 + '0';  // Mettre le chiffre des dizaines
            temp[7] = ( (raw_temp & 0x0F) * 625) % 10 +         '0';    // Mettre un chiffre
     
     
            updatePiscine();
     
          }
           else
          {
            Serial.println("Communication Error!");
          }
    Au final je souhaite afficher qu'un seul chiffre après la virgule ( char *temp = "000.0 C" )
    comment puis-je formater 'temp'
    svp ?

    Merci mille fois

  2. #2
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 633
    Points : 1 596
    Points
    1 596
    Par défaut
    Hello,

    Je suppose qu'il suffit de ne pas utiliser temp[de 5 à 7]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    int   raw_temp;
    char *temp = "000.0 C";
     
    ../..
     
    if(ds18b20_read(&raw_temp)) {
    	....
    	if(raw_temp & 0x8000) {
    		temp[0] = '-';
    		raw_temp = ~raw_temp + 1;
    	}
    	else {
    		if((raw_temp >> 4) >= 100)
    			temp[0] = '1';
    		else
    			temp[0] = ' ';
    	}
    	temp[1] = ( (raw_temp >> 4) / 10 ) % 10 + '0';
    	temp[2] =   (raw_temp >> 4)        % 10 + '0';
    	temp[4] = ( (raw_temp & 0x0F) * 625) / 1000 + '0';
     
    	updatePiscine();
    }
    	....
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  3. #3
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    Oui c'est logique
    je n'ai pas voulu le faire , pensant que j'allais perdre en précision mais comme il ne s'agit que d'affichage ...

    merci encore edgarjacobs

    PS : je recherche des conseils pour utiliser l'écran E-paper , objet de cette demande
    j'arrive à afficher maintenant la température mais je suis confronté à une même problématique
    celle d'afficher le % batterie issu de ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    int8_t batteryPercentage;
     
    ../..
     
     
     if (!isADCReady)
        {
            //adcValue = analogRead(A0); //<============
    		    adcValue = 950;  // <=== test
            //batteryVoltage = adcValue * 0.00410; // 4.2v / 1023 = 0.00410
    		    batteryPercentage = (int8_t)((adcValue - 740) / 2.83); // 1023 - 740 = 283 pour 0 - 100% soit 3.3v à 2,4v
     
            constexpr int seuilTensionBruteBasse = 930 ; // 3.0V ==> calculé par (3.0V * 1023) / 3.3V
            //int tensionBrute =analogRead(A0);
            int tensionBrute =adcValue; // <==== test
            if  (tensionBrute <= seuilTensionBruteBasse)
            {
                D_timestamp();
                D_println("Batterie faible. Sommeil profond.");
                D_printf("Battery Percentage: %i", batteryPercentage);
                ESP.deepSleep(0);
            }
     
            D_timestamp();
            D_println("ADC Reading ready");
            D_timestamp();
            D_printf("Battery Percentage: %i", batteryPercentage);
            D_println();
     
            bat =int8_t(&batteryPercentage);
     
            updateBattery() ;
            delay(1000);
            //isADCReady = true;
        }
     
    **/**
     
    void updateBattery() 
    {
    int16_t tbx, tPar;
    uint16_t tbw, tbh;
    display.setRotation(3);
    //display.mirror(false);
     
    uint16_t x = 32;
    uint16_t y = 24;
    display.getTextBounds(bat, x, y, &tbx, &tPar, &tbw, &tbh);  //<================
     
    display.setFont(&FreeMonoBold9pt7b);
    display.setTextColor(GxEPD_BLACK);
     
    display.setPartialWindow(tbx, tPar, tbw, tbh);
     
      //display.firstPage();
      do {
        display.fillScreen(GxEPD_WHITE);
        display.setCursor(x, y);
        display.print(bat);                //   <==================
      } while (display.nextPage());
       
    }
    comment faire pour transformer le % batteryPercentage en chaine de caractères pour permettre l'affichage
    il attend : const char * string //<=========================== pour la variable bat (?)

  4. #4
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 633
    Points : 1 596
    Points
    1 596
    Par défaut
    Question précision, tu peux toujours affiner les 10èmes de degré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp[4] = ( (raw_temp & 0x0f) * 625) / 1000 + ((((raw_temp & 0x0F) * 625) / 100 ) % 10 >=5 ? 1 : 0) + '0';
    Pour ton problème de % de batterie, je ne suis pas compétent.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  5. #5
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 647
    Points : 56 973
    Points
    56 973
    Billets dans le blog
    40
    Par défaut
    Bonsoir,

    Citation Envoyé par cobra38 Voir le message
    comment faire pour transformer le % batteryPercentage en chaine de caractères pour permettre l'affichage
    il attend : const char * string //<=========================== pour la variable bat (?)
    avec sprintf peut-être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char bat[10];
      sprintf(bat, "%d", batteryPercentage);

  6. #6
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    Citation Envoyé par edgarjacobs Voir le message
    Question précision, tu peux toujours affiner les 10èmes de degré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    temp[4] = ( (raw_temp & 0x0f) * 625) / 1000 + ((((raw_temp & 0x0F) * 625) / 100 ) % 10 >=5 ? 1 : 0) + '0';
    Pour ton problème de % de batterie, je ne suis pas compétent.
    Grand merci edgarjacobs
    je prends ...

    Bon WE
    pascal

  7. #7
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    Citation Envoyé par f-leb Voir le message
    Bonsoir,

    avec sprintf peut-être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char bat[10];
      sprintf(bat, "%d", batteryPercentage);
    Bonsoir f-leb
    merci pour l'info
    mais pourquoi : bat[10] , je n'ai besoin que 3 caractères

    pour essayer, j'ai fait cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    int   raw_bat;
    char *bat ="000%"; 
     
    ../..
     
    if((batteryPercentage) >= 100) 
      {                                            
          bat[0] = '1';                            // Put 1 of hundreds
      }else{                                       // otherwise
          bat[0] = ' ';                            // put space ' '
      }  
      // Put the first two digits ( for tens and ones)
       bat[1] = ( (batteryPercentage) / 10 ) % 10 + '0' ;      // Put tens digit
       bat[2] =  (batteryPercentage)        % 10 + '0'  ;      // Put ones digit
    c'est beaucoup moins élégant mais çà l'air de fonctionner mais ce n'est peut-être pas la bonne méthode
    je suis un peu perdu dans les conversions , c'est difficile pour un débutant
    y aurait-il des moyens mémo-techniques pour apprendre plus facilement les principes ?

  8. #8
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 647
    Points : 56 973
    Points
    56 973
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    mais pourquoi : bat[10] , je n'ai besoin que 3 caractères
    J'ai mis 10 au pif, tu adaptes en fonction du besoin...


    sprintf dispose de nombreuses options de formatage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf(bat, "%3d%s", batteryPercentage, "%");
    va aussi rajouter des espaces devant pour occuper 3 caractères au minimum.

  9. #9
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 633
    Points : 1 596
    Points
    1 596
    Par défaut
    sprintf(bat, "%3d%s", batteryPercentage, "%");

    Je préfère de loin sprintf(bat, "%3d%%", batteryPercentage);

    Edit: cobra38 a écrit
    Bon WE
    pascal
    Ha ben oui, c'est le moment (le dimanche 31.03.2024 est le dimanche Pascal)
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  10. #10
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 775
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 775
    Points : 5 577
    Points
    5 577
    Par défaut
    Sur quel Arduino etes vous ?

  11. #11
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    Bonjour edgarjacobs
    Bien vu !!

    Bonjour Jay M
    Sur quel Arduino êtes vous ?
    Sur un ESP8266 Wemos D1 et Arduino IDE 2.3.2

    Bonjour f-leb
    sprintf dispose de nombreuses options de formatage :
    çà reste pour moi complexe mais j'ai bien noté

    D'une façon générale et au vu des posts précédents vous avez du comprendre, j'expérimente un écran E-paper
    la façon de travailler est différente des autres écrans comme le SSD1306 et elle est plus compliquée
    Je ne trouve pas beaucoup de solutions sur le net entre autre sur la gestion des rafraichissements partiels d'écran
    Si quelqu'un a de l'expérience sur ce type de produit , je suis preneur car je galère

    merci encore
    Bon dimanche à tous
    pascal

  12. #12
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 775
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 775
    Points : 5 577
    Points
    5 577
    Par défaut
    l'ESP8266 supporte avec printf() et ses variantes la gestion d'un nombre a virgule flottante (float, double)

    Si vous avez besoin d'une c-string pour votre affichage, le plus simple est d'utiliser effectivement snprintf() (plutôt que sprintf() pour ne pas déborder la mémoire prévue)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    float x = 123.45678;
    char petitBuffer[10]; // on prévoit de la place pour 9 caractères et le caractère null obligatoire pour une cString
     
    void setup() {
      Serial.begin(115200);
     
      // on remplit petitBuffer avec la version textuelle de la valeur de x avec 1 chiffre après la virgule
      snprintf(petitBuffer, sizeof petitBuffer, "%.1f", x); // le .1 dit que l'on veut 1 chiffre après la virgule cf  https://cplusplus.com/reference/cstdio/snprintf/
     
      // ici vous pouvez utiliser petitBuffer comme un pointeur char* qui contient "123.5"  (printf gère l'arrondi)
      Serial.println(petitBuffer);
    }
     
    void loop() {}


    ----

    Notez que vous n'avez pas le droit de faire

    car vous allouez ) un pointeur vers un contenu variable le contenu d'un pointeur à contenu constant. Certain micros contrôleurs vont placer "000%" en mémoire non modifiable donc vous ne pouvez pas utiliser cette approche. (le compilateur donne un warning sans doute)

  13. #13
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    RE..

    Merci Jay M

    Pour afficher sur l'ecran E-paper la valeur de la température DB18B20 je procède comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    display.getTextBounds(temp, x, y, &tbx, &tPar, &tbw, &tbh);  //<===== variable temp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    int   raw_temp;
    char *temp = "000.0";
     
    --/--
     
    if(ds18b20_read(&raw_temp))
          {
            Serial.printf("Temperature = %8.4f°C\r\n", (float)raw_temp / 16);
     
            if(raw_temp & 0x8000)                      // Si la température est négative
            {
              temp[0] = '-';                               // Mettre le signe moins (-)
              raw_temp = ~raw_temp + 1;           // Changer la valeur de la température en forme positive
            }
            else
            {
              if((raw_temp >> 4) >= 100)            // Si la température >= 100 °C
                temp[0] = '1';                            // Mettre 1 parmi des centaines
              else                                           // autrement
                temp[0] = ' ';                            // mettre un espace ' '
            }
     
            // Mettre les deux premiers chiffres ( pour les dizaines et les uns)
            temp[1] = ( (raw_temp >> 4) / 10 ) % 10 + '0';      // Put tens digit
            temp[2] =   (raw_temp >> 4)        % 10 + '0';      // Put ones digit
            // Mettre les chiffres de la fraction 1 (chiffres après le point)
            // Pourquoi 625 : parce que nous travaillons avec une résolution de 12 bits (résolution par défaut).
            temp[4] = ( (raw_temp & 0x0F) * 625) / 1000 +       '0';    // Put thousands digit
     
          }
    je pourrais donc remplacer tout çà par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int   raw_temp;
    char temp[10];
     
    --/--
    if(ds18b20_read(&raw_temp))
    {
    Serial.printf("Temperature = %8.4f°C\r\n", (float)raw_temp / 16);
    snprintf(temp, sizeof temp, "%.1f",(float)raw_temp / 16);
    }
    çà a l'air de fonctionner
    mais que signifie l'expression : "Temperature = %8.4f°C\r\n"
    Images attachées Images attachées  

  14. #14
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 633
    Points : 1 596
    Points
    1 596
    Par défaut
    "%8.4f" signifie: afficher un float sur 8 caractères, dont 1 pour le point décimal et avec 4 caractères dans la partie décimale. Ce qui laisse donc 3 caractères pour la partie entière.
    A noter que si la partie entière prend plus de 3 caractères, elle ne sera pas tronquée, et que la partie décimale peut etre arrondie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
     
    int main(void) {
    	printf("%8.4f\n",20/2.);
    	printf("%8.4f\n",20/3.);
    	printf("%8.4f\n",20/6.);
    	printf("%8.4f\n",455/3.);
    	printf("%8.4f\n",3000/2.);
     
    	return(0);
    }
    Nom : 0054.png
Affichages : 41
Taille : 891 octets
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  15. #15
    Membre actif
    Inscrit en
    Juillet 2004
    Messages
    797
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 797
    Points : 230
    Points
    230
    Par défaut
    Mille mercis edgarjacobs

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XSL-FO] formatage de nombre
    Par qouify dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 16/05/2006, 13h58
  2. [PHP-JS] Formatage de nombre
    Par goldorax113 dans le forum Langage
    Réponses: 5
    Dernier message: 08/05/2006, 11h50
  3. formatage de nombre
    Par Phiz dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 29/03/2006, 18h17
  4. Formatage de nombres dans une page JSP
    Par Addouna dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 10/03/2006, 13h01
  5. Formatage des nombres à l'affichage
    Par nbutin dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 13/07/2004, 10h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo