Convertion decimal en binaire et Codage binaire des chiffres négatifs

Bonjour,

Pour convertir une valeur numérique décimale en une chaîne de bits à afficher, j’utilise la fonction DecBin suivante (la fonction Serial.print(chiffre, BIN) permet de le faire directement) :

int entree;

char *DecBin (int n);

void setup() {
  Serial.begin(9600);

}

void loop() {
  while (Serial.available() !=0) {
   entree = Serial.parseInt();
    if (entree!=0) {
      Serial.print("conversion en binaire de  : ");
      Serial.println(entree);
      Serial.println (DecBin (entree));
  }
  }
}

char *DecBin (int n)
{
  static char bin[8];
  int x;
  for (x= 0 ; x<8; x++)
  {
    bin[x] = n & 0x80 ? '1' : '0'; // 0x8000 pour 16 bits
    n <<= 1;
   }

  bin[x] ='\0';
  return(bin);
}

En fait si j’ai bien compris la fonction de conversion se résume à ces deux lignes de code :
1/ bin[x] = n & 0x80 ? '1' : '0'; // 0x8000 pour 16 bits
2/ n <<= 1;

  • La première ligne applique un masque hexa de ET binaire à la valeur n, le masque équivaut à 10000000 en binaire. On utilise un opérateur ternaire donc si le bit de poids fort de n est armé la condition est vraie bin[x] = 1, sinon bin[x] = 0 ;
  • La deuxième décale tous les bits de n d’une position à gauche. A chaque décalage une comparaison est effectuée.
    En gros si n = 4 on obtient la chaîne bin = ‘00000100’ le microcontrôleur procède ainsi :

Pour stocker les nombres négatifs on utilise la représentation en complément à deux :

Prenons par exemple le nombre décimal -4 :

1/ on prend sa valeur positive soit 00000100 en binaire ;

2/ on lui applique l’opérateur de complément à 1 (~) ce qui donne une inversion des bits soit : 11111011 ;

3/ on ajoute un 1 binaire ce qui donne : 11111100 = -4.

Le bit de signe est passé à 1 et indique le nombre négatif, d’autre part si j’additionne 3 +(-4) cela fait en binaire 00000011 + 11111100 = 11111111. Pour l’addition j’utilise le mode de calcul suivant :

3 +(-4) donne donc le nombre binaire 11111111, son complément à deux est 00000001 soit 1 en décimal donc avec le bit de signe à 1 on obtient -1 en décimal.

En utilisant le complément à deux pour stocker les nombres négatifs cela permet donc de transformer une soustraction en addition (c’est une instruction simple pour le microcontrôleur ).

Maintenant si je reviens à la fonction DecBin et que j’utilise un masque 16 bits : 0x8000

-4 = 1111111111111100

alors qu’en 8bits -4 = 11111100

J’ai deux questions :

1/ est-ce que mon analyse de la fonction DecBin est correcte ?

2/ le codage de -4 en 16 bits est-il correct ?

Merci par avance à tous ceux qui voudront bien prendre le temps de me lire et de me répondre.

un entier de type int est sur 2 octets sur un petit AVR et 4 octets sur MKR ou ESP

Avec for (x= 0 ; x<8; x++) vous n'allez regarder que 8 bits, donc pas avoir la représentation complète

il existe la macro bitRead() pour aller lire un bit dans une valeur. essayez ce code

void printBits(int valeur) {
  Serial.print(valeur); Serial.print(F("\t--> "));
  for (int i = sizeof(int) * 8 - 1; i >= 0; i--) {
    Serial.write(bitRead(valeur, i) == 0 ? '0' : '1');
    if (i%4 == 0) Serial.write(' '); // pour grouper par 4 bits
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200); Serial.println();
  printBits(128);
  printBits(-128);
}

void loop() {}

si je ne me suis pas trompé (non testé, tapé ici) - vous devriez voir

128	 --> 0000 0000 1000 0000 
-128 --> 1111 1111 1000 0000 

si vous essayez avec 4 et -4

4	--> 0000 0000 0000 0100 
-4	--> 1111 1111 1111 1100 

