Question de chaines.

Bonjour à tous,
Voila, j'ai des tests du genre:
if(a==t and b==u and c=v and d==w...->(7 and's par test une vingtaine de tests)
Je voudrais mettre les a,b,c,d... dans une chaine;
Les: t,u,v,w... Dans une autre; pour pouvoir faires les tests avec switch case.
Une bonne âme aurait-elle les quatre lignes de: Déclaration; mise en chaine; switch et case à me céder ? [smiley: Kiss]
Sinon, il va falloir que je teste toutes les combinaisons de mots clé et de ponctuation, et y'en a beaucoup. [smiley: Snif]
A vot' bon coeur m'sieurs dam...Pour une pauv mendiante.

Bonjour,
Tes a,b,c,d... et le reste de la compagnie c'est quoi des char, int, uint8_t, etc ........?

Switch ... case ne fonctionne qu'avec des entiers.

Pour les chaînes il y a strcmp

Maintenant, si tu détaillais ton problème un peu plus, on pourrait peut être te proposer quelque chose de plus sympa.

Merci fdufnews de te soucier de moi; les tests sont sur des états de pin's (LOW/HIGH =? 0/1)
Et ce sont des combinaisons sur les mêmes pin's: AO;A1;A2;...A15...du genre: 0; 1; 0; 0; 1; 0... ou LOW; HIGH; LOW; LOW...
J'ai essayé avec des tableaux, mais il doit y avoir mieux.

Si ce sont des indications binaires par paquets de 8, rien de plus simple.

Tu les transformes en un octet (byte ou uint8_t) pour lequel chacun des 8 bits correspond à l'état d'une de tes PIN.
Et ton test devient alors :

if (serie8PIN == 0b01010101)
{
  ...
}

Pour réaliser cette concaténation, tu peux passer par une fonction pour alléger ton code principal.

byte cruntch(byte valeur1, byte valeur2, ... , byte valeur8)
{
  byte resultat = 0;
  resultat = (resultat << 1) | (!!valeur1);
  resultat = (resultat << 1) | (!!valeur2);
  ...
  resultat = (resultat << 1) | (!!valeur8);
  return resultat;
}

...
  if (cruntch(a1,a2,...,a8) == 0b01010101)
  {
    ...
  }

Hélas, c'est pas un octet, il y a 14 pins.
En fait y'en 7, mais pour sécuriser je dois en tester 14.
Et là, ton code n'est pas de mon niveau, ou alors il faudrait commenter.

En ben dans ce cas :

  • soit tu passes par un uint16_t et c'est la même chose, mais avec 16 bits (tu peux même aller jusqu'à uint32_t). Par exemple :
uint16_t cruntch16(byte a1, ..., byte a16)
{
  return (((uint16_t) cruntch(a1,...,a8)) << 8) | cruntch(a9,...,a16);
}
...
if (cruntch16(...) == 0b0101010101010101)
{
  ...
}
  • soit tu gères par paquets de 8
if ((cruntch(a1,a2,...,a8) == 0b11111111) && (cruntch(a9,..,a14,0,0) == 0b11111100))

à toi de remplir les ...

Carolyne:
Hélas, c'est pas un octet, il y a 14 pins.
En fait y'en 7, mais pour sécuriser je dois en tester 14.
Et là, ton code n'est pas de mon niveau, ou alors il faudrait commenter.

7 infos et 7 contrôles?

14 infos, 28 tests.
Est-ce que passer par du 16 bits est plus avantageux que des chaines ?
Je ne trouve pas: "strcmp" dans la doc de ref "C". Ils ont l'air de pas trop aimer les chaines en "C".
La réalité: 7 inverseurs à point milieu; soit 3 possibilités par inverseur:
Point milieu: on envoie "0" nulle part.
En haut: On envoie "0" sur une pin.
En bas: On envoie "0" sur une autre pin.
Soit 14 pins en tout.
Seules 28 combinaisons sont valides. Les autres doivent êtres exclues (sans réaction)

Bon alors,
Tu déclares
un tableau qui contient le numéro des entrées
une variable qui va contenir l'état des contacts

Tu fais une boucle qui va parcourir le tableau
Avant l'entrée dans la boucle tu initialises la variable d'état à 0
A chaque pas dans la boucle
tu lis une des entrées référencées dans le tableau
tu mets un bit à un ou a zérodans la variable d'état en fonction de l'état de l'entrée testée
tu multiplies par 2 la variable d'état

A la fin tu as un entier qui contient les 14 bits

Je ramasse les copies dans 1 heure

Et ben c'est ce que j'avais fait; je pensais qu'on pouvait faire mieux (pour moins cher).
Bon, ben j'ai plus qu'à recommencer parce que bien sûr, je l'ai jeté.
C'est quand même bizarre que je ne trouve rien sur les manips de chaînes dans les docs de ref du "C".
Merci quand même.

Y'a quand même pas mal de simplifications qui ont été évoquées : sachant que tu peux lire directement l'état des ports (voir "Arduino Port Manipulation") il est ensuite beaucoup plus rapide de faire des comparaisons multiples. Exemple :

int State;
int MesTest[]={32,25,2,13}; 
State = PINB<<8;
State |= PIND; // à partir de la, State représente l'état digital des pins 0 à 13

for(int i =0; i<NombreDeTest;i++){
if((State&MesTest[i])==MesTest[i]) TestPositif(i);
}

Carolyne:
C'est quand même bizarre que je ne trouve rien sur les manips de chaînes dans les docs de ref du "C".
Merci quand même.

Tout dépend de ce que tu appelles les docs de ref du C. En C "standard" il y a la librairie string.h qui contient justement toutes les fonctions strxxx

Après, la manipulation de chaînes est quand même assez lourdes et quand on a pas réellement de chaînes de caractères c'est vraiment se tirer une balle dans le pied que de vouloir traiter des comparaisons de cette manière.

Il y a d'autres solutions pour interpréter tes inter. Je t'en ai proposé une précédemment mais on peut en imaginer d'autres.
Tu peux très bien interpréter la combinaison des touches à la volée en lisant leur état. Si au départ, tu crées un arbre avec les combinaisons d'inter, au fur et à mesure que tu lis l'état des inter tu avances le long des branches de l'arbre pour vérifier si la combinaison est valide. L'arbre n'est pas très volumineux si tu ne codes que les combinaisons valides. Les combinaisons invalides entraînant de fait un abandon de l'analyse.

B@tto, tes codes me semblent venir d'un autre monde.
Dans: int MesTest[]={32,25,2,13}; c'est les valeurs décimales des combinaisons ?
Qu'est-ce qui peut bien se passer lors du shift left 8 alors qu'il y a 14 pin's ? :astonished:
D'où sortent ce: "PINB" et ce: "PIND" et où puis-je en trouver de la doc ?
Et dans: if((State&MesTest_)==MesTest*) TestPositif(i); "i" est le numéro d'ordre de la combinaison dans le tableau des combinaisons ?*_
Purée ! plus c'est court, et plus c'est compliqué à comprendre. ]:slight_smile:

Bon, je ne sais pas si c'est prétentieux; mais comme j'en soupçonne quelque uns de tirer des plans sur la comète, sans passer à la réalisation.
Je montre la bête en cours de finition:
http://hpics.li/9ba145c
Nous sommes bien en présence de réel, voire de surréalisme.
La rampe fonctionne, il me reste à trouver le meilleur moyen pour la marche forcée.
Je pense que je vais convertir les 28 combinaisons en décimal, comme ça je pourrai faire avec switch case.
A ce propos: Y'a pas de problèmes si on converti plus de 8 bits (14 en fait); ça va pas faire un trop gros chiffre ?

Carolyne:
A ce propos: Y'a pas de problèmes si on converti plus de 8 bits (14 en fait); ça va pas faire un trop gros chiffre ?

Depuis le temps qu'on t'en parle tu t'es surement aperçu qu'un int est codé sur 16 bits donc je ne vois pas où est le problème

Ok ok :stuck_out_tongue: Pas de panique... Jusqu'à combien on peut mettre dans un "int" ?
Qu'est-ce qu'il faut déclarer si on dépasse la capacité du "int" ?
Est-ce qu'on peut mettre deux Mégas et faire comme s'il n'y en avait qu'une (pour avoir le double de broches)
Est-ce que c'est difficile ?
Merciiiiiiiiiii!

Carolyne:
Jusqu'à combien on peut mettre dans un "int" ?

...

fdufnews:
Dpuis le temps qu'on t'en parle tu t'es surement aperçu qu'un int est codé sur 16 bits donc je ne vois pas où est le problème

Carolyne:
Qu'est-ce qu'il faut déclarer si on dépasse la capacité du "int" ?

Un long ou un float

Carolyne:
Est-ce qu'on peut mettre deux Mégas et faire comme s'il n'y en avait qu'une (pour avoir le double de broches)
Est-ce que c'est difficile ?

Vaut mieux des I/O expander type PCF8574

B@tto:

Carolyne:
Qu'est-ce qu'il faut déclarer si on dépasse la capacité du "int" ?

Un long ou un float

Un long = 32 bits
le float n'apporte rien dans son cas

J'ai vu des "longs" dans des codes ces derniers temps et ça m'a inquiétée. J'aime bien vos propos rassurants. :smiley:
Je vais voir à quoi ressemble ce PCF8574.
B@tto, ton code de la page précédente est fort alléchant, mais je n'ai pu en tirer que des questions. :relaxed:
Qui sont restées sans réponse. Snif!
Je suis rendue à 314 lignes, et je suis aux 4/5ème de mon premier but. J'ai mis les combinaisons en décimal et andiamo to the switch!