LOCODUINO

Calculer avec l’Arduino (2)

Les opérations sur les bits

. Par : Jean-Luc

Dans ce qui suit, les bits sont numérotés comme montré dans la figure ci-dessous. Chaque case peut contenir un bit, au dessus on a le numéro du bit. Le bit 0 est le bit le plus à droite, le bit 7 est le bit le plus à gauche. Ceci est donc un octet. Opérateurs sur les bits Plusieurs opérateurs permettent de manipuler les bits. Ces opérateurs (…)

Retourner à l'article

Vous répondez à :

calculer en binaire 8 février 2021 19:35, par Nicolas

Bonsoir, j’essaie de comprendre la manipulation des bits et le calcul binaire.
Dans la bibliothèque d’une RTC (DS3231), j’ai une fonction pour lire la temperature.
J’ai une fonction if() pour voir si le bit 7 du registre vaut 1 (1-temp negative, 0-temp positive) :

if (tUBYTE & 0b10000000)
{
    tUBYTE  ^= 0b11111111;
    tUBYTE  += 0x1;
    fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25);
    fTemperatureCelsius = fTemperatureCelsius * -1;
}
return (fTemperatureCelsius);

Je n’arrive pas à décrypter le calcul (les 2 premières lignes dans la fonction if) car si je prends tUBYTE = 23 par exemple, je n’arrive pas à -23 au final.
Pourtant le sketch test fourni avec la bibliotèque me donne la bonne valeur. Donc je dois faire un mauvais calcul sur ma feuille quelque part.

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

