Autre solution ?

Bonjour à tous,
Voila, j’ai besoin de lire 12 pins, et de remmener le N° de la pin qui est “HIGH”.
J’ai mis les pins dans un tableau, et la var de récupération en “int”
int contact[12] = {18,19,20,21,22,23,24,25,26,27,28,29};
int conta=0;
Un inter (pin 15) pour basculer sur ce mode de fonctionnement.
et pour récupérer le N° de la pin “HIGH”, je fais ça:

void testContacts(){   
     while(digitalRead(15)==LOW){ 
     nolight();
     nolightMG();
     conta=18; //la var qui récupère le N° de la pin
     for (int i = 0; i < 12; i++) { 
           VarCont  = digitalRead(contact[i]); //lecture des pins      
           if(VarCont==1){ 
               agitcont(); 
       }
         conta=conta + 1;
        if(conta > 29){
           conta=18;  
        }     
     }   
  }
}
// Puis je teste si Maj ou Min
void agitcont(){ 
  if(digitalRead(16)==LOW){ //Majeurs
    agitcontmaj();
  } 
  if(digitalRead(16)==HIGH){ //Mineurs
    agitcontmin(); 
  }
}
// Et enfin, je switche vers des fonctions
void agitcontmaj(){
   switch (conta){ 
   case 18: 
   dooomaj(); 
   break;
//.....

Il n’y aurait pas un meilleur moyen pour récupérer le N° de la pin “HIGH” ?
Merciiiiiii. biz à l’oeil.

Bon j’ai pas tout compris, surtout le fonctionnement de conta. Si je m’en tiens à ta description d’idée j’aurais plus procéder comme ça déjà :

void testContacts(){   

     while(digitalRead(15)==LOW){ 

    byte i=0;

     nolight();
     nolightMG();
    
     for (i = 0; i < 12; i++) { 

         if(digitalRead(contact[i])==LOW) {
        agitcontmaj(contact[i],digitalRead(16));      
          break; 
            }

       }      
     }   
  }

void agitcontmaj(byte pin, byte MajMin){

switch(pin) {

case 12:
if(MajMin) { ...} else {... }
break;

case 13:
if(MajMin) {... } else {.... }
break;

...

}
}

Ah oui, c'est pas mal ça; Dans : agitcontmaj(contact*,digitalRead(16));* (contact et digitalRead(16) c'est des paramètres passés à la fonction. C'est ça ? J'ai jamais fait ça, je vais le tenter.

Je remarque que les broches 22 à 29 sont sur le même port du microcontrolleur (port A) et les broches 18 à 21 sont sur le même port aussi (port D) Si ton appli est critique en temps d'exécution tu pourrais récupérer les 12 informations en 2 accès au lieu de faire une boucle de lecture en utilisant PINA et PIND pour lire l'état des 2 ports.

Salut fdufnews, l’appli n’est pas critique en temps, mais il faut qu’elle “assure” au niveau N° de pin.
Je viens de tester la soluce de B@tto; ça ne réagit pas du tout.
Si tu peux en dire plus sur ce que tu appelle “accés”…
C’est bien des 12 infos (HIGH/LOW) dont j’ai besoin, mais avec le N° de pin associé.

Edit: Avec le code de B@tto, j’ai fait ça:

void testContacts(){
    while(digitalRead(15)==LOW){
      nolight();
      nolightMG();
      byte i=0;
      for (int i = 0; i < 12; i++) {
        agitcont(contact[i],digitalRead(16));      
          break;
      }
    }
}
void agitcont(byte pin, byte MajMin){
   switch (pin){
          case 18:
          if(MajMin) {
           dooomaj();
          }
          else{
            dooomin();
          }
          break;

Et ban y’a pu rien qui bouge. :~

Le dernier c’est normal y’a plus de condition dans la boucle for !

Après comme ton code j’ai pas tout pigé, ça fait peut-être pas ce que tu veux … Dans tous les cas il faut débuguer, suffit de placer des Serial.print() aux endroits stratégique pour voir où ça bloque :

void testContacts(){   

     while(digitalRead(15)==LOW){ 

    byte i=0;

     nolight();
     nolightMG();
    
     for (i = 0; i < 12; i++) { 

         if(digitalRead(contact[i])==LOW) {
        agitcontmaj(contact[i],digitalRead(16));      
          break; 
            }

       }      
     }   
  }

void agitcontmaj(byte pin, byte MajMin){

Serial.print("Pin n°");
Serial.print(pin);
Serial.print(" MajMin ");
Serial.println(MajMin);

switch(pin) {

case 12:
if(MajMin) { ...} else {... }
break;

case 13:
if(MajMin) {... } else {.... }
break;

...

}
}

Ah Ok, je retente, c'est que ça m'a fait modifié pas mal de trucs; dans la manip, le if est resté en rade.

ça y 'est, ça marche; il y avait un décalage, et je croyais que c'était le code qui foirais. J'ai décalé en conséquence. Merci de m'avoir fait tester le passage en paramètres, c'est pratique. :P

Après comme évoqué par fdufnews le plus rapide et le plus simple en terme de code c'est ça :

void testContacts(){   

     while((~PORTJ) & 1){ 

     nolight();
     nolightMG();

agitcontmaj((PORTD & 0b1111) & PORTA, PORTH & 0b10).

}

void agitcontmaj(byte pin, byte MajMin){

if(pin!=0) {

switch(pin) {

// il faudra juste revoir les valeur de pin pour les case qui ne seront plus les mêmes

http://arduino.cc/en/Reference/PortManipulation#.UwXcRKLEK8A

Houla la !...Je vais tester ton truc, mais ça va être du "sans -filet". ]:) Si ça marche, je consacre tout le mois prochain à comprendre pourquoi. :)

Y’a pas grand grand chose à piger :

PORTA est le registre qui contient l’état des pins du port A, c’est à dire PD0, PD1, PD2 … PD7 ou encore en langage Arduino les pins 22 à 29. Correspondance :
http://www.pighixxx.com/pgdev/Temp/mega2.png

PORTA est donc un byte (8 bits), chaque bit représentant un pin :

PORTA bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
Pin 29 28 27 26 25 24 23 22

Donc si tout les pin sont à l’état haut et que le pin 24 est à l’état bas, PORTA renverra 00000100

D’ailleurs à la relecture je me suis planté dans le code puisque bouton appuyé = LOW = 0 :

Donc si un bouton sur portD est appuyé admettons PD0 :
PORTD = 01001110 (volontairement j’introduis des valeurs sur les pins PD4 à 7)
~01001110=10110001 on inverse les bits
10110001 & 00001111 => 00000001 cette opération permet d’éliminer les pin PD4 à 7, on appelle ça du masquage
00000001<<8 = 100000000 on décale de 8 rang vers la gauche
100000000 & ~PORTA = 100000000 & ~11111111 = 100000000 (si aucun bouton appuyé PORTA = 11111111)

agitcontmaj((~PORTD & 0b1111)<<8 & (~PORTA), ~PORTH & 0b10);

et modifier agitcont pour pouvoir recevoir un int et non un byte pour pin

On est d'accord que bien expliqué, ça paraît assez simple; mais les manipulations de bits, il faut en avoir une bonne pratique (habitude); je me vois mal, à mon niveau, aller dénicher un plantage dans un foyon' de "0" et de "1". Mais je m'y ferai quand même les dents, quand j'aurai mis deux ou trois copies de mon prog bien à l'abri. Et donc: Merci pour l'explic'. (que je copie, because: C'est pas si simple que ça en a l'air.... ;))

Si tu comprends pas où ton programme plante ou pour faire des tests toujours la même méthode (pas trop le choix sur Arduino en même temps) ==> Serial.print()

==> Serial.print()

On fini toujours pas y venir...Après deux heures de prise de tête, trente-six téléversements et douze versions. :grin:

Carolyne: On est d'accord que bien expliqué, ça paraît assez simple; mais les manipulations de bits, il faut en avoir une bonne pratique (habitude); je me vois mal, à mon niveau, aller dénicher un plantage dans un foyon' de "0" et de "1".

Ouai enfin si t'essayes pas c'est pas demain que tu y arriveras.

En honnêtement il n'y a pas de quoi en faire un plat. Il ne faut pas hésiter à faire quelques Serial.print dans les fonctions que tu ne comprends pas et d'analyser ensuite. Assez vite en général on s'aperçoit que ce n'est pas si magique que ça en à l'air