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 ?
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
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..
Merci beaucoup ! 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
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é
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;
}
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
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)