Arduino Forum

International => Français => Topic started by: kammo on Apr 22, 2018, 03:56 pm

Title: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 03:56 pm
Bonjour
Cinq capteurs en digital, cinq variables booléennes.
Comme je veux comparer toutes les combinaisons (robot line follower), je pense qu'il sera plus aisé de "combiner" ces cinq variables pour en obtenir une qui comporte cinq chiffres, de 0 à 1. Je veux une variable  faite de 1 et de 0.
Dans un switch case ca fera très joli, et question relecture, c'est top.

case 00100 > tout droit
case 00010 > tourne à droite
case 00001 > tourne à fond à droite

Vous voyez l'idée?
Comment fait-on? :D
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 04:05 pm
Bonjour
Cinq capteurs en digital, cinq variables booléennes.
Comme je veux comparer toutes les combinaisons (robot line follower), je pense qu'il sera plus aisé de "combiner" ces cinq variables pour en obtenir une qui comporte cinq chiffres, de 0 à 1. Je veux une variable  faite de 1 et de 0.
Dans un switch case ca fera très joli, et question relecture, c'est top.

case 00100 > tout droit
case 00010 > tourne à droite
case 00001 > tourne à fond à droite

Vous voyez l'idée?
Comment fait-on? :D
Garçon, l'addition s'il vous plaît!
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 04:16 pm
Haha ^^
et bah non, paske 1+0+0+0+0 ça fait pas 10000 mais ... la tête à tototo
Bon, et sans déconner? :D
Title: Re: Faire de 5 booleans une variable type 00010
Post by: jfs on Apr 22, 2018, 04:20 pm
Tu multiplie par l'emplacement où il va se trouver et tu additionnes.

tout à droite multiplie par 1 (pas indispensable...)
le deuxième à droite par 10
le troisième par 100
etc

Tu additionnes le tout après coup et hop....
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 04:21 pm
+1
Bravo
C'est futé ... Merci
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 04:28 pm
Du coup, c'est plus des booleans... On y servivra
Autre problème, comment je lui dis que chaque valeur compte 5 chiffres pour éviter ceci:

110
1000
11000
11000
11000
1
0
0
0
110
1000
0
0
0
1110
Title: Re: Faire de 5 booleans une variable type 00010
Post by: jfs on Apr 22, 2018, 04:35 pm
tu mets six positions avec un 1 tout à gauche et tu ne lis que les 5 autres....  :smiley-mr-green:
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 04:37 pm
Futé, mais ya pas plus propre?
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 04:42 pm
Haha c'est la cata:

-3002
16960
-14112
27960
17070
16960

Code: [Select]
  VarLL = digitalRead(PinLL) * 10;
  VarLC = digitalRead(PinLC) * 100;
  VarCC = digitalRead(PinCC) * 1000;
  VarCR = digitalRead(PinCR) * 10000;
  VarRR = digitalRead(PinRR) * 100000;

  int Traj = 1000000 + VarLL + VarLC + VarCC + VarCR + VarRR;


En fait ça ne marche pas parce qu'on multiplie 0 par qch. En plus, mes valeurs relevées sur les pins ne sont plus booléennes, ça fait joli, mais c'est pas ce que je cherche à faire ....
Title: Re: Faire de 5 booleans une variable type 00010
Post by: jfs on Apr 22, 2018, 04:47 pm
Il faut convertir tes boléens avant de les multiplier

à part faire une chaine.... pas sur que ce soit possible plus propre.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 05:45 pm
Tu multiplie par l'emplacement où il va se trouver et tu additionnes.

tout à droite multiplie par 1 (pas indispensable...)
le deuxième à droite par 10
le troisième par 100
etc

Tu additionnes le tout après coup et hop....
Euh, un programmeur doit d'abord penser en binaire!

Si pin1, ajoute 1
Si pin2, ajoute 2
Si pin3, ajoute 4
Si pin4, ajoute 8
etc.

pour l'utilisation:
case B00100 > tout droit
case B00010 > tourne à droite
case B00001 > tourne à fond à droite