PS: sizeof est un opérateur qui permet de connaître le nombre d'octets assignés à une variable ou un type, donc dans la boucle for quand je fais sizeof(int) ça va s'adapter à la longueur d'un entier, 2 ou 4 octets suivant la plateforme. je multiplie par 8 pour compter le nombre de bits (1 octet c'est 8 bits) et j'enlève 1 car on compte les bits par puissance de 2, de 0 pour le bit de poids faible à 15 (sur 2 octets) pour le bit de poids fort.
➜ sur AVR l'index de ma boucle va donc varier de 15 à 0 et aller chercher par bitRead() le bit correspondant dans la valeur passée en paramètre et l'afficher.

PS2: au lieu de
Serial.write(bitRead(valeur, i) == 0 ? '0' : '1');
or aurait pu aussi bien faire directement
Serial.print(bitRead(valeur, i));
qui aurait aussi affiché 0 et 1

1 Like

Merci JML,

int entree;
void printBits(int valeur);



void setup() {
  Serial.begin(115200); Serial.println();
  
}

void loop() {
  while (Serial.available() !=0) {
   entree = Serial.parseInt();
  
    if (entree!=0) printBits(entree);
  
  }
}

  void printBits(int valeur) {
  Serial.print(valeur); Serial.print(F("\t--> "));
  for (int i = sizeof(int) * 8 - 1; i >= 0; i--) {
    Serial.print(bitRead(valeur, i) == 0 ? '0' : '1');
    if (i%4 == 0) Serial.print(' '); // pour grouper par 4 bits
  }
  Serial.println();
}

sur ESP32 :

128 --> 0000 0000 0000 0000 0000 0000 1000 0000
-128 --> 1111 1111 1111 1111 1111 1111 1000 0000

sur AVR (UNO)

128 --> 0000 0000 1000 0000
-128 --> 1111 1111 1000 0000

Votre fonction offre l'avantage de s'adapter à la taille que le matériel attribue à la variable. Elle est parfaite !
Vos explications sont claires et précises encore une fois.

Merci beaucoup.
Bonne journée

int entree;
void printBits(int valeur);



void setup() {
  Serial.begin(115200); Serial.println();
  
}

void loop() {
  while (Serial.available() !=0) {
   entree = Serial.parseInt();
  
    if (entree!=0) printBits(entree);
  
  }
}

  void printBits(int valeur) {
  Serial.print(valeur); Serial.print(F("\t--> "));
  for (int i = sizeof(int) * 8 - 1; i >= 0; i--) {
    Serial.print(bitRead(valeur, i)); 
    if (i%4 == 0) Serial.print(' '); // pour grouper par 4 bits
  }
  Serial.println();
}

Merci.

joli petit programme de test - bravo !

le point important c'est de savoir si ça vous a permis de bien comprendre la représentation des nombres négatifs :slight_smile:

Oui je crois,
En général la méthode du complément à deux est utilisée.
Pour faire simple je travaille sur 1 octet mais c'est valable sur deux, 4... :
Si je prends le nombre décimal -4 :
1/ je retiens sa valeur positive ou valeur absolue : 0000 0100 ;
2/ je lui applique l’opérateur de complément à 1 (~) ce qui donne une inversion des bits soit : 1111 1011 ;
3/ je lui ajoute un 1 binaire ce qui fait 1111 1100 sur 1 octet 1111 1111 1111 1100 sur 2.

La représentation négative d'un nombre binaire est donc égale à son inverse + 1.

Du moins c'est ce que je comprends ...

voilà :slight_smile:

(on évite d'utiliser le mot inverse qui pourrait avoir d'autres sens et on parle de complément à 1)

De plus lorsque l'on applique le complément à 1, ​le bit de signe le plus à gauche est armé ce qui confère au nombre son attribut.
Enfin mais là je suis moins sûr, il semble que l'on remplace une soustraction par une addition :
Si je fais 3 + (-4) soit 0000 0011 + 1111 1100 = 1111 1111, le résultat est négatif donc j'effectue un complément à deux sur le résultat ==> 0000 0001 ce qui donne un 1 décimal négatif : -1
L'addition étant plus simple pour le microcontrôleur, microprocesseur... ==> c'est encore mieux.

1 Like

même les petits AVR savent faire des additions et soustractions (sur 8 bits)

cf la liste d'instructions du micro-contrôleur Atmel AVR instruction set - Wikipedia

image

ensuite le compilateur joue avec ces instructions un peu comme il veut

