Valeur INT =42 vers valeur Hexa = 0x42 ?

Bonjour,

Après une semaine à m'arracher les cheveux la dessus, je me décide de m'inscrire sur le forum et vous poser probablement cette question qui pour vous sera facile à résoudre.

Je cherche à transformer une valeur INT = 42 vers un 0x42 pour la transmettre via RS232.

Comment dois-je m'y prendre ?

Merci pour votre aide...

Je ne vois pas l'intérêt d'une telle conversion.
Si tu envoies un caractère 42 tu recevra 42 à l'autre bout.

Mais si tu y tiens absolument cela revient à convertir le nombre en BCD.

int bcd(int dec)
{
  return ((dec/10)<<4)+(dec%10);
}

On convertit en BCD pour envoyer des nombres décimaux à des circuits non intelligents du genre encodeur BCD / 7 segments CD4511 par exemple.
A L'autre bout de la ligne série, il y a forcément un récepteur intelligent qui comprendra que 42 est un nombre décimal.

oui faudrait comprendre le besoin exact généralement on veut envoyer une chaîne en ASCII...

sinon pour votre question:

en décimal [color=red]4[/color][color=blue]2[/color] = [color=red]4[/color] x 10 + [color=blue]2[/color]

Pour passer à 0x42 en hexadécimal, il suffit de faire [color=red]4[/color] x 16 + [color=blue]2[/color]

extraire le 4 et le 2 n'est pas compliqué, l'un est obtenu par division entière par 10 et l'autre modulo par 10.

byte x = 42;
void setup() {
  Serial.begin(115200);
  byte dizaine = x / 10;
  byte unite = x % 10;
  Serial.print(F("En Decimal: "));
  Serial.print(x);
  Serial.print(F(" = "));
  Serial.print(dizaine);
  Serial.print(F(" x 10 + "));
  Serial.println(unite);


  byte hexadecimal = 16 * dizaine + unite;
  Serial.print(F("En Hexa: 0x"));
  Serial.println(hexadecimal, HEX);
}

void loop() {}

Sur le moniteur Série à 115200 bauds vous verrez

[color=purple]
En Decimal: 42 = 4 x 10 + 2
En Hexa: 0x42
[/color]

En fait, ce qu'il faudrait dire c'est ce qu'attend l'application à l'autre bout:

  • une chaine de caractères contenant un 4 suivi d'un 2
  • un entier de valeur 42
  • le nombre 42 codé en BCD

Bonjour,

Tu es sur que tu veux convertir 42 en 0x42?
Ce n'est pas plutôt convertir 42 en chaîne de caractères "42" pour transmission?

le problème est que j'ai besoin de ma valeur récupéré dans un tableau en INT qui me donne :

freq[0] = 42;
freq[1] = 21;
freq[2] = 10;
freq[3] = 00;
freq[4] = 01;

pour la transmettre en :

RS232.write(0x42);
RS232.write(0x21);
RS232.write(0x10);
RS232.write(0x00);
RS232.write(0x01);

et je ne sais pas faire, je bloque la dessus depuis une bonne semaine (heureusement pas 24H/24H) :slight_smile:

A qui envoies-tu ces données ?

bunoo:
le problème est que j'ai besoin de ma valeur récupéré dans un tableau en INT qui me donne :

et je ne sais pas faire, je bloque la dessus depuis une bonne semaine (heureusement pas 24H/24H) :slight_smile:

mais pourquoi voulez vous transmettre des chiffres qui ne correspondent pas ? 42 en décimal c'est 42, alors que 0x42 c'est 66 en décimal... vous allez envoyer des données erronées ?

(je vous ai mis un bout de code d'exemple en #2 si c'est vraiment ce que vous voulez faire)

C'est pour changer la fréquence d'un émetteur radio :

Page 70 à 73 de cette doc :

FT-817

Je n'ai pas le choix de lui envoyer ce type de données.

Oui OK.
Pas trop le choix donc.

01, 42, 34, 56, [01] = 14.23456 MHz

Tu peux donc utiliser la solution en #1.

Bonjour, je vous annonce le combat entre deux fervents défenseurs du BCD:
((dec/10)<<4)+(dec%10); contre dec>9?dec+6:dec;

Programme de test, première valeur affichée en décimale, deuxième en hexa (ça affiche pour ceusses qui sont incrédules)

le print dans la fonction, c'est pour être sûr qu'il y ait bien la fonction (je pense que le compilateur a une fâcheuse tendance à virer mon code si il ne fait rien)

byte bcd(byte dec)
{
  Serial.print(dec); Serial.print(" -> "); 
//  return ((dec/10)<<4)+(dec%10);
//  if (dec>9) return dec+6; else return dec;
//  return dec > 9 ? dec + 6 : dec;
}