22 Messages

  • Calculer avec l’Arduino (2) 11 mai 2015 00:19, par hicham

    q’est ce que ne donne les deux lignes d’instruction suivante :

    a=5;
    a=|a;

    Répondre

  • Calculer avec l’Arduino (2) 11 mai 2015 09:54, par Jean-Luc

    La première met la valeur 5 dans la variable a.
    La seconde n’est pas une expression possible en langage Arduino/C. Je suppose qu’il y a une faute de frappe et que vous vouliez écrire a |= a;. C’est l’équivalent de a = a | a; et a | a est égal à a. Donc l’expression se réduit à a = a;

    Répondre

  • Bonjour ,Cela fait deux semaines que j’ étudie Arduino et je me casse la tête pour trouver une solution : c’ est à dire comment utiliser deux capteurs a et b , les rentrer dans deux variables (x et y) et diviser les données de "x" par les données de "y" et sortir le résultat sur les pins de l arduino. Par comparaison avec le Pic, Et encore moins comment rentrer je ne trouve pas l’ accumulateur "W" sur l arduino.
    Je suis habitué aux Pics où il fallait mettre le premier chiffre dans la variable "x" et le deuxième dans la variable "y" mais avec arduino je ne sais pas comment rentrer les données des pins dans les variables "x".
    et "y".
    J espère que j ai été assez explicite et vous remercie de votre réponse.

    Répondre

  • Convertir une valeur binaire en texte 9 mai 2019 16:56, par Romain

    Bonjour,
    j’essaye de convertir une suite de 1 et 0 ( par ex : x=01001000 )en une lettre ( Ici x = H)

    Je ne sais pas sous quel forme (char,int,..) initialiser ma variable (x) et je ne sais également pas ce qu’il faut ecrire pour convertir ma variable.
    J’ai réussit a faire l’inverse mais la je bloque.

    Merci de votre réponse .

    Programme pour convertir "Hector" en binaire :

    void loop()
    {
      String myText = "Hector";
      for(int i=0; i<myText.length(); i++)
      {
        char myChar = myText.charAt(i);  
        for(int i=7; i>=0; i--)
        {
          String bytes = String( bitRead(myChar,i));
        }
      }
    }

    Répondre

    • Convertir une valeur binaire en texte 9 mai 2019 21:20, par Jean-Luc

      Bonsoir,

      X est une chaîne de caractères ?

      Répondre

      • Convertir une valeur binaire en texte 9 mai 2019 23:42, par Romain

        Entait c’est ce que je cherche a savoir !

        J’essaye de faire un système LI-Fi (transport d’information par la lumière) En locurrence on transmet des 1 avec une led allumée et 0 avec une led éteinte
        J’arrive à envoyer mon message et à le recevoir mais je ne sais pas comment "stocker" et convertir en lettre mon message binaire.

        Répondre

        • Convertir une valeur binaire en texte 10 mai 2019 08:31, par Jean-Luc

          Ok, vous recevez des 0 et des 1 et vous voulez les accumuler dans un octet. Si b est le bit reçu et lettre la lettre :

          byte b;
          unsigned char lettre;

          alors après avoir initialisé lettre à 0 et en supposant que vous receviez le bit de poids fort en premier, pour chaque bit, on fait :

          lettre = (lettre << 1) | b;

          Si par contre c’est le bit de poids faible qui est reçu en premier, on fera :

          lettre = (lettre >> 1) | (b << 7);

          Il faut par contre bien recevoir 8 bits

          À la fin, lettre contient ce que vous voulez.

          Répondre

          • Convertir une valeur binaire en texte 10 mai 2019 20:05, par Romain

            Bonsoir,
            J’ai essayer votre solution mais je n’arrive pas a afficher "lettre" dans un Serial.print
            Et je n’ai pas compris la ligne de code donc je ne peux pas l’adapter (Pas besoin d’expliquer si cest trop long)

            Merci de votre réponse.

            Répondre

            • Convertir une valeur binaire en texte 10 mai 2019 21:33, par Jean-Luc

              Rajoutez (char) juste avant lettre dans le Serial.print

              Répondre

              • Convertir une valeur binaire en texte 12 mai 2019 14:13, par Romain

                Bon je désespère un peu, lorsque j’écrit Serial.print(lettre) j’obtiens que des 0 et pour Serial.print((char)lettre) je n’obtient rien !

                Je vous laisse mon programme si vous avez des idée je suis preneur.

                boolean Start = true; //this is used to determine if the counting has started
                byte b ;
                unsigned char lettre = 0 ;
                
                void setup()
                {
                  Serial.begin(9600);
                }
                
                void loop()
                {
                  // read the sensor value
                  int sensorValue = analogRead(A0);
                
                  for (int i=0 ; i<=7 ; i++) {
                    // read the sensor value
                    int sensorValue = analogRead(A0);
                    if (Start==true && sensorValue>850) {
                      // if the counting has not yet started and the light is on
                      b = 1 ;
                      delay (1000);
                    }
                
                    if (Start== true && sensorValue<850) {
                      // if the counting has started and the light is off
                      b = 0 ;
                      delay (1000);
                
                      lettre = (lettre << 1) | b;
                    }
                  }
                  Serial.print( (char) lettre) ;
                  Serial.print(" ") ;
                }

                Répondre

                • Convertir une valeur binaire en texte 12 mai 2019 16:13, par Jean-Luc

                  Bonjour,

                  Des idées j’en ai plusieurs :

                  1. j’ai remis l’indentation d’équerre. L’indentation ce n’est pas que pour faire beau, ça permet de trouver les bugs puisqu’elle renseigne sur la structuration du programme. Si vous ne faites pas des efforts sur l’indentation vous allez écrire des choses fausse sans le voir.
                  2. À quoi sert la ligne 13 ? sensorValue n’est pas utilisé et est écrasé ligne 17.
                  3. Dans le if de la ligne 18 à 22, vous ne faites rien de b.
                  4. Si sensorValue est exactement égal à 850, que devrait-il se passer ?
                  5. Je soupçonne que ce qui est ligne 29 devrait être deux lignes plus bas.
                  6. On n’écrit jamais deux if qui sont censés être mutuellement exclusifs, on met un else à la place :
                  if (Start == true) {
                    if (sensorValue > 850) {
                      b = 1 ;
                    }
                    else {
                      b = 0;
                    }
                    lettre = (lettre << 1) | b;
                    delay(1000);
                  }

                  ou plus concis :

                  if (Start == true) {
                    lettre = (lettre << 1) | ((sensorValue > 850) ? 1 : 0);
                    delay(1000);
                  }

                  Répondre

  • Calculer avec l’Arduino (2) 20 mai 2020 17:57, par Nicolas

    Félicitations pour vos articles. Vraiment une pédagogie sans pareil.
    Je voudrais s’il vous plait si c’est possible de mettre dans chaque article ou sur quelques un pourquoi on utilise, tel ou tel élément. Par exemple pour quoi on utiliserait les opérateurs de décalage. Dans quelle but ? Comme ça on cible nos besoins et on comprends mieux pourquoi on utiliserait plus une opération qu’une autre.
    Merci encore

    Répondre

    • Calculer avec l’Arduino (2) 21 mai 2020 10:27, par Jean-Luc

      Bonjour,
      Merci beaucoup pour votre commentaire. J’ai complété l’article avec un exemple qui illustre l’emploi du << et du >> mais également du &, du | et du ~.

      Répondre

  • calculer en binaire 8 février 2021 19:35, par Nicolas

    Bonsoir, j’essaie de comprendre la manipulation des bits et le calcul binaire.
    Dans la bibliothèque d’une RTC (DS3231), j’ai une fonction pour lire la temperature.
    J’ai une fonction if() pour voir si le bit 7 du registre vaut 1 (1-temp negative, 0-temp positive) :

    if (tUBYTE & 0b10000000)
    {
        tUBYTE  ^= 0b11111111;
        tUBYTE  += 0x1;
        fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25);
        fTemperatureCelsius = fTemperatureCelsius * -1;
    }
    return (fTemperatureCelsius);

    Je n’arrive pas à décrypter le calcul (les 2 premières lignes dans la fonction if) car si je prends tUBYTE = 23 par exemple, je n’arrive pas à -23 au final.
    Pourtant le sketch test fourni avec la bibliotèque me donne la bonne valeur. Donc je dois faire un mauvais calcul sur ma feuille quelque part.

    Répondre

    • calculer en binaire 8 février 2021 21:37, par Jean-Luc

      Bonsoir,

      Les deux premières lignes font une complémentation à 2 :

      • La première ligne inverse tous les bits (ou exclusif avec tous les bits à 1)
      • La seconde ligne ajoute 1

      Il n’y a aucune raison qu’une valeur de 23 pour tUBYTE produise un résultat de -23. En effet, le bit 7 est à 0 et la condition du if est fausse.

      Répondre

      • calculer en binaire 9 février 2021 10:26, par Nicolas

        Bonjour, oui je me suis trompé, je voulais bien dire tUBYTE= -23 et non pas 23.
        Reprenons cette boucle if() ligne par ligne : (on garde tUBYTE= -23 soit 0b10010111 et tLRBYTE= 0)

        if(tUBYTE & 0b10000000)
          {
           tUBYTE  ^= 0b11111111;
           tUBYTE  += 0x1;
           fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25);
           fTemperatureCelsius = fTemperatureCelsius * -1;
          }

        "if(tUBYTE & 0b10000000)" : je lis Si( 0b10010111 et 0b10000000), je ne comprends pas ce qu’est la condition vraie ?
        Si on calcule 0b10010111 & 0b1000000, on obtient 0b10000000. Doit-on lire Si(0b10000000) ? Ca reviendrait à dire "Si(resultat de tUBYTE & 0b10000000 vaut 0b10000000), la condition est vraie" ? On aurait pu donc l’ecrire : if(tUBYTE & 0b10000000 == 0b10000000) ?

        "tUBYTE ^= 0b11111111 ;" : je lis tUBYTE = tUBYTE ^ 0b11111111 soit tUBYTE = 0b10010111 ^ 0b11111111 = 0b01101000.

        "tUBYTE += 0x1 ;" : je lis tUBYTE (calculé juste au-dessus) = tUBYTE + 0b00000001 soit tUBYTE = 0b01101000 + 0b00000001 = 0b01101001.

        "fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25) ;" : je lis fTemperatureCelsius = 0b01101001 + 0 = 0b01101001 soit 105.

        "fTemperatureCelsius = fTemperatureCelsius * -1 ;" : je lis fTemperatureCelsius = 105* -1 = -105. Donc -105°C.

        Il y a donc quelque chose que je ne lis pas correctement, mais quoi ?

        Répondre

        • calculer en binaire 9 février 2021 18:10, par Jean-Luc

          Bonsoir.

          En C, une expression est considérée vrai si elle est différente de 0. Par conséquent tUBYTE & 0b10000000 sera vrai si le bit 7 de tUBYTE est à 1.

          –23 est égal à 0b11101001 en complément à 2 (Pas à 0b10010111). Le ou exclusif avec un octet dont tous les bits sont à 1 inverse tous les bits. On a donc 0b00010110. En ajoutant 1 on a 0b00010111, ce qui est égal à 16 + 4 + 2 + 1 = 23 (on a pris l’opposé).

          Répondre

          • calculer en binaire 9 février 2021 18:20, par Nicolas

            Merci pour ces précisions.
            Je vais étudier cette histoire de complément à 2 car c’est cela qui m’induit en erreur.
            Encore merci pour tout ce travail.

            Répondre

Rubrique Programmation

Les derniers articles

Les articles les plus lus