Merci JML,
Tout ça me donne envie d'apprendre à programmer en assembleur mais pour l'instant ce serait me disperser tant la route est encore longue pour maîtriser le c - c++ et le matériel exploitable sur l'IDE arduino. D'autant plus qu'à ma connaissance, il n'est pas convivial de programmer avec ce type de langage sur cette plate-forme.

Bonne journée.

C’est assez amusant de programmer au plus proche du hardware mais vous pouvez garder cela pour plus tard. :slight_smile:

Bonsoir,

J'essaye d'améliorer le petit croquis de conversion décimal en binaire en y ajoutant une fonction qui convertit inversement de binaire en décimal tout en visualisant l'algorithme de cette conversion. Si tout se passe bien sur arduino AVR (UNO...) ou 32 bits (DUE, nano 33...) , ce n'est pas le cas sur ESP32.

Le croquis :

int entree;
int octets;
int Bit;
bool negatif;


void printBits(int valeur);
int BinDec(boolean Bin[]);


void setup() {
  Serial.begin(9600);
  
}

void loop() {
  while (Serial.available() !=0) {
   entree = Serial.parseInt();
  
    if (entree!=0) octets=0,negatif = false, Serial.print("\n"), printBits(entree);
  
  }
}

  void printBits(int valeur) {
    Bit =sizeof(int) * 8 - 1;
    int i= Bit;
    boolean Bin[i];
  Serial.print(valeur); Serial.print(F("\t--> "));
  for ( i ; i >= 0; i--) {
    Serial.print(bitRead(valeur, i));
    Bin[i]= bitRead(valeur, i);
      if (i%4 == 0) {
      Serial.print(' '); //pour grouper par 4 bits
     octets++;
     
    }
    if (Bin[Bit]) negatif = true; // si le bit de poid fort, le bit de signe est = 1 ==> le nombre est négatif
  }
  Serial.print("(");Serial.print(octets/2); Serial.println(" octets)");// 
  if (!negatif) Serial.println(BinDec(Bin)); // on ne developpe le calcul en décimal que si le chiffre est positif
  //Serial.println(BinDec(Bin));
}

int BinDec(boolean Bin[]) { // ne fonctionne pas sur ESP32
  int Total = 0;
  for(int i=0;i <= Bit;i++) {
    if(Bin[i]) {
      Total += 1<<i;  //Total = Total + (1 << i);
      Serial.print("(2^");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(pow(2, i),0);
      //Serial.print((int) pow(2, i));
      Serial.print(")");
      Serial.print(" + ");
    }
      }
  Serial.print("rien ==> TOTAL = ");
  return Total;
}

La fonction BinDec prend en paramètre un tableau de type boolean instancié dans la fonction de JML :

boolean Bin[i];
Bin[i]= bitRead(valeur, i);

Dans cette même fonction, je fais appel à la fonction BinDec en testant le bit de signe sur ARDUINO (16 ou 32 bits) et tout se déroule correctement :

if (!negatif) Serial.println(BinDec(Bin)); // on ne developpe le calcul en décimal que si le chiffre est positif
  //Serial.println(BinDec(Bin));

Sur ESP32 ça ne marche pas car le bit de signe, le 31ème (INT de 0 à 31 bits pour 4 octets) est armé même pour un chiffre positif. Sur cette plate-forme, je suis obligé d'utiliser le code suivant :

//if (!negatif) Serial.println(BinDec(Bin)); // on ne developpe le calcul en décimal que si le chiffre est positif
  Serial.println(BinDec(Bin));

j'obtiens les résultats suivants avec la version ESP32 et la version Arduino :

ESP32 :

110	--> 0000 0000 0000 0000 0000 0000 0110 1110 (4 octets)
(2^1 = 2) + (2^2 = 4) + (2^3 = 8) + (2^5 = 32) + (2^6 = 64) + (2^31 = 2147483648) + rien ==> TOTAL = -2147483538

4500	--> 0000 0000 0000 0000 0001 0001 1001 0100 (4 octets)
(2^2 = 4) + (2^4 = 16) + (2^7 = 128) + (2^8 = 256) + (2^12 = 4096) + (2^31 = 2147483648) + rien ==> TOTAL = -2147479148