void setup()
{
  Serial.begin(115200);
  for (byte n = 0; n < 16; n++) Serial.println(bcd(n), HEX);
}
void loop()
{
}

1746 octets. C'est ma base!

byte bcd(byte dec)
{
  Serial.print(dec); Serial.print(" -> "); 
  return ((dec/10)<<4)+(dec%10);
//  if (dec>9) return dec+6; else return dec;
//  return dec > 9 ? dec + 6 : dec;
}

void setup()
{
  Serial.begin(115200);
  for (byte n = 0; n < 16; n++) Serial.println(bcd(n), HEX);
}
void loop()
{
}

1782 octets

byte bcd(byte dec)
{
  Serial.print(dec); Serial.print(" -> "); 
//  return ((dec/10)<<4)+(dec%10);
  if (dec>9) return dec+6; else return dec;
//  return dec > 9 ? dec + 6 : dec;
}

void setup()
{
  Serial.begin(115200);
  for (byte n = 0; n < 16; n++) Serial.println(bcd(n), HEX);
}
void loop()
{
}

1754 octets

byte bcd(byte dec)
{
  Serial.print(dec); Serial.print(" -> "); 
//  return ((dec/10)<<4)+(dec%10);
//  if (dec>9) return dec+6; else return dec;
  return dec > 9 ? dec + 6 : dec;
}

void setup()
{
  Serial.begin(115200);
  for (byte n = 0; n < 16; n++) Serial.println(bcd(n), HEX);
}
void loop()
{
}

1754 octets

En résumé:

pour 8 octets vous avez les formules compètes (sans jus d'orange):
if (dec>9) return dec+6; else return dec;
return dec > 9 ? dec + 6 : dec;

la deuxième, c'est pour les fatigués du clavier. C'est moins lisible si on n'a pas l'habitude.
La première est pas mal.

pour 68 octets vous n'avez qu'un plat:
return ((dec/10)<<4)+(dec%10);

Pour ceux qui n'ont pas suivi, prenez

byte bcd(byte dec)
{
  if (dec>9) return dec+6;
  else return dec;
}

C'était ce qui était utilisé quand on faisait des décodeurs BCD avec des portes ET OU NON... Ça fonctionne encore

@olivier_pecheux
ça ne fonctionne que si votre octet d'entrée tient sur 4 bits...

Pour être honnête, je ne vois pas comment je peux me servir de ça :o

Comment au final, de mon

int[0] = 42;

je peux l'envoyer dans ma RS232 :

RS232.write(0x42);

Désolé, mais même si j'ai commencé à programmer au tout début des années 80, la je dois avouer qu'en arduino, je suis presque novice et je ne m'en sors pas avec cette foutue instruction qui ne me fait pas avancer depuis un moment.

Je sais récupérer la fréquence, aucun problème, je sais la reconstituer mais je n'arrive pas à la récupérer pour la renvoyer dans un autre appareil du même type.

int[0] = 42;

je peux l'envoyer dans ma RS232 :

RS232.write(0x42);

int bcd(int dec)
{
return ((dec/10)<<4)+(dec%10);
}

En remplaçant INT par ((INT/10)<<4)+(INT%10)
INT = 42;
RS232.write(((INT/10)<<4)+(INT%10));

ou en appelant la fonction bcd
INT = 42;
RS232.write(bcd(INT));

Un grand merci Olivier,

ça fonctionne parfaitement, je vais enfin pouvoir avancer...
Je vais bien reprendre l'explication pour que ça rentre dans ma petite tête de vieux programmateur.

Bien amicalement.

Bruno.

ça ne fonctionne que si votre octet d'entrée tient sur 4 bits...

J'étais resté sur:

01, 42, 34, 56, [01] = 14.23456 MHz

Qui n'est pas non plus sur 8 bits

olivier_pecheux:
J'étais resté sur:...
Qui n'est pas non plus sur 8 bits

son tableau c'est

req[0] = 42;
freq[1] = 21;
freq[2] = 10;
freq[3] = 00;
freq[4] = 01;

donc au minimum ils seront sur un octet.

je ne suis pas sûr de bien comprendre votre point. Par exemple appeler le code que vous proposez

byte bcd(byte dec)
{
  if (dec>9) return dec+6;
  else return dec;
}

avec 42dec comme paramètre va retourner 48dec et non pas 66dec qui est le 42hex attendu...

je ne suis pas sûr de bien comprendre votre point.

la réponse est la:

ça ne fonctionne que si votre octet d'entrée tient sur 4 bits...

Dans un premier temps, j'ai pensé que tant qu'à découper, au lieu de découper en 6 puis en 2, on pouvait découper en 12. Mais cela ne fonctionne pas car il faut envoyer les chiffres deux par 2. Erreur de ma part.

ah OK