Ajouter des variables en Binaire pour envoie en RF433

Bonjour,
Afin de pouvoir envoyer en radiofréquence 433mhz via la methode "Send" de la library RCSwitch les informations de 3 variables int, je souhaite les ajouter de manière binaire.

Je mets une illustration de ce que je souhaite réaliser.
J'ai conscient que ce code est loin d'être de qualité, mais étant débutant je fais au mieux.

int A = 0;
int B = 1;
int C = 1;

Char MotBinaire = A + B + C // je souhaite obtenir 011, soit 3 bit. Je ne suis pas sur du type choisi.
Char* Pointeur = &MotBinaire;
RCSwitch.Send(Pointeur);

// Pour la partie reception : je récupère le 011 et fait un genre de "explode" pour recupérer chaque valeur.  (honnetement je n'ai pas encore bien refléchi à ce point).

Il existe probablement une meilleur solution mais je ne suis pas assez expérimenté.

Dans l'attente de votre aide.
En vous remerciant.

Bonne Journée.

1 Like

La question est ambiguë.
Un int peut contenir une valeur entre -32768 et + 32767. Donc on ne peut théoriquement pas faire entrer 3 int dans un char.

En admettant que A, B et C ne contiennent jamais que 0 ou 1 alors tu pourrais remplacer

par

char MotBinaire = A | B << 1 | C  << 2// je souhaite obtenir 011, soit 3 bit. Je ne suis pas sur du type choisi.

A noter:

  • il faut écrire char et non Char
  • les variables A, B et C pourraient être de type char ou mieux unsigned char cela économiserait de la RAM

et attention la fonction send attend une cString, c'est à dire un buffer de caractères terminé par un caractère nul. Vous ne pouvez pas donc juste envoyer MotBinaire car vous risquez d'envoyer tous les octets qui suivent en mémoire jusqu'à ce que vous rencontriez un 0.

donc plutôt un truc comme cela

// les états de A, B et C. Vrai si activé, faux sinon
bool A = false;
bool B = true;
bool C = true;

char message[2]; // 1 octet pour les états suivi du caractère nul de fin de chaîne

message[0] = (A ? 4 : 0)  |  (B ? 2 : 0)  |  (C ? 1 : 0); // on construit les 3 bits de poids faible ABC
message[1] = '\0'; // caractère nul marquant la fin du message
RCSwitch.Send(message);

attention aussi, si A, B et C sont faux, le premier octet sera nul et RCSwitch.Send() n'enverra rien du tout. Peut être c'est bien, peut être pas... Si vous voulez envoyer à tous les coups, il faut s'assurer qu'un bit qui ne sert pas soit toujours à 1, par exemple

message[0] = 128 | (A ? 4 : 0)  |  (B ? 2 : 0)  |  (C ? 1 : 0); // on construit les 3 bits de poids faible ABC et on met le bit de poids fort à 1 pour être sûr que l'octet est non nul

PS/
attention ça construit les bits dans l'ordre CBA et pas ABC

Déjà un grand merci pour vos retours.

Pour éclaicir un peu mes besoins les 3 variables à envoyés sont bien des bools en réalité.
Après étude de vos réponses j'ai réussi à coder le code ci-dessous :
J'avoue ne pas avoir compris la lignes 128 | (A ? 4 : 0) | (B ? 2 : 0) | (C ? 1 : 0)

bool A = false;
bool B = true;
bool C = false;
unsigned long CodeBin = A | B << 1 | C  << 2; // attention ça construit les bits dans l'ordre CBA 
mySwitch.send(CodeBin , 4);
delay(1000);
static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength) {
  static char bin[64]; 
  unsigned int i=0;

  while (Dec > 0) {
    bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0';
    Dec = Dec >> 1;
  }

  for (unsigned int j = 0; j< bitLength; j++) {
    if (j >= bitLength - i) {
      bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
    } else {
      bin[j] = '0';
    }
  }
  bin[bitLength] = '\0';
  
  return bin;
}

// ---- Dans le loop ------
if (mySwitch.available())
{
    digitalWrite(PIN_LED_ALARME,LOW);
    digitalWrite(PIN_LED_FORAGE,HIGH);
    char* value = dec2binWzerofill(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength());
    mySwitch.resetAvailable();
    Serial.println(  value );
     /* JE RECUPERE BIEN LE CODE BINAIRE MAIS JE SUIS BLOQUE POUR LE DISPACHER SUR LES 3 VARIABLES A, B ET C
}

En attendant vos retours sur ce code.

Merci et Bonne journée.

prenons les choses une par une

128 en binaire c'est 1000 0000
4 c'est 0000 0100
2 c'est 0000 0010
1 c'est 0000 0001

A est un booléen, une valeur de vérité (vrai ou faux). C'est comme le résultat d'une condition.

l'opérateur (dit ternaire) ? : fonctionne comme cela

condition ? valeur si vrai : valeur si faux

donc quand j'écris (A ? 4 : 0) c'est comme si j'écrivais "prends la valeur 4 si A est vrai, sinon prend la valeur 0"

ensuite il y a l'opérateur binaire | qui est le OU binaire qui va donc s'appliquer aux bits

0 | 0 c'est 0
1 | 0 c'est 1
0 | 1 c'est 1
1 | 1 c'est 1

donc quand je fais 128 | (A ? 4 : 0)

je dis

  • effectue une OU entre 1000 0000 et soit '0000 0000' si A est faux ➜ 1000 0000
  • effectue une OU entre 1000 0000 et soit '0000 0100' si A est vrai ➜ 1000 0100

vous voyez que ça permet de placer le bit au bon endroit pour A

on fait de même pour B et C et au final on a fabriqué 1000 0ABC (avec ABC qui valent 0 ou 1)


dec2binWzerofill() c'est l'artillerie lourde !

si vous avez un octet qui contient byte b = 0000 0ABC (avec ABC qui valent 0 ou 1) alors un simple masque et décalage vous permet d'obtenir ces bits

(b & 1) c'est C
(b & 2) >> 1 c'est B
(b & 4) >> 2 c'est A

D'abord Merci pour ton explication. C'était très bien expliqué.

Suite à ton retour j'ai repris le code comme ci-dessous :

// EMETTEUR
bool A = true;
bool B = true;
bool C = true;
unsigned long CodeBin = 8 | (A ? 4 : 0)  |  (B ? 2 : 0)  |  (C ? 1 : 0); // Utilise du 8 (soit 1000 en binaire) afin d'envoyer toujours les valeurs de A, B et C même lorsqu'elle valent FALSE
mySwitch.send(CodeBin , 4);
delay(1000);
// RECEPTEUR
if (mySwitch.available())
  {
    unsigned long R = mySwitch.getReceivedValue();
    C = (R & 1);
    B = (R & 2) >> 1;
    A = (R & 4) >> 2;
    Serial.print("Variable A : ");
    Serial.println(A);
    Serial.print("Variable B : ");
    Serial.println(B);
    Serial.print("Variable C : ");
    Serial.println(C);
    Serial.println("");
    delay(1000);
    mySwitch.resetAvailable();
  }

Je trouve ce code plus simple. J'imagine qu'on peut mieux faire mais pour ma part je trouve ça bien.
N'hésitez pas à me donner vos retours sur ce code.

Encore Merci et Bonne journée.

Très bien

Bonne continuation

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.