445	--> 0000 0000 0000 0000 0000 0001 1011 1101 (4 octets)
(2^0 = 1) + (2^2 = 4) + (2^3 = 8) + (2^4 = 16) + (2^5 = 32) + (2^7 = 128) + (2^8 = 256) + (2^31 = 2147483648) + rien ==> TOTAL = -2147483203

ARDUINO 32 bits (DUE,nano33...) :

110	--> 0000 0000 0000 0000 0000 0000 0110 1110 (4 octets)
(2^1 = 2) + (2^2 = 4) + (2^3 = 8) + (2^5 = 32) + (2^6 = 64) + rien ==> TOTAL = 110

4500	--> 0000 0000 0000 0000 0001 0001 1001 0100 (4 octets)
(2^2 = 4) + (2^4 = 16) + (2^7 = 128) + (2^8 = 256) + (2^12 = 4096) + rien ==> TOTAL = 4500

445	--> 0000 0000 0000 0000 0000 0001 1011 1101 (4 octets)
(2^0 = 1) + (2^2 = 4) + (2^3 = 8) + (2^4 = 16) + (2^5 = 32) + (2^7 = 128) + (2^8 = 256) + rien ==> TOTAL = 445

Tout se passe comme si sur ESP 32 le bit de poids fort était armé :

(2^31 = 2147483648)

Pourtant ma fonction me semble correcte :
Chaque bit du tableau bin[i] si il est armé :
1/ incrémente Total en y ajoutant le nombre binaire correspondant à i, par exemple pour le chiffre 445 :


2/ Affiche la puissance de 2 de i et son résultat.
3/ retourne la valeur de Total.

La fonction de JML retourne bien '0'pour le bit de poids fort...

445	--> 0000 0000 0000 0000 0000 0001 1011 1101 (4 octets)
(2^0 = 1) + (2^2 = 4) + (2^3 = 8) + (2^4 = 16) + (2^5 = 32) + (2^7 = 128) + (2^8 = 256) + (2^31 = 2147483648) + rien ==> TOTAL = -2147483203

Merci par vance.

quand vous faites

    if (Bin[Bit]) negatif = true; // si le bit de poid fort, le bit de signe est = 1 ==> le nombre est négatif

vous accédez une valeur qui n'existe pas. le tableau Bin a bien Bit éléments ,mais donc le dernier c'est Bin[Bit-1]


dans int BinDec(boolean Bin[]) vous avez le même souci