Sacrebleu!
Title: Re: Faire de 5 booleans une variable type 00010
Post by: lesept on Apr 22, 2018, 05:51 pm
Pour multiplier par 2, il y a l'instruction "<<1", par 4 "<<2" etc.
Donc tu peux faire un truc comme

Code: [Select]
(B5 << 5) + (B4 << 4) + (B3 << 3) + (B2 << 2) + (B1 << 1) + B0

où B0 à B5 sont les 6 bits à regrouper : cool non ?

Donc :
Code: [Select]
Traj= digitalRead(PinLL)+ digitalRead(PinLC) <<1  +digitalRead(PinCC)<<2 + digitalRead(PinCR) <<3 + digitalRead(PinRR) <<4;
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 06:26 pm
Pour multiplier par 2, il y a l'instruction "<<1", par 4 "<<2" etc.
Donc tu peux faire un truc comme

Code: [Select]
(B5 << 5) + (B4 << 4) + (B3 << 3) + (B2 << 2) + (B1 << 1) + B0

où B0 à B5 sont les 6 bits à regrouper : cool non ?

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

On ne doit pas faire d'arithmetique avec des booleans!
Si "False" est toujours 0, "True" peut être tout sauf zero.
Suivant le compilateur et le processeur ca peut être 1 ou 255 ou 65535 ou...

On commence avec
Code: [Select]
Traj=0;
if (digitalRead(PinLL)) Traj++;
Traj = Traj << 1;
if (digitalRead(PinLC)) Traj++;
Traj = Traj << 1;

etc...

Bon, un vrai programmeur Arduino lira le registre en une fois, basta*!
Avec par exemple les entrées de D8 à D13

Code: [Select]
DDRB = 0;    //mettre les entrées en mode digital input
Traj = PINB & B0011111;  // lire les 8 entrées et masquer les 2 inutiles.


Fini!

*au prix de la compatibilité de son code
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 06:49 pm
Punaise
Je sais pas si c'est l'heure ou l'apéro, mais là, je suis dépassé.
Par contre c'est super intéressant.
Pour les << je connaissais pas, je me fais des exercices demain pour que ça rentre, merci lesept.
Par contre le PINA je vois pas d'où il sort.
J'avance dans mes projets, mais en code comme en électronique, je découvre encore plein de bases que je n'ai pas, j'apprends sur le tas. Pour dire, les && et trucs avec des !! j'ai du mal à les lire, mais ça va venir.

Merci pour vos contributions, reste à déchiffrer tout ça et à comprendre pourquoi vous n'êtes pas d'accord ^^

Bon apéro, bon appétit !
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 06:55 pm
Punaise
Je sais pas si c'est l'heure ou l'apéro, mais là, je suis dépassé.
Par contre c'est super intéressant.
Pour les << je connaissais pas, je me fais des exercices demain pour que ça rentre, merci lesept.
Par contre le PINA je vois pas d'où il sort.
J'avance dans mes projets, mais en code comme en électronique, je découvre encore plein de bases que je n'ai pas, j'apprends sur le tas. Pour dire, les && et trucs avec des !! j'ai du mal à les lire, mais ça va venir.

Merci pour vos contributions, reste à déchiffrer tout ça et à comprendre pourquoi vous n'êtes pas d'accord ^^

