Calculer avec l’Arduino (2)
Les opérations sur les bits
. Par : Jean-Luc
Vous répondez à :
Bonsoir, j’essaie de comprendre la manipulation des bits et le calcul binaire.
Dans la bibliothèque d’une RTC (DS3231), j’ai une fonction pour lire la temperature.
J’ai une fonction if() pour voir si le bit 7 du registre vaut 1 (1-temp negative, 0-temp positive) :
if (tUBYTE & 0b10000000)
{
tUBYTE ^= 0b11111111;
tUBYTE += 0x1;
fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25);
fTemperatureCelsius = fTemperatureCelsius * -1;
}
return (fTemperatureCelsius);
Je n’arrive pas à décrypter le calcul (les 2 premières lignes dans la fonction if) car si je prends tUBYTE = 23 par exemple, je n’arrive pas à -23 au final.
Pourtant le sketch test fourni avec la bibliotèque me donne la bonne valeur. Donc je dois faire un mauvais calcul sur ma feuille quelque part.
22 Messages
-
Calculer avec l’Arduino (2) 11 mai 2015 00:19, par hicham
q’est ce que ne donne les deux lignes d’instruction suivante :
a=5; a=|a;
-
Calculer avec l’Arduino (2) 11 mai 2015 09:54, par Jean-Luc
La première met la valeur 5 dans la variable
a
.
La seconde n’est pas une expression possible en langage Arduino/C. Je suppose qu’il y a une faute de frappe et que vous vouliez écrirea |= a;
. C’est l’équivalent dea = a | a;
eta | a
est égal àa
. Donc l’expression se réduit àa = a;
-
Calculer avec l’Arduino (2) résultat des pins sur var a et var b 19 juillet 2016 21:47, par anbze
Bonjour ,Cela fait deux semaines que j’ étudie Arduino et je me casse la tête pour trouver une solution : c’ est à dire comment utiliser deux capteurs a et b , les rentrer dans deux variables (x et y) et diviser les données de "x" par les données de "y" et sortir le résultat sur les pins de l arduino. Par comparaison avec le Pic, Et encore moins comment rentrer je ne trouve pas l’ accumulateur "W" sur l arduino.
Je suis habitué aux Pics où il fallait mettre le premier chiffre dans la variable "x" et le deuxième dans la variable "y" mais avec arduino je ne sais pas comment rentrer les données des pins dans les variables "x".
et "y".
J espère que j ai été assez explicite et vous remercie de votre réponse.-
Calculer avec l’Arduino (2) résultat des pins sur var a et var b 20 juillet 2016 10:12, par dominique
Êtes-vous certain que votre question à un rapport avec le modélisme ferroviaire ?
Quel est le cadre dans lequel s’inscrit votre question ?Je pense que vous devriez commencer par lire un livre d’introduction à l’Arduino et au langage C : vous y trouverez votre réponse.
Vous avez aussi des articles sur les entrées-sorties, notamment sur le site officiel :
-
-
Convertir une valeur binaire en texte 9 mai 2019 16:56, par Romain
Bonjour,
j’essaye de convertir une suite de 1 et 0 ( par ex : x=01001000 )en une lettre ( Ici x = H)Je ne sais pas sous quel forme (char,int,..) initialiser ma variable (x) et je ne sais également pas ce qu’il faut ecrire pour convertir ma variable.
J’ai réussit a faire l’inverse mais la je bloque.Merci de votre réponse .
Programme pour convertir "Hector" en binaire :
void loop() { String myText = "Hector"; for(int i=0; i<myText.length(); i++) { char myChar = myText.charAt(i); for(int i=7; i>=0; i--) { String bytes = String( bitRead(myChar,i)); } } }
-
Bonsoir,
X est une chaîne de caractères ?
-
Entait c’est ce que je cherche a savoir !
J’essaye de faire un système LI-Fi (transport d’information par la lumière) En locurrence on transmet des 1 avec une led allumée et 0 avec une led éteinte
J’arrive à envoyer mon message et à le recevoir mais je ne sais pas comment "stocker" et convertir en lettre mon message binaire.-
Ok, vous recevez des 0 et des 1 et vous voulez les accumuler dans un octet. Si
b
est le bit reçu etlettre
la lettre :byte b; unsigned char lettre;
alors après avoir initialisé
lettre
à 0 et en supposant que vous receviez le bit de poids fort en premier, pour chaque bit, on fait :lettre = (lettre << 1) | b;
Si par contre c’est le bit de poids faible qui est reçu en premier, on fera :
lettre = (lettre >> 1) | (b << 7);
Il faut par contre bien recevoir 8 bits
À la fin,
lettre
contient ce que vous voulez.-
Bonsoir,
J’ai essayer votre solution mais je n’arrive pas a afficher "lettre" dans un Serial.print
Et je n’ai pas compris la ligne de code donc je ne peux pas l’adapter (Pas besoin d’expliquer si cest trop long)Merci de votre réponse.
-
Rajoutez
(char)
juste avantlettre
dans leSerial.print
-
Bon je désespère un peu, lorsque j’écrit Serial.print(lettre) j’obtiens que des 0 et pour Serial.print((char)lettre) je n’obtient rien !
Je vous laisse mon programme si vous avez des idée je suis preneur.
boolean Start = true; //this is used to determine if the counting has started byte b ; unsigned char lettre = 0 ; void setup() { Serial.begin(9600); } void loop() { // read the sensor value int sensorValue = analogRead(A0); for (int i=0 ; i<=7 ; i++) { // read the sensor value int sensorValue = analogRead(A0); if (Start==true && sensorValue>850) { // if the counting has not yet started and the light is on b = 1 ; delay (1000); } if (Start== true && sensorValue<850) { // if the counting has started and the light is off b = 0 ; delay (1000); lettre = (lettre << 1) | b; } } Serial.print( (char) lettre) ; Serial.print(" ") ; }
-
Bonjour,
Des idées j’en ai plusieurs :
- j’ai remis l’indentation d’équerre. L’indentation ce n’est pas que pour faire beau, ça permet de trouver les bugs puisqu’elle renseigne sur la structuration du programme. Si vous ne faites pas des efforts sur l’indentation vous allez écrire des choses fausse sans le voir.
- À quoi sert la ligne 13 ?
sensorValue
n’est pas utilisé et est écrasé ligne 17. - Dans le
if
de la ligne 18 à 22, vous ne faites rien deb
. - Si
sensorValue
est exactement égal à 850, que devrait-il se passer ? - Je soupçonne que ce qui est ligne 29 devrait être deux lignes plus bas.
- On n’écrit jamais deux
if
qui sont censés être mutuellement exclusifs, on met un else à la place :
if (Start == true) { if (sensorValue > 850) { b = 1 ; } else { b = 0; } lettre = (lettre << 1) | b; delay(1000); }
ou plus concis :
if (Start == true) { lettre = (lettre << 1) | ((sensorValue > 850) ? 1 : 0); delay(1000); }
-
-
-
-
-
-
-
-
Calculer avec l’Arduino (2) 14 mai 2020 16:20, par JeeLet
.. des info sur | le OR binaire.
-
Calculer avec l’Arduino (2) 20 mai 2020 17:57, par Nicolas
Félicitations pour vos articles. Vraiment une pédagogie sans pareil.
Je voudrais s’il vous plait si c’est possible de mettre dans chaque article ou sur quelques un pourquoi on utilise, tel ou tel élément. Par exemple pour quoi on utiliserait les opérateurs de décalage. Dans quelle but ? Comme ça on cible nos besoins et on comprends mieux pourquoi on utiliserait plus une opération qu’une autre.
Merci encore-
Bonjour,
Merci beaucoup pour votre commentaire. J’ai complété l’article avec un exemple qui illustre l’emploi du<<
et du>>
mais également du&
, du|
et du~
.
-
-
calculer en binaire 8 février 2021 19:35, par Nicolas
Bonsoir, j’essaie de comprendre la manipulation des bits et le calcul binaire.
Dans la bibliothèque d’une RTC (DS3231), j’ai une fonction pour lire la temperature.
J’ai une fonction if() pour voir si le bit 7 du registre vaut 1 (1-temp negative, 0-temp positive) :if (tUBYTE & 0b10000000) { tUBYTE ^= 0b11111111; tUBYTE += 0x1; fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25); fTemperatureCelsius = fTemperatureCelsius * -1; } return (fTemperatureCelsius);
Je n’arrive pas à décrypter le calcul (les 2 premières lignes dans la fonction if) car si je prends tUBYTE = 23 par exemple, je n’arrive pas à -23 au final.
Pourtant le sketch test fourni avec la bibliotèque me donne la bonne valeur. Donc je dois faire un mauvais calcul sur ma feuille quelque part.-
calculer en binaire 8 février 2021 21:37, par Jean-Luc
Bonsoir,
Les deux premières lignes font une complémentation à 2 :
- La première ligne inverse tous les bits (ou exclusif avec tous les bits à 1)
- La seconde ligne ajoute 1
Il n’y a aucune raison qu’une valeur de 23 pour
tUBYTE
produise un résultat de -23. En effet, le bit 7 est à 0 et la condition du if est fausse.-
calculer en binaire 9 février 2021 10:26, par Nicolas
Bonjour, oui je me suis trompé, je voulais bien dire tUBYTE= -23 et non pas 23.
Reprenons cette boucle if() ligne par ligne : (on garde tUBYTE= -23 soit 0b10010111 et tLRBYTE= 0)if(tUBYTE & 0b10000000) { tUBYTE ^= 0b11111111; tUBYTE += 0x1; fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25); fTemperatureCelsius = fTemperatureCelsius * -1; }
"if(tUBYTE & 0b10000000)" : je lis Si( 0b10010111 et 0b10000000), je ne comprends pas ce qu’est la condition vraie ?
Si on calcule 0b10010111 & 0b1000000, on obtient 0b10000000. Doit-on lire Si(0b10000000) ? Ca reviendrait à dire "Si(resultat de tUBYTE & 0b10000000 vaut 0b10000000), la condition est vraie" ? On aurait pu donc l’ecrire : if(tUBYTE & 0b10000000 == 0b10000000) ?"tUBYTE ^= 0b11111111 ;" : je lis tUBYTE = tUBYTE ^ 0b11111111 soit tUBYTE = 0b10010111 ^ 0b11111111 = 0b01101000.
"tUBYTE += 0x1 ;" : je lis tUBYTE (calculé juste au-dessus) = tUBYTE + 0b00000001 soit tUBYTE = 0b01101000 + 0b00000001 = 0b01101001.
"fTemperatureCelsius = tUBYTE + ((tLRBYTE >> 6) * 0.25) ;" : je lis fTemperatureCelsius = 0b01101001 + 0 = 0b01101001 soit 105.
"fTemperatureCelsius = fTemperatureCelsius * -1 ;" : je lis fTemperatureCelsius = 105* -1 = -105. Donc -105°C.
Il y a donc quelque chose que je ne lis pas correctement, mais quoi ?
-
calculer en binaire 9 février 2021 18:10, par Jean-Luc
Bonsoir.
En C, une expression est considérée vrai si elle est différente de 0. Par conséquent
tUBYTE & 0b10000000
sera vrai si le bit 7 detUBYTE
est à 1.–23 est égal à 0b11101001 en complément à 2 (Pas à 0b10010111). Le ou exclusif avec un octet dont tous les bits sont à 1 inverse tous les bits. On a donc 0b00010110. En ajoutant 1 on a 0b00010111, ce qui est égal à 16 + 4 + 2 + 1 = 23 (on a pris l’opposé).
-
calculer en binaire 9 février 2021 18:20, par Nicolas
Merci pour ces précisions.
Je vais étudier cette histoire de complément à 2 car c’est cela qui m’induit en erreur.
Encore merci pour tout ce travail.
-
-
-