for(int i=0;i <= Bit;i++) {

comme vous allez de 0 jusqu'à Bit inclus (à cause du <=), vous prenez Bit+1 éléments...

for(int i=0;i < Bit;i++) {


Ne prenez pas l'habitude d'écrire comme cela. utilisez des accolades pour grouper les expressions est des points virgules pour séparer chaque expression.

if (entree!=0) {
  octets=0;
  negatif = false;
  Serial.print("\n");
  printBits(entree);
}

idem pour ce genre d'écriture

  for ( i ; i >= 0; i--) {

le i tout seul au début ne veut rien dire. Si vous activez les warning d'ailleurs le compilo va vous le dire.

par exemple on va écrire:

  for ( int i=Bit ; i >= 0; i--) {

quand vous faites

    if (i % 4 == 0) {
      Serial.print(' '); //pour grouper par 4 bits
      octets++;
    }

octets augmente de 1 à chaque groupe de 4 bits, ce qui n'est pas un octet. le nombre d'octets c'est toujours sizeof(valeur) ou sizeof(int)


prenez aussi l'habitude de déclarer les variables au bon niveau. ça sert à rien de passer une variable globale en paramètre, laissez la fonction travailler sur la variable globale dans ce cas. sinon utilisez des variables locales. (sauf si vous avez une raison pour vouloir allouer de manière définie la mémoire)

Bonjour JML,
J'ai tout repris à zéro en déclarant une constante Bit qui définit le nombre de bit d'un int sur chaque plateforme :

const int Bit =sizeof(int) * 8; // Définit le nombre de bits pour un 'int' sur la plateforme

Partant de là j'ai pris en compte vos remarques, notamment celle concernant le premier élément d'un tableau qui commence à l'indice 0 ==> le dernier élément a donc pour indice le nombre d'éléments moins 1 et c'est à prendre en compte dans l'écriture du code. Et pourtant je le sais depuis longtemps…
Je vous prie de m'excuser également pour la variable octets qui n'avait rien à faire dans ce croquis d'autant plus que vous m'avez déjà rabâché plusieurs fois que le nombre d'octets correspond à sizeof(valeur) et que de surcroit je l'ai lu à plusieurs reprises.
Voilà, j'ai également fait des corrections en fonction de vos autres remarques.

Ce programme fonctionne parfaitement sur toutes les plateformes dont je dispose, y compris sur ESP 32 :

const int Bit =sizeof(int) * 8; // Définit le nombre de bits pour un 'int' sur la plateforme
boolean negatif; // définit si le nombre est négatif - variable utilisée dans tout le programme

//Déclaration des procédures et fonctions
void printBits(int valeur);
int BinDec(boolean Bin[]);


void setup() {
  Serial.begin(9600);
  //Serial.println("Valeur de Bit :");
  //Serial.print(Bit);
}

void loop() {
  while (Serial.available() !=0) {
  int entree = Serial.parseInt();
  
    if (entree!=0) {
      negatif = false;
      Serial.print("\n");
      printBits(entree);
    }
  
  }
 
}

  void printBits(int valeur) {
  boolean Bin[Bit]; // Tableau binaire de Bits éléments
  Serial.print(valeur); Serial.print(F("\t--> "));
  for (int i= Bit-1;  i >= 0; i--) { // Bit-1 car on va du nombre de bits -1 à 0
    Serial.print(bitRead(valeur, i));
    Bin[i]= bitRead(valeur, i); 
      if (i%4 == 0) Serial.print(' '); //pour grouper par 4 bits
     }
     if (Bin[Bit-1]) negatif = true; //si le bit de poid fort, le bit de signe est = 1 ==> le nombre est négatif - Bit-1 est le dernier élément du tableau.
     Serial.print("(");Serial.print(sizeof(int)); Serial.println(" octets)");// sizeof(int) définit la taille en octets de la variable
    if (!negatif) Serial.println(BinDec(Bin)); // on ne developpe le calcul en décimal que si le chiffre est positif
   
  }
   
  
int BinDec(boolean Bin[]) { 
  int Total = 0;
  
    for(int i=0;i <Bit; i++) { //<bit permet de ne pas dépasser le NB d'éléments du tableau Bin[i] 
      if(Bin[i]) {
        Total += 1<<i;  //Total = Total + (1 << i);
        Serial.print("(2^");
        Serial.print(i);
        Serial.print(" = ");
        Serial.print(pow(2, i),0);
        //Serial.print((int) pow(2, i));
        Serial.print(")");
        Serial.print(" + ");
    }
   }
  Serial.print("rien ==> TOTAL = ");
  return Total;
}

Merci et bonne journée.

super code, bravo ! :clap:

Pour vous améliorer:

Si vous voulez respecter le standard adopté par Arduino (et bcp d'autres) on utilise le camelCase pour écrire le nom des variables ➜ on commence par une minuscule et tout nouveau mot dans le nom de la variable commence par une majuscule.

On essaye aussi d'avoir un nom parlant

par exemple, votre tableau Bin pourrait s'appeler representationBinaire et au lieu de Bit, le nombre de bits dans votre entier pourrait s'appeler nombreDeBits

ça rend le code plus lisible


Sinon c'est bien d'être attentif aux types des variables lors des affectations. (ça vous servira pour d'autres langages)

Par exemple quand vous faites

    Bin[i] = bitRead(valeur, i);

vous essayez de stocker un entier dans une variable de type bool (boolean c'est un truc arduino) . Le compilateur applique alors une règle officielle qui est qui si la valeur est 0 il transforme cela en false, sinon c'est true. On a donc bien un booléen au final qui va dans la variable mais c'est pas super lisible (même si ça respected la norme) et certains aiment écrire clairement la conversion

    Bin[i] = (bitRead(valeur, i) == 0) ? false : true ;

Enfin, pour la lisibilité, assurez vous aussi d'indenter le code dans l'IDE. Cela se fait en pressant ctrlT sur PC ou cmdT sur un Mac). Comme ça vos accolades seront alignées, ça permet de voir la structure du code

Merci JML,

const int nombreDeBits = sizeof(int) * 8; // Définit le nombre de bits pour un 'int' sur la plateforme
boolean nombreNegatif; // définit si le nombre est négatif - variable utilisée dans tout le programme

//Déclaration des procédures et fonctions
void printBits(int valeur);
int binDec(boolean tableauBinaire[]);


void setup() {
  Serial.begin(9600);

}

void loop() {
  while (Serial.available() != 0) {
    int entree = Serial.parseInt();

    if (entree != 0) {
      nombreNegatif = false;
      Serial.print("\n");
      printBits(entree);
    }

  }

}

void printBits(int valeur) {
  boolean representationBinaire[nombreDeBits];
  Serial.print(valeur); Serial.print(F("\t--> "));
  for (int i = nombreDeBits - 1;  i >= 0; i--) { // nombreDeBits-1 car on va du nombre de bits -1 à 0
    Serial.print(bitRead(valeur, i));
    representationBinaire[i] = (bitRead(valeur, i) == 0) ? false : true; // operateur ternaire : si (bitRead(valeur, i)== 0) ==> representationBinaire[i] = false sinon =true
    if (i % 4 == 0) Serial.print(' '); //pour grouper par 4 bits
  }
  if (representationBinaire[nombreDeBits - 1]) nombreNegatif = true; //si le bit de poid fort, le bit de signe est = 1 ==> le nombre est négatif - nombreDeBits-1 est le dernier élément du tableau.
  Serial.print("("); Serial.print(sizeof(int)); Serial.println(" octets)"); // sizeof(int) définit la taille en octets de la variable
  if (!nombreNegatif) Serial.println(binDec(representationBinaire)); // on ne developpe le calcul en décimal que si le chiffre est positif

}


int binDec(boolean tableauBinaire[]) {
  int totalDec = 0;

  for (int i = 0; i < nombreDeBits; i++) { //<bit permet de ne pas dépasser le NB d'éléments du tableau Bin[i]
    if (tableauBinaire[i]) {
      totalDec += 1 << i; //Total = Total + (1 << i);
      Serial.print("(2^");
      Serial.print(i);
      Serial.print(" = ");
      Serial.print(pow(2, i), 0);
      //Serial.print((int) pow(2, i));
      Serial.print(")");
      Serial.print(" + ");
    }
  }
  Serial.print("rien ==> TOTAL = ");
  return totalDec;
}

Merci à vous, bonne soirée.

super - bonne soirée à vous aussi

PS/ un dernier truc: 9600 bauds c'était au millénaire dernier, vous pouvez passer à 115200 bauds sans souci

void setup() {
  Serial.begin(115200);
}

et bien sûr passer le moniteur série à ce débit aussi

D'accord merci encore. :wink:

En complément du premier croquis, en voici un autre qui convertie de décimal en Hexa et inversement d'Hexa en décimal tout en visualisant l'algorithme de cette dernière conversion :

char tableauHex[16]; // variable globale car utilisée dans les deux fonctions
int indice; // variable globale car utilisée dans les deux fonctions

void setup() {
  Serial.begin(115200);

}

// Déclaration des fonctions
char *conversion (int chiffre);
int hexDec() ;

void loop() {
  while (Serial.available() != 0) {
    int entree = Serial.parseInt();

    if (entree != 0) {
      Serial.print(entree);
      Serial.print(F("\t-->\t"));
      Serial.print(F("\tHEXA\t"));
      Serial.println(conversion(entree));
      Serial.println(hexDec());
    }
  }
}
char  *conversion (int chiffre) { // renvoie une chaîne de caractères 
  static char resultat[16]; // tableau de char qui va constitué la chaîne renvoyée par la fonction
  int reste[16]; // reste de la division par 16
  int i = 0;
  int y = 0;

  do {
    reste[i] = chiffre % 16; // reste de la division par 16
    chiffre =  (int) (chiffre / 16); // on garde le nombre entier de la division
    i++;
  } while ( chiffre > 0 ); // tant que chiffre est > 0

  for ( int x = i - 1 ; x >= 0 ; x--) {

    switch (reste[x]) { // convertie int en char(s) et chaque reste en hexa
                        // 
      case 0:
        resultat[y] = '0';
        break;
      case 1:
        resultat[y] = '1';
        break;
      case 2:
        resultat[y] = '2';
        break;
      case 3:
        resultat[y] = '3';
        break;
      case 4:
        resultat[y] = '4';
        break;
      case 5:
        resultat[y] = '5';
        break;
      case 6:
        resultat[y] = '6';
        break;
      case 7:
        resultat[y] = '7';
        break;
      case 8:
        resultat[y] = '8';
        break;
      case 9:
        resultat[y] = '9';
        break;
      case 10:
        resultat[y] = 'A';
        break;
      case 11 :
        resultat[y] = 'B';
        break;
      case 12 :
        resultat[y] = 'C';
        break;
      case 13 :
        resultat[y] = 'D';
        break;
      case 14 :
        resultat[y] = 'E';
        break;
      case 15 :
        resultat[y] = 'F';
        break;
    }
    y++;
  }
  resultat[y] = '\0'; // marque la fin du tableau de char
  indice =  y; //  récupère l'indice qui servira à parcourir tableauHex ds la fonction hexDec
  for ( int x = y - 1 ; x >= 0 ; x--) tableauHex[x] = resultat[x]; //remplie tableauHex pour la fonction hexDec

  return (resultat);

}

int hexDec() {
  int totalDec = 0;
  int caractere;
  int z = 0;
  for (int i = indice - 1 ; i >= 0; i--) { 

    switch (tableauHex[i]) { // convertie les éléments du tableau HEX en decimal

      case '0':
        caractere = 0;
        break;
      case '1':
        caractere = 1;
        break;
      case '2':
        caractere = 2;
        break;
      case '3':
        caractere = 3;
        break;
      case '4':
        caractere = 4;
        break;
      case '5':
        caractere = 5;
        break;
      case '6':
        caractere = 6;
        break;
      case '7':
        caractere = 7;
        break;
      case '8':
        caractere = 8;
        break;
      case '9':
        caractere = 9;
        break;
      case 'A':
        caractere = 10;
        break;
      case 'B':
        caractere = 11;
        break;
      case 'C':
        caractere = 12;
        break;
      case 'D':
        caractere = 13;
        break;
      case 'E':
        caractere = 14;
        break;
      case 'F':
        caractere = 15;
        break;
    }
    totalDec += caractere * (1 << (4 * z)); // pow(16, z) donne en binaire 1 << (4 * z)
    Serial.print("(16^");
    Serial.print(z);
    Serial.print(")");
    Serial.print("*");
    Serial.print(tableauHex[i]);
    Serial.print(" = ");
    Serial.print(caractere * (pow(16, z)), 0);
    Serial.print(")");
    Serial.print(" + ");
    z = z + 1;
  }
  Serial.print("rien ==> TOTAL = ");
  return totalDec;
}

Le croquis fonctionne parfaitement sur toutes les plateformes dont je dispose.
Malheureusement, je rencontre des difficultés pour convertir les variables de type int en char et inversement. J'ai bien essayé plusieurs méthodes mais toutes ont entrainé des dysfonctionnements d'où la lourdeur et la longueur de mes instructions switch

Merci à tous ceux qui voudront bien émettre des critiques…
Bonne journée.

Un code classique pour vous donner des idées. Le paramètre len représente la place dispo dans le buffer pointé par le paramètre str. L’algo donne la représentation ASCII de num pour la base choisie.


int itoa(int num, unsigned char* str, int len, int base = 10) {
	int sum = num;
	int i = 0;
	int digit;
	if (len == 0)
		return -1;
	do {
		digit = sum % base;
		if (digit < 0xA)
			str[i++] = '0' + digit;
		else
			str[i++] = 'A' + digit - 0xA;
		sum /= base;
	} while (sum && (i < (len - 1)));
	if (i == (len - 1) && sum)
		return -1;
	str[i] = '\0';
	strrev(str); // la chaîne est inversée
	return 0;
}

L’algo se base sur le modulo. Par exemple en base 10, si on veut convertir 123

123 modulo 10 = ‘3’ et on continue avec 123 / 10 = 12
12 modulo 10 = ‘2’ et on continue avec 12 / 10 = 1
1 modulo 10 = ‘1’ et on continue avec 1 / 10 = 0
0 ==> fin de l’algo
On a bâti "321", reste plus qu’à inverser cette chaîne pour avoir la bonne représentation "123"

Implémentation classique

void strrev(unsigned char *str)
{
	int i;
	int j;
	unsigned char a;
	unsigned len = strlen((const char*) str);
	for (i = 0, j = len - 1; i < j; i++, j--) {
		a = str[i];
		str[i] = str[j];
		str[j] = a;
	}
}