Bon apéro, bon appétit !
A lire absolument! (https://www.arduino.cc/reference/en/)
pour PINA-iller:
 Bidouiller avec les registres (http://www.elecrom.com/avr-tutorial-2-avr-input-output/)
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 22, 2018, 07:18 pm
Je lis ça demain!

En attendant, ceci semble fonctionner:

Code: [Select]
  VarLL = digitalRead(PinLL) * 1;
  VarLC = digitalRead(PinLC) * 10;
  VarCC = digitalRead(PinCC) * 100;
  VarCR = digitalRead(PinCR) * 1000;
  VarRR = digitalRead(PinRR) * 10000;






  long int Traj = 100000 + VarLL + VarLC + VarCC + VarCR + VarRR; //on obtient une variable à 6 chiffres, le premier ne sert à rien^^

  Serial.println(Traj);



Ca renvoie

1   0   100   1000   10000
111101
 
0   10   100   1000   10000
111110
 
0   10   100   1000   10000
111110
 
1   0   100   1000   10000
111101
 
1   0   100   1000   10000
111101
 
1   0   0   1000   10000
111001
 
1   0   0   1000   10000
111001
 
1   10   0   1000   10000
111011
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 07:36 pm
Je lis ça demain!

En attendant, ceci semble fonctionner:

Code: [Select]
  VarLL = digitalRead(PinLL) * 1;
  VarLC = digitalRead(PinLC) * 10;
  VarCC = digitalRead(PinCC) * 100;
  VarCR = digitalRead(PinCR) * 1000;
  VarRR = digitalRead(PinRR) * 10000;
  long int Traj = 100000 + VarLL + VarLC + VarCC + VarCR + VarRR; //on obtient une variable à 6 chiffres, le premier ne sert à rien^^

  Serial.println(Traj);




Faire ensuite un switch() avec un long int...
Moi, j'aurais pas osé!

Tiens nous au courant.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: lesept on Apr 22, 2018, 07:40 pm
Non!

On ne doit pas faire d'arithmetique avec des booleans!
Si "False" est toujours 0, "True" peut être tout sauf zero.
Et ça :
Code: [Select]
Traj= byte(digitalRead(PinLL))+ byte(digitalRead(PinLC)) <<1  +byte(digitalRead(PinCC)) <<2 +
byte(digitalRead(PinCR)) <<3 + byte(digitalRead(PinRR)) <<4 + 1 <<5;
ça se tente, non ?
Pour le même prix j'ajoute le 1 au début :)
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kamill on Apr 22, 2018, 07:47 pm
Non!

On ne doit pas faire d'arithmetique avec des booleans!
Si "False" est toujours 0, "True" peut être tout sauf zero.
Suivant le compilateur et le processeur ca peut être 1 ou 255 ou 65535 ou...
Bonjour,

digitalRead() n'est pas un booléen, mais un int. La valeur retournée est soit HIGH soit LOW.

Quand lesept fait
Code: [Select]
Traj= digitalRead(PinLL)+ digitalRead(PinLC) <<1  +digitalRead(PinCC)<<2 + digitalRead(PinCR) <<3 + digitalRead(PinRR) <<4;
Il assume que HIGH vaut 1.
Ce n'est pas très portable, mais guère moins que lorsqu'on fait
Code: [Select]
if (digitalRead(PinLL)) Traj++;
ce qui assume que HIGH est différent de 0.

Pour ma part, si j'avais à le faire j'utiliserai la solution de lesept, car c'est la solution la plus élégante et il y a quand même de grandes chances que HIGH reste à 1 dans les futures révisions du framework.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 08:24 pm
Et ça :
Code: [Select]
Traj= byte(digitalRead(PinLL))+ byte(digitalRead(PinLC)) <<1  +byte(digitalRead(PinCC)) <<2 +
byte(digitalRead(PinCR)) <<3 + byte(digitalRead(PinRR)) <<4 + 1 <<5;
ça se tente, non ?
Pour le même prix j'ajoute le 1 au début :)
Pourquoi ajouter 1 au début? Juste pour tromper l'ennemi?

Dans le code, on met les zeros non significatifs qu'on veut.

case B00100:
Title: Re: Faire de 5 booleans une variable type 00010
Post by: Jambe on Apr 22, 2018, 08:45 pm
C'est tordu la façon de faire, il faut lire le port en entier, comme le suggère RIN67630.

J'essaie d'expliquer. Les broches de ton microcontroleurs sont regroupés en « port ». Un port regroupe 8 broche et l'état du port entier est stocké dans un registre du micro, soit une variable que tu peux lire mais pas modifier. Si toute les broches sont à 0, le registre du port sera égal à 0b00000000, si une sur deux sont à 1 alors ob0101010 etc...

Quand tu fais un appel à digitalRead(), tu demande à aller lire un bit bien particulier du port pour en extraire sont état.

Faire ce que tu fais, c'est en gros aller lire les bits un par un pour aller ensuite reconstituer un octet.

Regroupe tes capteurs sur le même port, lis ton port et agis en conséquence.
C'est un plus le seul moyen que tu as pour lire tes entrées exactement en même temps.
Avec un digitalRead(), le temps de les enchaîner, la première lecture est peut être déjà plus la même

Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 09:34 pm
En effet, ici, transcrire cinq variables booléennes en une unique variable entière ne s'avère utile qu'à la compréhension du programme par le développeur.
C'est bien le but: ecrire le code dans un switch(Traj)
et de définir les actions à réaliser par des case: correspondants.
Ca fait du code simple et clair.

Par contre il FAUT coder en binaire dans un octet.
Faire un switch(Traj) sur une variable longue est une heresie.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 10:12 pm
...
Si par exemple les pins appartiennent à plusieurs ports ou ne sont pas présentées de façon consécutives sur un même port, et si leur lecture doit être réalisée (quasiment) simultanément...
D'après la description de l' OP, c'est des capteurs de proximité. Rien à craindre si on les capture a la queue-le-leu. Pas la peine de compliquer la sauce.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 10:14 pm
Si le switch() correspond bien au traitement à réaliser (ce dont je ne suis pas certain, compte tenu de l'usage probable des boutons), alors il faut l'utiliser.

Mais si sa seule utilité est de faire du code simple et clair, alors on est certainement dans l'erreur. Quand il s'agit de petits micro-contrôleurs, le programme ne doit pas imposer à la machine de ré-exécuter chaque fois le travail que le développeur ne s'est pas donné la peine de faire au moment du codage.
Non. Une instruction switch() est très efficace et genère un code très compact.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 10:33 pm
Une instruction switch() qui ne justifie pas coûtera toujours plus cher en ressources que le code optimum sans switch(). Par ailleurs, on constate que avr-gcc remplace presque toujours les switch() courts en une succession de if()/else.
Dans le cas présent le code avec switch est optimum.
Même un UNO poussif fera le boulot avec 95% de idle...

Quote
Dans le cas d'un suiveur de ligne, je doute de l'utilité de traiter des valeurs comme 10101, 11011, 00101, etc. . On aurait certainement gros à gagner à ne traiter que les quelques cas de figure auxquels on s'attend vraiment (au lieu de 32), directement à partir de l'état des cinq capteurs.
C'est bien l'avantage de switch().
On ne met que les case: dont on a besoin.
Clair, net et concis.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 10:44 pm
Désolé, mais faire du travail inutile n'est jamais optimum.

Et l'on ne peut juger des ressources restantes que sur le système complet. Si le reste du code consomme 96%, alors les 95% non utilisés par le bout de code qu'on considère s'avèreront insuffisants.
Quel "travail inutile", quel "reste du code"?
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 22, 2018, 11:15 pm
Le travail inutile que j'évoquais au post #27.
Tu te mords la queue. Ce "travail inutile" n'existe que dans ta tête.
Les problèmes ca se résoud quand ils se posent, inventer des hypothèses n'avance à rien.

Reviens quand tu auras programmé quelques robots en fuzzy-logic sous freeRTOS...
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 23, 2018, 08:36 am
[exemples idiots...]
On peut laisser tomber la discussion.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 10:25 am
Pour revenir à la base (même si pas adapté) voici un petit exemple qui devrait être simple à lire et comprendre sur comment bâtir un octet avec 5 flags et l'imprimer

Code: [Select]
void print5bits(byte aByte)
{
  Serial.print(F("B"));
  for (int8_t aBit = 4; 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();
}

void setup() {
  Serial.begin(115200);       // console Série à 115200 bauds
  randomSeed(analogRead(A0)); // on initialise le générateur de nombre aléatoire avec un peu de variabilité
}

void loop() {
  boolean b4, b3, b2, b1, b0;
  byte b = 0;

  b0 = (random(2) == 0); // une valeur 0 ou 1 transformée en booléen
  b1 = (random(2) == 0);
  b2 = (random(2) == 0);
  b3 = (random(2) == 0);
  b4 = (random(2) == 0);

  // on construit un octet avec des 1 pour chaque booléen qui est à vrai
  b = (b4 ? B10000 : B0) | (b3 ? B1000 : B0) | (b2 ? B100 : B0) | (b1 ? B10 : B0) | (b0 ? B1 : B0) ;
  print5bits(b);

  delay(500); // on attend un peu
}



La console Série (réglée à 115200 bauds) m'affiche alors
B11110
B00100
B11111
B01111
B10111
B10110
B01110
B01111
B11000
B11001
B10101
B01010
B10001
B00101
B11000
B11100
B10000
B00010
B11001
B00001
B01000
B10101
B00100
B01001
B01010
B00011
B10010
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 11:55 am
Bien...

Bon mon but c'est pas de déchaîner les gens les uns contre les autres.
J'ai l'impression que personne n'a tort mais je ne comprends pas tout quand on se retrouve avec des codes à base de B0100010 ox1201100 honnêtement j'y pige rien.

Quand je dis que ça fait joli, ça veut dire lisible et propre. Pour moi, pour l'arduino.

Je dis ça parce que je cherchais un code exemple, et le type empilait des if et des elseif avec des & partout, j'ai eu la nausée.

Pour avoir déjà utilisé un switch/case, je trouve ça d'une clarté exemplaire, et surtout JE COMPRENDS.

Je rappelle que j'ai un niveau vraiment naze, j'ai commencé ya un mois, sans rien connaître ni à l'électronique, ni à la programmation. RIEN.

Quand on me dit de mettre mes capteurs sur le même port, bah super parce que mon arduino est bourré de fils. Mais, concrètement, ça veut dire quoi? Je mets E1 sur D8? Ouais, j'en suis là...

J'ai très envie de voir ce petit robot courir sur la ligne de scotch que je viens de tracer au pif sur le sol. C'est pas comme ça qu'on fait? bah j'ai fait comme ça parce que je sais pas comment faire, et que les autres sont pas toujours de bon conseil, surtout quand on fouille ailleurs que sur notre forum, c'est ânerie sur connerie.

OUI, il y a forcément une multitude de façons de programmer ça, et c'est ce qui doit nous motiver, pas nous opposer. Je veux pas faire la morale, mais je fais pas des robots pour qu'on s'engueule, sinon je sors le parasol et on règle ça à coups de bière, compris? :D

Avec ma petite tête, j'ai trouvé une solution qui fonctionne, mais qui n'est pas optimale? Bah ouais, j'ai vaguement compris les types de variables la semaines dernière, et je fais tout à tâtons!!! Les copains, c'est mon premier robot ...

Hier je me suis dit que je vais lui claquer un nano pour lire les capteurs et un autre pour traiter le signal. Actuellement, je me sens davantage capable de faire comme ça que d'écrire un code en binaire complexe, parce que j'ignore tout de cette manière de coder, c'est aussi simple que ça.

La proposition de lesept me paraît simple (une ligne) mais je comprends pas les <<, jamais vu avant. je vais chercher.
L'histoire de pins sur le même port, pas j'ai pas compris. (pour moi chaque porc a sa propre pine, non? ok c'est grossier mais elle m'a échappé)
Du binaire pour avoir des valeurs à traiter sous la forme B00100 ?? merveilleux! Comment on fait?

Je suis tout fier d'avoir trouvé mon astuce hier, bien conscient que c'est un bricolage foireux qui va se traîner à mort. J'essaie de faire au mieux avec ce que je comprends, et je comprends pas autant que j'aimerais.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 12:12 pm
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 (https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitread)

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();
}
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 12:30 pm
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?


Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 23, 2018, 12:50 pm
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à
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 12:58 pm
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
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 01:08 pm
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 ...


Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 01:15 pm
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)
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 01:32 pm
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.

(http://forum.arduino.cc/index.php?action=dlattach;topic=543025.0;attach=254602)
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 02:22 pm
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?
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 02:54 pm
Bon, je fais pipi par terre et je me roule dedans.

J'ai pas encore trouvé, je vais marcher un peu ^^
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 03:04 pm
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é
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 03:22 pm
Ah j'étais pas loin. Mais j'y étais pas ^^
Merci m'siô !
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 03:52 pm
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à...
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 04:50 pm
Très fin, du coup je comprends le code! merci encore
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 23, 2018, 06:07 pm
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.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 07:13 pm
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
Title: Re: Faire de 5 booleans une variable type 00010
Post by: biggil on Apr 23, 2018, 07:40 pm
Soit je suis fatigué, soit... c'est le pastis
Non, c'est la syntaxe de case.
Les deux-points vont après la valeur:
Code: [Select]
case 00011 :
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 23, 2018, 07:41 pm
Pfffffffffff
Merci
Bon j'arrête pour aujourd'hui
C'est une erreur ridicule ^^
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 08:27 pm
Non, c'est la syntaxe de case.
Les deux-points vont après la valeur:
Code: [Select]
case 00011 :

et vous ne pouvez pas écrire 0011 le compilateur va croire que c'est une valeur en octal (base 8 ) et pas en binaire... il faut écrire B0011 ou B11 tout simplement avec le B pour binaire.

il faut savoir que le compilateur ne savait décoder que la base 10, la base 8 et la base 16.

en base 10, vous écrivez normalement par exemple 17 (en décimal = 1 x 10 + 7 x 1)
en base 16, on met 0x devant le chiffre par exemple 0x11 (ça fait aussi 17 en décimal, 1x16 + 1x1)
en base 8, on met 0 devant les chiffres... et donc quand on écrit 021 ça fait 17 en décimal (2 x 8 + 1 x 1)

le compilateur ne connaissait pas nativement une notation en binaire (enfin depuis C++14 on peut écrire 0b10011100) et si vous vous demandez c'est quoi ces Bxxxx ce sont des macros de l'ancien temps... Quelqu'un s'est tapé le boulot d'écrire toutes les combinaison possibles dans le fichier binary.h (https://github.com/arduino/Arduino/blob/2bfe164b9a5835e8cb6e194b928538a9093be333/hardware/arduino/avr/cores/arduino/binary.h)

Code: [Select]
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
...
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 23, 2018, 09:14 pm
et vous ne pouvez pas écrire 0011 le compilateur va croire que c'est une valeur en octal (base 8 ) et pas en binaire... il faut écrire B0011 ou B11 tout simplement avec le B pour binaire.
Non.

[connerie de ma part, que j'ai effacée pour ne pas embrouiller davantage]

Mille excuses.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 23, 2018, 09:47 pm
Non.
ÉDIT: Ouf ça a été corrigé :)

essayez code code
Code: [Select]
byte octal = 0011;

void setup() {
  Serial.begin(115200);
  Serial.println(octal);
}

void loop() {}

 vous verrez que la console affiche 9 c'est à dire qu'on a bien 0011 =  1x8 + 1x1 = 9 on est en octal...

Pour le B majuscule ce n'est pas la spécification du C++, comme dit plus haut c'est bien des #define pour chacune des formes et donc c'est le preprocesseur qui remplace; la notation officielle serait de commencer par 0b par exemple 0b0011

et je n'invente pas tout cela, c'est la specification (http://en.cppreference.com/w/cpp/language/integer_literal)

Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 23, 2018, 11:50 pm
Allons vous avez 400 posts sur ce forum... ne dites pas n'importe quoi....Ça vous avance à quoi?
Ups! C'est vrai. J'étais fatigué.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: jfs on Apr 23, 2018, 11:52 pm
Ups! C'est vrai. J'étais fatigué.

ça peut arriver à tout le monde..... non ?   :D
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 24, 2018, 07:52 am
Oui :)

J'ai édité mon message pour que ce soit plus lisible
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 24, 2018, 09:11 am
En effet, je saisis mieux, à force d'expérimentations et de coups de mains, ce que sont ces "modes" d'écriture. Je ne suis pas encore à l'aise, mais je comprends déjà que ça a des avantages.
Mon code fonctionne, reste à créer un algo magique avec des maths dedans. J'ai le même niveau en maths qu'un écureuil de corée. 
Title: Re: Faire de 5 booleans une variable type 00010
Post by: J-M-L on Apr 24, 2018, 09:25 am
En effet, je saisis mieux, à force d'expérimentations et de coups de mains, ce que sont ces "modes" d'écriture. Je ne suis pas encore à l'aise, mais je comprends déjà que ça a des avantages.
Mon code fonctionne, reste à créer un algo magique avec des maths dedans. J'ai le même niveau en maths qu'un écureuil de corée. 
commencez par mettre des B0011 si vous utilisez du binaire ça aidera :)

ensuite comme expliqué plus faut dans la discussion, pas sûr que ce soit super pertinent de procéder comme cela... mais c'est une autre histoire
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 24, 2018, 09:28 am
En effet, je saisis mieux, à force d'expérimentations et de coups de mains, ce que sont ces "modes" d'écriture. Je ne suis pas encore à l'aise, mais je comprends déjà que ça a des avantages.
Mon code fonctionne, reste à créer un algo magique avec des maths dedans. J'ai le même niveau en maths qu'un écureuil de corée.  
Un détail qui a son importance pour bien comprendre: ce ne sont pas des "modes" d'écriture au sens informatique, mais des présentations différentes au programmeur de la même chose.

L' Arduino voit exactement le même code que tu ecrives

case 17: ou
case B01001:


Maintenant t'as pas besoin de maths, ni d'un algo magique.

Tu ecris simplement ce qu'il faut faire dans chaque cas de figure case n:
Y'a pas plus simple.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: kammo on Apr 24, 2018, 09:45 am
commencez par mettre des B0011 si vous utilisez du binaire ça aidera :)

    C'est le cas dans mon code, c'était le but. pour ce qui est des case, je sais faire comme ça, mais il y a toujours mieux. Je lâche pas l'affaire, si je trouve pas cette semaine, ça sera peut-être dans deux mois. Mes connaissances ne me permettent pas d'optimiser mon code pour l'instant.

Tu ecris simplement ce qu'il faut faire dans chaque cas de figure case n:

    Ouais, mais ça fait un robot qui zigzag et manque de finesse. Je cherche un moyen de définir la vitesse de rotation des roues en fonction de leur écartement et de l'empattement. Le capteur, selon sa distance avec l'essieu, détermine un angle, je voudrais partir de là. C'est un calcul de différentiel, faut mixer des équation écrites à moitié en grec, je ferai ça à tête reposée.
Title: Re: Faire de 5 booleans une variable type 00010
Post by: biggil on Apr 24, 2018, 11:51 am
J'ai le même niveau en maths qu'un écureuil de corée.  
Les petits coréens sont très forts en maths ;) 
Title: Re: Faire de 5 booleans une variable type 00010
Post by: RIN67630 on Apr 24, 2018, 12:48 pm
commencez par mettre des B0011 si vous utilisez du binaire ça aidera :)

    C'est le cas dans mon code, c'était le but. pour ce qui est des case, je sais faire comme ça, mais il y a toujours mieux. Je lâche pas l'affaire, si je trouve pas cette semaine, ça sera peut-être dans deux mois. Mes connaissances ne me permettent pas d'optimiser mon code pour l'instant.

Tu ecris simplement ce qu'il faut faire dans chaque cas de figure case n:

    Ouais, mais ça fait un robot qui zigzag et manque de finesse. Je cherche un moyen de définir la vitesse de rotation des roues en fonction de leur écartement et de l'empattement. Le capteur, selon sa distance avec l'essieu, détermine un angle, je voudrais partir de là. C'est un calcul de différentiel, faut mixer des équation écrites à moitié en grec, je ferai ça à tête reposée.
Si tes capteurs ne sont pas proportionels, tu auras du mal a faire en finesse, à moins d'en rajouter.