Test sur entrées numeriques

Bonjour, j'essaye de tester des entrées digitales branchées sur ma carte Arduino.
J'aimerais tester l'octet dans lequel j'ai rangé sur les 4 premiers bits les valeurs de mes entrées.
La valeur de mon octet apres avoir lu mes entrées est soit égale à 1111 1110 ou 1111 1101 ou 1111 1011 ou 1111 0111. Voici le test que j'ai réalisé :

for (int k=0; k<4; k++)
      {
       if ((input == (254+k)) | (input == ((0xFE<<k | 0xFE>>7))))

{
stock();
}
}

Je teste les 4 resultats possible et lorsque mon octet est egal a une de ces valeurs je rentre dans le if pour lancer une fonction ( je rentrerais donc qu'une seule fois dans le if ).
Je n'ai pas trouvé d'autres moyen que ceci, la premiere condition sert pour k=0 puis la deuxieme condition pour k=1 à 3. Mais cela ne marche pas, auriez vous une solution :s ?

if ((input & 0x0F) >= 1)

Bonjour,

Il suffit de tester si input vaut une des quatre valeurs (mais je ne suis pas sur d'avoir compris ton problème)

  if (input==B11111110 || input==B11111101 || input==B11111011 || input==B11110111)
  {}

Bonjour,

if ((input & 0x0F) >= 1)

Il me semble que lorsqu'une entrée est active, le bit correspondant passe à 0. Dès lors, aucune entrée activée équivaut à 0xFF et donc le test est vrai, ce qui est faux :wink:

Je pencherais plutôt pour

if ( (!input) & 0x0F  > 0 )

Pour eeaeea :
!input : On inverse la valeur de input (donc les bits à 1 deviennent 0 et les bits 0 deviennent 1
Exemple : 1111 1101 devient 0000 0010

& 0x0f : On effectue une opération booléenne de type "ET logique" bit à bit avec la valeur 0x0F (soit 0000 1111 en binaire)
Pour rappel, la table de vérité de & est la suivante :

0 0 1 1  
0 1 0 1  
-------
0 0 0 1

Donc notre exemple devient :

0000 0010
0000 1111
---------
0000 0010

Ainsi, on va garder que la partie des bits qui nous intéresse, à savoir, les 4 derniers à droite (dits bits de poids faible)
Si l'un de ceux-ci est à 1, la valeur résultante sera non nulle et donc le test sera vrai.
Cette technique te permet de tester en une opération la présence de plusieurs bits dans un mot.

Bon amusement !

Coyotte

ps: Désolé pour les boîtes de code un peu grandes...

Merci beaucoup pour vos réponses et astuces ! Je pense que j'ai mal posé le problème, je vais essayer d'être plus précis :

Si input vaut 1111 1110, j'aimerais pouvoir récupérer une variable égale à 0 pour l'utiliser dans ma fonction ( d'où la boucle for, qui me donnerait k égale à 0)
Si input vaut 1111 1101, j'aimerais récupérer une variable égale à 1 pour l'utiliser dans ma fonction
Si input vaut 1111 1011, j'aimerais récupérer une variable égale à 2 pour l'utiliser dans ma fonction
et si input vaut 1111 0111 avoir une variable égale à 3

C'est ce que j'ai essayé de faire en imbriquant un if dans un for, en faisant un test sur ces 4 valeurs, de manière a n'entrer qu'une seule fois dans le if et de pouvoir utiliser la valeur de k correspondante a la valeur de input qui va bien.

Mais en décomposant ma boucle, je ne trouve pas le problème :(, je rappelle les 2 lignes :

for (int k=0; k<4; k++)
      {
       if ((input == (254+k)) | (input == ((0xFE<<k | 0xFE>>7))))

Pour k=0, on teste si input vaut 254 (avec la première condition) ou 1111 1111 (avec la deuxième condition), donc si input vaut 1111 1110 (soit 254) on rentrera dans le if avec k=0 comme je le desire.

Maintenant, si input vaut 1111 1101 (soit 253), pour k=0 aucune condition n'est remplie pour rentrer dans le if, mais pour k=1 oui puisqu'on teste si input vaut 255 ou 1111 1101, donc cela devrait être bon.

Et pareil pour input=1111 1011 on rentre dans le if pour k=2
Et pour input=1111 0111 on rentre pour k=3

Mais le raisonnement ci-dessus est forcément faux puisque cela ne marche pas..

for (int k=0; k<4; k++){
  if ((!input)>>k == 1) {
         ....
   }
}

Merci beaucoup :slight_smile: ! J'ai une autre question, j'aimerais passer l'action de lecture de mes entrées et de l'écriture dans la variable input dans une fonction. Pour l'instant je le fais de la manière suivante :

for (int a=0; a<4; a++)
 {
  if (digitalRead(22+a) == 1)
  {
   bitWrite(input,a,1);
  }
  else 
  {
   bitWrite(input,a,0);
   }
 }

Mais lorsque je la passe dans une fonction comme ceci j'ai l'impression que la fonction ne fait rien

void readAndWrite(char pinArduino, char octet) 
{
 for (int a=0; a<4; a++)
 {
  if (digitalRead(pinArduino+a) == 1)
  {
   bitWrite(octet,a,1);
  }
  else 
  {
   bitWrite(octet,a,0);
   }
 }
}

comment sont déclarées ces variables ?
pourquoi les passer a la fonction en type char ?
tu devrais peut être présenter ton projet en globalité avec son code, car difficile de comprendre la finalité

Bonjour,

Dans void readAndWrite(char pinArduino, char octet), la variable octet est locale. Une fois que tu es sorti de la fonction sa valeur n'existe plus.
Si tu veux que le programme modifie la variable globale (ou au moins externe à la fonction), il faut la passer par référence

void readAndWrite(char pinArduino, char &octet)

J'ajoute que ça ne me semble pas la meilleure méthode, il vaudrait mieux que la fonction retourne un octet

byte readAndWrite(char pinArduino)
{
  byte octet=0;
  for (int a = 0; a < 4; a++)
  {
    if (digitalRead(pinArduino + a) == 1)
    {
      bitWrite(octet, a, 1);
    }
    else
    {
      bitWrite(octet, a, 0);
    }
  }

  return octet;
}

Bonjour ! Merci pour vos réponses ! J'aimerais revenir sur la boucle suivante

for (int k=0; k<4; k++){
  if ((!input)>>k == 1) {
         ....
   }
}

si je la remplace par les boucles ci dessous le programme fonctionne, mais pas avec ta boucle et je ne sais pas pourquoi :confused:

      if (input==254)
       {
        k=0;
        stock();
        } 
       if (input==253)
        {
         k=1;
         stock();
        }
        if (input==251)
        {
          k=2;
          stock();
        }
        if (input==247)
        {
          k=3;
          stock();
        }

Pour ce qui est du deuxième problème merci kamill tes méthodes fonctionnent :slight_smile:

Il faut utiliser le not binaire '~' et non le not logique '!'

for (int k=0; k<4; k++){
 if ((~input)>>k == 1) {
        ....
  }
}

Cela ne fonctionne pas, en verifiant avec des print on n'entre jamais dans le if, donc la condition n'est jamais vraie :(. Alors que je maintiens qu'avec ma boucle cela fonctionne je viens de retester

alors essayes comme cela

for (int k=0; k<4; k++){
 if ((((input&0xFF)^0xFF)>>k) == 1) {
        ....
  }
}

si input est unsigned il n'y a pas besoin de &0xFF

On ne connait pas le type de la variable input. Pour être sur il faut isoler les quatre premiers bits

for (int k=0; k<4; k++){
if ((~input & 0x0F)>>k == 1) {
      ....
}
}

Effectivement cette fois ci cela fonctionne ! La variable est un byte, pourquoi est il necessaire de rajouter des 0 sur les msb ?

Parce que je pense que quand on fait un not le compilateur convertit en entier ou en unsigned.

En utilisant vos réponses j'essaye d'appliquer ceci sur un autre exemple. Je voudrais tester l'égalité de ma variable input a celle de ma variable output, bit par bit pour pouvoir me servir du n ème bit de output qui serait potentiellement different du n ème bit de input.

      for (int n=0; n<4; n++)
      {
        if (output&(0x01<<n) == input&(0x01<<n))
       {
         // je ne fais rien pour l'instant
       }
       else
       {
        bitDifferent=n; // vue mon application, un seul bit peut etre different entre input et output 
       }
      }

Mais encore une fois je ne vois pas ou est le probleme... (les deux variables sont des bytes)

le problème c'est que en C l'opérateur & a une priorité très basse (contrairement à d'autres languages).
il faut des parenthèses

if ((output&(0x01<<n)) == (input&(0x01<<n)))