Go Down

Topic: Faire de 5 booleans une variable type 00010 (Read 3568 times) previous topic - next topic

J-M-L

#30
Apr 23, 2018, 12:12 pm Last Edit: Apr 23, 2018, 12:24 pm by J-M-L
Quote
Du binaire pour avoir des valeurs à traiter sous la forme B00100 ?? merveilleux! Comment on fait?
si vous voulez "packer" des booléens dans un octet (pour que chaque bit représente une valeur de vérité) et que vous ne voulez pas vous embêter à jouer vous même avec des masques et des décalages de bits lisez les fonctions (macros) de traitement de bits

Bits and Bytes
bit()
bitClear()
bitRead()
bitSet()
bitWrite()
highByte()
lowByte()


si vous voulez imprimer un octet avec des 0 devant - ce que ne fait pas Serial.print par défaut - il faut vous faire une petite fonction (cf mon code posté ci dessus, il n'en imprime que 5 mais libre à vous de commencer la boucle à 7 au lieu de 4 :

Code: [Select]
void printBits(byte aByte)
{
  Serial.print(F("B"));
  for (int8_t aBit = 7; aBit >= 0; aBit--)
    Serial.print(bitRead(aByte, aBit) == 0 ? F("0") : F("1")); // cf https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitread/
  Serial.println();
}
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

kammo

#31
Apr 23, 2018, 12:30 pm Last Edit: Apr 23, 2018, 12:34 pm by kammo
bitWrite

bitWrite(x, n, b) permet d'écrire un bit. Le premier argument, x est la donnée où on écrit le bit, le second argument, n est le numéro du bit et le 3e, b est la valeur à écrire, 0 ou 1.

byte a = 5;      //  5 en base 10 est égal à  00000101 en binaire
bitWrite(a,3,1);
écrira un 1 dans le bit 3. La valeur contenue dans a sera donc 00001101.



D'accord, on partirait de 11111 (tout blanc) et on met un 0 (noir) là où le capteur correspondant à la position dans la chaine 11111 voit du noir.
Si le capteur LC voit noir (je rappelle les capteurs LL LC CC CR RR), on obtient 10111 = tourne à gauche.

Est-ce que c'est plus rapide de faire comme ça que de lire la valeur et la multiplier par un multiple de 10 comme je le fais? Ca je peux pas le pondre,j'ai aucune idée de ce que ça donne une fois compilé.

Cool, on a notre "trajectoire" sous la forme 11011 souhaitée. Sauf que:
1-Comment on écrit ça du coup? (je continue de chercher hein, je mendie pas)
2-Et après je traite ça avec un switch/case ? Trop lent?

Avec switch/case, je me retrouve comme le mentionne pepe avec plein de combinaisons:
11011tout droit
00000 intersection, continuer tout droit
00011 angle 90° gauche
10111 = 01111 = 00111 = 10011 on tourne à gauche, l'angle diffère mais on s'comprend

Des cas réels mais dont on n'a rien à fichtre:
01011 = bon bah j'ai laissé un morceau de scotch à côté du circuit. dans certaines course, c'est un marqueur pour prévenir que ça va tourner, ou qu'il y a une priorité à effectuer.
01010 = mon robot s'est perdu sur un échiquier

Pour être franc, j'aime beaucoup l'idée de travailler comme ça, c'est à ma portée, c'est clair, mais ça fait beaucoup de lignes pour le comparateur... mais si on en fait des fonctions, on s'en fichtre pas un peu? C'est pas sensé marcher vite une fonction?
L'avantage, c'est que chaque case peut lancer une fonction qui détermine l'angle (ouais, vous avez pas fini, pask'un cosinus je sais pas ce que c'est) du différentiel, mais aussi la vitesse du robot (attention 7,4v je passe le mur du son facile)

Sinon, ya quoi?


Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

RIN67630

#32
Apr 23, 2018, 12:50 pm Last Edit: Apr 23, 2018, 12:52 pm by RIN67630
pas de panique!

Tu encodes tes 5 entrées sur un octet Traj avec n'importe laquelle des methodes binaires proposées.

ensuite B01001 ou 9 sont deux présentations de la même chose.

Tu ecris
switch (Traj)
{
case B00011:  // C'est kif-kif avec case 3:
break;

//case: ...


default:         // pour tous les cas non prévus
// allumer une Led rouge ou déclancher une attque nucléaire...
break;
}
Si tu veux deboguer Traj sur la console tu ecris Serial.print(Traj, BIN)

C'est aussi simple que ca.

C#est aussi simple que celà

kammo

J'ai du pain sur la breadboard :)

Bon donc le switch/case n'était pas le problème, le problème c'était de traiter un long int ?

J'ai fait un essai avec ma méthode, le robot s'est planté dans le panier du chien ^^ Il fait n'importe quoi ^^

Bon j'essaie de piger cette histoire de binaire, merci
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

kammo

Avec
Code: [Select]
int Traj= digitalRead(PinLL)+ digitalRead(PinLC) <<1  +digitalRead(PinCC)<<2 + digitalRead(PinCR) <<3 + digitalRead(PinRR) <<4;



On obtient
0
0
0
0
1024
1024
1024
2048
1024
2048
2048
0
0
0
0
0
0
0
0
0
C'est pas très binaire tout ça

Je précise que j'ai déclaré mes pins en byte, comme ça plantait avec les booleans ...


Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

kammo

J'essaie donc la méthode J-M-L
Son bout de code marche bien avec le random, je vais adapter ça à mes capteurs (dit-il confiant)
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

J-M-L

#36
Apr 23, 2018, 01:32 pm Last Edit: Apr 23, 2018, 01:55 pm by J-M-L
en binaire on a des bits (0 et 1 - base 2). Un octet a 8 positions (8 bits)
en décimal on a dix symboles (0 à 9 - base 10)

utiliser la base 10 ne présente aucun intérêt, vous allez devoir utiliser bcp de mémoire pour représenter au final quelque chose qui nécessite qu'un seul bit.

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

kammo

Je pars sur ce code, je le comprends (presque tout).
Par contre, pour l'adapter, j'ai un souci évident de syntaxe:

  b0 = (digitalRead (PinRR)) == 0); // une valeur 0 ou 1 transformée en booléen

Je peux pas le faire là, comme ça?
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

kammo

Bon, je fais pipi par terre et je me roule dedans.

J'ai pas encore trouvé, je vais marcher un peu ^^
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

J-M-L

#39
Apr 23, 2018, 03:04 pm Last Edit: Apr 23, 2018, 03:06 pm by J-M-L
Je pars sur ce code, je le comprends (presque tout).
Par contre, pour l'adapter, j'ai un souci évident de syntaxe:

  b0 = (digitalRead (PinRR)) == 0); // une valeur 0 ou 1 transformée en booléen

Je peux pas le faire là, comme ça?
comme ça ce serait sans doute mieux
Code: [Select]
b0 = (digitalRead (PinRR) == HIGH); // HIGH ou LOW suivant comment c'est configuré
ce code met b0 à vrai si le pin PinRR est HIGH

les parenthèses sont optionnelles, c'est juste pour vous facile la lecture - on met dans b0 le résultat d'une comparaison (==) donc une valeur de vérité
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

kammo

Ah j'étais pas loin. Mais j'y étais pas ^^
Merci m'siô !
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

J-M-L

si si vous y étiez - juste que puisque un digitalRead() retourne HIGH ou LOW (même si c'est 1 et 0) c'est mieux de tester avec ces valeurs là...
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

kammo

Très fin, du coup je comprends le code! merci encore
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

RIN67630

Avec
Code: [Select]
int Traj= digitalRead(PinLL)+ digitalRead(PinLC) <<1  +digitalRead(PinCC)<<2 + digitalRead(PinCR) <<3 + digitalRead(PinRR) <<4;



On obtient
0
0
0
0
1024
1024
1024
2048
1024
2048
2048
0
0
0
0
0
0
0
0
0
C'est pas très binaire tout ça

Si! C'est parfaitment binaire!

Remplace ton Serial.print(Traj); par Serial.print(Traj, BIN); et admire le résultat.

kammo

J'ai encoooore un souci. pour tourner à 90 degrés, il devient capricieux.
J'ai des soucis avec le sens des roues etc. Avec des if, il fait n'importe quoi, j'essaie avec switch/case:

Code: [Select]
void VIRAGE90(byte sens) { // virage 90°
  //vitesse max
  analogWrite(E1, 255);
  analogWrite(E2, 255);

  //pivot
  switch (sens) {
    case : 00011
        Serial.println("90G");
      digitalWrite(I1, HIGH);
      digitalWrite(I2, LOW);
      digitalWrite(I3, LOW);
      digitalWrite(I4, HIGH);
      break;
    case : 11000
        Serial.println("90D");
      digitalWrite(I1, LOW);
      digitalWrite(I2, HIGH);
      digitalWrite(I3, HIGH);
      digitalWrite(I4, LOW);
      break;
  }


et là, badaboum:
expected primary-expression before ':' token

Soit je suis fatigué, soit... c'est le pastis
Make it, or make it burn.
carte des membres:
https://drive.google.com/open?id=1QmXJT44QyZHM3SIgDaMo7MGUbBSKAaVD&usp=sharing

Go Up