Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Effectuer une association entre deux tableaux


Sujet :

Arduino

  1. #1
    Membre régulier
    Effectuer une association entre deux tableaux
    Bonjour à toutes et tous,

    Comment déclarer ceci :
    boutons-poussoir normalement ouvert et nommés :
    C1_V1, C1_V2 ;
    C2_V1, C2_V2, C2_V3 ;
    C3_V1, C3_V2, C3_V3.

    ces boutons-poussoirs doivent actionner des moteurs nommés comme suit :
    C1_V1 => G1, A1, A3 ;
    C1_V2 => G1, A1, A4 ;
    C2_V1 => B1, B3, A2, A3 ;
    C2_V2 => B1, B3, A2, A4 ;
    C2_V3 => B1, B4 ;
    C3_V1 => B2, B3, A2, A3 ;
    C3_V2 => B2, B3, A2, A4 ;
    C3_V3 => B2, B4 ;

    Comment traduire ça en langage Arduino ?
    J'ai tenté de déclarer 2 tableaux, un pour les boutons, l'autre pour les moteurs, mais je n'ai pas réussi (avec mes très maigres connaissances !) à associer l'un par rapport à l'autre.
    Une idée ?
    Merci
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  2. #2
    Expert éminent sénior
    Bonjour,

    Sur ce forum, nous pouvons t'aider mais en aucun cas réaliser ton exercice.

    Ceci est l'énoncé de ton exercice ? Il ne contient que ces informations ? Que sont les G1, B1 à B4 et A1 à A4 ? Comment sont connectés tes boutons poussoirs et tes moteurs sur ton Arduino ?
    Montre nous ce que tu as fait, dis nous ce que tu ne comprends pas.

  3. #3
    Membre régulier
    Citation Envoyé par Auteur Voir le message
    Bonjour,

    Sur ce forum, nous pouvons t'aider mais en aucun cas réaliser ton exercice.
    Je ne demande pas qu'on me fasse mon exercice mais je ne sais pas comment faire une association entre les deux tableaux.
    Je pensais être clair en dénommant les boutons et les moteurs différemment l'un de l'autre
    les BP doivent actionner les moteurs :
    C1_V1 => G1, A1, A3 ;
    C1_V2 => G1, A1, A4 ;
    C2_V1 => B1, B3, A2, A3 ;
    C2_V2 => B1, B3, A2, A4 ;
    C2_V3 => B1, B4 ;
    C3_V1 => B2, B3, A2, A3 ;
    C3_V2 => B2, B3, A2, A4 ;
    C3_V3 => B2, B4 ;

    je désire savoir le principe de déclaration des 2 tableaux et ensuite l'association des BP avec les moteurs afférents
    C'est un exemple que je cherche, pas le code !
    J'utilise une carte MEGA 2560 R3 pour avoir un maximum de pins de connexion.
    Merci pour tes réponses
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  4. #4
    Membre régulier
    Pour poursuivre ...
    Bonjour à toutes et tous,
    Pour poursuivre mon idée (bonne ou pas !), j'ai écris ce script hier avec le peu de connaissance que je possède et des exemples tirés ici ou là.
    Je vais utiliser une carte MEGA 2560 R3, afin de profiter d'un nombre nettement plus important de pins.
    Il y a quelques erreurs que je ne comprends pas et c'est là que j'ai besoin de votre aide :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    F:\PROGRAMMATION PERSO\TEST_Boutons-poussoirs-et-Aiguillages\TEST_Boutons-poussoirs-et-Aiguillages.ino: In function 'void loop()':
    F:\PROGRAMMATION PERSO\TEST_Boutons-poussoirs-et-Aiguillages\TEST_Boutons-poussoirs-et-Aiguillages.ino:40:29: warning: invalid conversion from 'int*' to 'uint8_t {aka unsigned char}' [-fpermissive]
     buttonState = digitalRead(bp) ;
                                 ^
    In file included from C:\Users\jsior\AppData\Local\Temp\arduino_build_839821\sketch\TEST_Boutons-poussoirs-et-Aiguillages.ino.cpp:1:0:
    C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:136:5: note:   initializing argument 1 of 'int digitalRead(uint8_t)'
     int digitalRead(uint8_t pin);
         ^~~~~~~~~~~
    TEST_Boutons-poussoirs-et-Aiguillages:44:13: error: switch quantity not an integer
       switch (bp) {     // debut de la structure
                 ^


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    // Déclaration dans des tableaux du nombre de bp et des moteurs d'aiguillages
     
    int bp[] = {5, 6, 7, 8, 9, 10, 11, 12} ;              // Boutons poussoirs Normalement Ouvert (NO)
    int aig[] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38} ; // aiguillage : position D(roite) ou G(auche)
     
    int buttonState = 0 ;
    int timer = 50 ;
     
    void setup() {
      // Initialisation
    for (int bp=0; bp<=13; bp++) {
      pinMode(bp, OUTPUT) ;
    }
    for (int aig=0; aig<=39; aig++) {
      pinMode(aig, OUTPUT) ;
    }
     
    // initialisation de la gare
    // C1_V1
    digitalWrite(22, HIGH) ; // aiguillage G1 D
    digitalWrite(23, HIGH) ; // aiguillage A1 G
    digitalWrite(28, HIGH) ; // aiguillage A3 G
    // C2_V2
    digitalWrite(31, HIGH) ; // aiguillage B1 G
    digitalWrite(36, HIGH) ; // aiguillage B3 D
    digitalWrite(26, HIGH) ; // aiguillage A2 D
    digitalWrite(29, HIGH) ; // aiguillage A4 G
    // C3_V3
    digitalWrite(34, HIGH) ; // aiguillage B2 D
    digitalWrite(37, HIGH) ; // aiguillage B4 G
    }
     
    void loop() {
    buttonState = digitalRead(bp) ;
     
    if (buttonState == HIGH) {      // vérifier si un bouton poussoir est enfoncé. Si tel est le cas, le boutonState est HIGH
     
      switch (bp) {     // debut de la structure 
        case 5:           // bouton C1_V1
        digitalWrite(22, HIGH) ;  // aiguillage G1_D
        delay(timer);
        digitalWrite(23, HIGH) ;  // aiguillage A1_G
        delay(timer);
        digitalWrite(28, HIGH) ;  // aiguillage A3_D
        break;       
      case 6:           // bouton C1_V2
        digitalWrite(22, HIGH) ;  // aiguillage G1_D
        delay(timer);
        digitalWrite(24, HIGH) ;  // aiguillage A1_D
        delay(timer);
        digitalWrite(30, HIGH) ;  // aiguillage A4_D
     
        break;
      case 7:           // bouton C2_V1
        digitalWrite(31, HIGH) ;  // aiguillage B1_G
        delay(timer);
        digitalWrite(36, HIGH) ;  // aiguillage B3_D
        delay(timer);
        digitalWrite(25, HIGH) ;  // aiguillage A2_G
        delay(timer);
        digitalWrite(27, HIGH) ;  // aiguillage A3_G
     
        break;
      case 8:           // bouton C2_V2
        digitalWrite(31, HIGH) ;  // aiguillage B1_G
        delay(timer);
        digitalWrite(36, HIGH) ;  // aiguillage B3_D
        delay(timer);
        digitalWrite(26, HIGH) ;  // aiguillage A2_D
        delay(timer);
        digitalWrite(29, HIGH) ;  // aiguillage A4_G
     
        break;
      case 9:           // bouton C2_V3
        digitalWrite(32, HIGH) ;  // aiguillage B1_D
        delay(timer) ;
        digitalWrite(38, HIGH) ;  // aiguillage B4_D
     
        break;
      case 10:          // bouton C3_V1
        digitalWrite(33, HIGH) ;  // aiguillage B2_G
        delay(timer) ;
        digitalWrite(35, HIGH) ;  // aiguillage B3_G
        delay(timer) ;
        digitalWrite(25, HIGH) ;  // aiguillage A2_G
        delay(timer) ;
        digitalWrite(27, HIGH) ;  // aiguillage A3_G
     
        break;
      case 11:          // bouton C3_V2
        digitalWrite(33, HIGH) ;  // aiguillage B2_G
        delay(timer) ;
        digitalWrite(35, HIGH) ;  // aiguillage B3_G
        delay(timer) ;
        digitalWrite(26, HIGH) ;  // aiguillage A2_D
        delay(timer) ;
        digitalWrite(29, HIGH) ;  // aiguillage A4_G
     
        break;
      case 12:          // bouton C3_V3
        digitalWrite(33, HIGH) ;  // aiguillage B2_G
        delay(timer) ;
        digitalWrite(37, HIGH) ;  // aiguillage B4_G
     
        break;
        // default: // cas par d&#65533;faut 
          // si aucune condition n'est vraie, le code par d&#65533;faut sera ex&#65533;cut&#65533;
          // le cas default est optionnel (non -obligatoire) 
      }
    }
    }

    Un grand merci pour votre aide
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  5. #5
    Membre expérimenté
    Bonjour Jsiorat

    Ah! jouer au train électrique avec un Arduino

    J'ai lu ton programme "en travers", je trouve cela un peu "lourd" et il sera difficile à gérer.

    Première remarque, à propos de tes boutons-poussoirs (bp)
    Tu les initialise mal:
    pinMode(bp, OUTPUT) ;
    au lieu de
    pinMode(bp, INPUT);
    ou
    pinMode(bp, INPUT_PULLUP);
    La question est "contre" quel potentiel sont câblés tes bp GND ou +5V, si c'est GND, c'est la version INPUT_PULLUP qu'il faut choisir, cela t'évitera de mettre, toi, ces résistances.
    Si c'est +5V., c'est la version INPUT. Par contre, c'est à toi de mettre des résistances de PULL_DOWN. Perso je câble toujours "contre" GND.

    Pour revenir au sujet principal, je te propose un tableau à 2 dimensions, bpArray, qui a autant d'éléments que de boutons (#define bpNombreMax 8). Chaque élément contient 5 valeurs, la première est le port Arduino du bouton, les 4 suivants (#define motNombreMax 4) sont les ports des moteurs dédicacés à ce bouton.
    Tu as un exemple d'utilisation de ce tableau avec l'initialisation des ports des bp et des moteurs dans le setup.
    Avec cette "mécanique" tu peux facilement interroger l'état de tes boutons, avec une boucle, les boutons sont numérotés de 0 à bpNombreMax-1.

    Voilà une base pour utiliser ce tableau.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #define bpNombreMax 8        // Nombre de boutons
    #define motNombreMax 4       // Nombre de moteurs
     
    /*
    	tableau contenant, en première position, le port du bp
    	ensuite, les moteurs attribues a ce bp, 0 si pas utilise
    	partant du principe qu'il y a 4 moteurs au maximum
    */
    const int bpArray[][motNombreMax +1] =                // [Nombre de moteurs + port bp]
    {
    	{5, 22, 23, 28, 0},      // bouton C1_V1
    	{6, 22, 24, 30, 0},      // bouton C1_V2
    	{7, 31, 36, 25, 27},     // bouton C2_V1
    	{8, 31, 36, 26, 29},     // bouton C2_V2
    	{9, 32, 38, 0, 0},       // bouton C2_V3
    	{10, 33, 35, 25, 27},    // bouton C3_V1
    	{11, 33, 35, 26, 29},    // bouton C3_V2
    	{12, 33, 37, 0, 0},      // bouton C3_V3
    };
     
    void setup()
    {
    	Serial.begin(115200);
    	// Initialisation des bp
    	for (int bp = 0; bp < bpNombreMax; bp ++)
    	{
    		pinMode(bpArray[bp][0], INPUT_PULLUP);
    	}
    	// Initialisation des moteurs
    	for (int bp = 0; bp < bpNombreMax; bp ++)
    	{
    		for (int mot = 1; mot < motNombreMax; mot ++)
    		{
    			int motPort = bpArray[bp][mot];             // Numero du port du moteur
    			if (motPort != 0)                           // Si port confugure
    			{
    				pinMode(bpArray[bp][mot], INPUT_PULLUP);
    			}
    		}
    	}
    }
     
    void loop()
    {
    	for (int bp = 0; bp < bpNombreMax; bp ++)
    	{
    		if (digitalRead(bpArray[bp][0]) == LOW)    // Dans le cas de bp cables "contre" GND
    		{
    			bpPresseAction(bp);
    		}
    	}
    }
     
    void bpPresseAction(int bpNumero)
    {
    	Serial.print(F("Bouton presse No. "));
    	Serial.println(bpNumero);
     
    	for (int mot = 1; mot < motNombreMax; mot ++)
    	{
    		int motPort = bpArray[bpNumero][mot];       // Numero du port du moteur
    		if (motPort != 0)                           // Si port confugure
    		{
    			Serial.print(F("\tRelais port "));
    			Serial.println(bpArray[bpNumero][mot]);
    		}
    	}
     
    }


    Je n'ai pas testé ce programme en réel avec des boutons, mais ça devrait fonctionner.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  6. #6
    Membre expérimenté
    C’est peut être un peu avancé, ça dépend ce que vous avez déjà appris en programmation mais Une structure (mot clé struct) est généralement la façon utilisée pour grouper un ensemble de données liées (une pin pour le bouton et les pins du moteur par exemple)

    Ensuite si vous en avez plusieurs vous pouvez créer un tableau de structures

    pour reprendre l'idée et une partie du code de @jpbricole (en introduisant une constant "pasDeMoteur" quand une entrée du tableau n'est pas pertinente pour simplifier la lecture et éviter les nombres "magiques" dans le code), ça serait comme cela
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    const byte nombreMaxDeMoteurs = 4;    // Nombre max de moteurs associés à un bouton
    const byte pasDeMoteur = 255;   // 255 = pas de pin associée
     
    // on déclare un type aiguillage qui relie la pin du bouton à un certain nombre de pins des moteurs
    struct t_aiguillage {
      byte pinBouton;
      byte pinMoteurs[nombreMaxDeMoteurs];
    };
     
    // puis on déclare un tableau aiguillages avec tous nos aiguillages. Si une entrée moteur n'est pas utilisée, on met pasDeMoteur à cet endroit
    t_aiguillage aiguillages[] = {
      {  5, {22, 23, 28, pasDeMoteur}},           // bouton C1_V1
      {  6, {22, 24, 30, pasDeMoteur}},           // bouton C1_V2
      {  7, {31, 36, 25,  27}},                   // bouton C2_V1
      {  8, {31, 36, 26,  29}},                   // bouton C2_V2
      {  9, {32, 38, pasDeMoteur, pasDeMoteur}},  // bouton C2_V3
      { 10, {33, 35, 25,  27}},                   // bouton C3_V1
      { 11, {33, 35, 26,  29}},                   // bouton C3_V2
      { 12, {33, 37, pasDeMoteur, pasDeMoteur}}   // bouton C3_V3
    };
     
    // enfin on compte combien on a d'aiguillages connus (comme cela si on en rajoute ça se recalcule tout seul)
    const byte nombreAiguillages = sizeof(aiguillages) / sizeof(aiguillages[0]);
     
    void setup() {
      {
        Serial.begin(115200);
     
        for (byte i = 0; i < nombreAiguillages; i++) { // pour chaque aiguillage
     
          // Initialisation de son bouton pression
          pinMode(aiguillages[i].pinBouton, INPUT_PULLUP);
     
          // Initialisation des pin des moteurs associés à ce bouton pression
          for (byte j = 0; j < nombreMaxDeMoteurs; j++) {
            byte pinMoteur = aiguillages[i].pinMoteurs[j]; // Numero de pin du moteur
            if (pinMoteur != pasDeMoteur) pinMode(pinMoteur, INPUT_PULLUP);
          }
        } // fin boucle pour chaque aiguillage
      }
    }
     
    void loop() {}

  7. #7
    Membre régulier
    Je suis subjugué !
    Bonjour et merci à vous deux ...
    Je peux remarquer que le train miniature vous interpelle !

    En prog Arduino, je suis un débutant de la dernière heure (j'ai 75 ans !) et je fais ce que je peux, malheureusement ! alors votre aide m'est précieuse.
    Voici ce que j'ai pondu avec mes maigres connaissances !
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    // Intégration de la bibliothèque dans le code :
    #include <Bounce2.h>
     
    // Création d'un objet Bounce appelé btn
    Bounce btn ;
     
    // déclaration des boutons poussoirs et des aiguillages
    uint8_t bp[] = {5, 6, 7, 8, 9, 10, 11, 12} ; // Boutons poussoirs Normalement Ouvert (NO)
    uint8_t aig[] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38} ;
     
    int buttonState = 0 ;
    int timer = 50 ;
    int n = 0 ;
    int i = 0 ;
     
    void setup() {
      // Initialisation des boutons poussoirs et des aiguillages
      for (uint8_t bp = 0; bp <= 7; bp++) {
        pinMode(bp, INPUT) ;
      }
      for (uint8_t aig = 0; aig <= 17; aig++) {
        pinMode(aig, OUTPUT) ;
      }
      // définition des paramètres de l'objet Bounce
      btn.attach(bp) ;		// la broche du bouton poussoir
      btn.interval(10) ;	// intervalle de temps en ms
     
      // initialisation de la gare
      // C1_V1
      digitalWrite(22, HIGH) ; delay(timer) ; digitalWrite(22, LOW) ;  // aiguillage G1 D
      digitalWrite(23, HIGH) ; delay(timer) ; digitalWrite(23, LOW) ;  // aiguillage A1 G
      digitalWrite(28, HIGH) ; delay(timer) ; digitalWrite(28, LOW) ;  // aiguillage A3 G
      // C2_V2
      digitalWrite(31, HIGH) ; delay(timer) ; digitalWrite(31, LOW) ;  // aiguillage B1 G
      digitalWrite(36, HIGH) ; delay(timer) ; digitalWrite(36, LOW) ;  // aiguillage B3 D
      digitalWrite(26, HIGH) ; delay(timer) ; digitalWrite(26, LOW) ;  // aiguillage A2 D
      digitalWrite(29, HIGH) ; delay(timer) ; digitalWrite(29, LOW) ;  // aiguillage A4 G
      // C3_V3
      digitalWrite(34, HIGH) ; delay(timer) ; digitalWrite(34, LOW) ;  // aiguillage B2 D
      digitalWrite(37, HIGH) ; delay(timer) ; digitalWrite(37, LOW) ;  // aiguillage B4 G
    }
     
    void loop()
    {
      loop() ;
      {
    	// l'objet Bounce doit exécuter son code interne à chaque loop :
    	btn.update() ;
        for (i = 0; i <= 12; i++)
        {
    	  // lire la valeur du bouton filtré
          buttonState = digitalRead(bp[i]) ;
          if (digitalRead(bp[i] == LOW)) {
            n = i;
          } ;
     
          switch (bp[i])                          // debut de la structure
          {
     
            case 5:                     // bouton C1_V1
              digitalWrite(22, HIGH) ;  delay(timer) ; digitalWrite(22, LOW) ;// aiguillage G1_D
              delay(timer);
              digitalWrite(23, HIGH) ;  delay(timer) ; digitalWrite(23, LOW) ;  // aiguillage A1_G
              delay(timer);
              digitalWrite(28, HIGH) ;  delay(timer) ; digitalWrite(28, LOW) ;  // aiguillage A3_D
              break;
            case 6:                     // bouton C1_V2
              digitalWrite(22, HIGH) ; delay(timer) ; digitalWrite(22, LOW) ;  // aiguillage G1_D
              delay(timer);
              digitalWrite(24, HIGH) ; delay(timer) ; digitalWrite(24, LOW) ;  // aiguillage A1_D
              delay(timer);
              digitalWrite(30, HIGH) ;  delay(timer) ; digitalWrite(30, LOW) ;  // aiguillage A4_D
     
              break;
            case 7:                     // bouton C2_V1
              digitalWrite(31, HIGH) ;  delay(timer) ; digitalWrite(31, LOW) ;  // aiguillage B1_G
              delay(timer);
              digitalWrite(36, HIGH) ;  delay(timer) ; digitalWrite(36, LOW) ;  // aiguillage B3_D
              delay(timer);
              digitalWrite(25, HIGH) ;  delay(timer) ; digitalWrite(25, LOW) ;  // aiguillage A2_G
              delay(timer);
              digitalWrite(27, HIGH) ;  delay(timer) ; digitalWrite(27, LOW) ;  // aiguillage A3_G
     
              break;
            case 8:                     // bouton C2_V2
              digitalWrite(31, HIGH) ;  delay(timer) ; digitalWrite(31, LOW) ;  // aiguillage B1_G
              delay(timer);
              digitalWrite(36, HIGH) ;  delay(timer) ; digitalWrite(36, LOW) ;  // aiguillage B3_D
              delay(timer);
              digitalWrite(26, HIGH) ;  delay(timer) ; digitalWrite(26, LOW) ;  // aiguillage A2_D
              delay(timer);
              digitalWrite(29, HIGH) ;  delay(timer) ; digitalWrite(29, LOW) ;  // aiguillage A4_G
     
              break;
            case 9:                     // bouton C2_V3
              digitalWrite(32, HIGH) ;  delay(timer) ; digitalWrite(32, LOW) ;  // aiguillage B1_D
              delay(timer);
              digitalWrite(38, HIGH) ;  delay(timer) ; digitalWrite(38, LOW) ;  // aiguillage B4_D
     
              break;
            case 10:                    // bouton C3_V1
              digitalWrite(33, HIGH) ;  delay(timer) ; digitalWrite(33, LOW) ;  // aiguillage B2_G
              delay(timer) ;
              digitalWrite(35, HIGH) ;  delay(timer) ; digitalWrite(35, LOW) ;  // aiguillage B3_G
              delay(timer) ;
              digitalWrite(25, HIGH) ;  delay(timer) ; digitalWrite(25, LOW) ;  // aiguillage A2_G
              delay(timer) ;
              digitalWrite(27, HIGH) ;  delay(timer) ; digitalWrite(27, LOW) ;  // aiguillage A3_G
     
              break;
            case 11:                    // bouton C3_V2
              digitalWrite(33, HIGH) ;  delay(timer) ; digitalWrite(33, LOW) ;  // aiguillage B2_G
              delay(timer) ;
              digitalWrite(35, HIGH) ;  delay(timer) ; digitalWrite(35, LOW) ;  // aiguillage B3_G
              delay(timer) ;
              digitalWrite(26, HIGH) ;  delay(timer) ; digitalWrite(26, LOW) ;  // aiguillage A2_D
              delay(timer) ;
              digitalWrite(29, HIGH) ;  delay(timer) ; digitalWrite(29, LOW) ;  // aiguillage A4_G
     
              break;
            case 12:                    // bouton C3_V3
              digitalWrite(33, HIGH) ;  delay(timer) ; digitalWrite(33, LOW) ;  // aiguillage B2_G
              delay(timer) ;
              digitalWrite(37, HIGH) ;  delay(timer) ; digitalWrite(37, LOW) ;  // aiguillage B4_G
     
              break;
          }
        }
      }
    }


    Je sais, c'est peut-être lourd mais ça fonctionne, tout au moins sans erreur dans l'IDE.
    En parlant de l'IDE Arduino, je regrette qu'on ne sois pas en mesure de faire du "step by step" pour débugger un programme.
    Avez-vous connaissance d'un IDE qui puisse faire ça ? un plugin peut-être ?
    Merci encore pour vos avis éclairés !
    Cordialement, Jacques
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  8. #8
    Membre expérimenté
    Bonjour Jacques
    Citation Envoyé par Jsiorat Voir le message

    Je sais, c'est peut-être lourd mais ça fonctionne, tout au moins sans erreur dans l'IDE.
    Le terme "lourd" voulait dire "difficile à gérer", autrement dit, si tu dois ajouter un bouton ou une aiguille, essaye d'imaginer tout ce que doit modifier dans ton programme. Une programmation un peu mieux structurée, permet de faire, ce type de modification, seulement à une ou 2 places.
    Je te ferais un exemple.
    Cela étant dit, débuter l'Arduino à 75 ans (je suis presque aussi jeune que toi, 72 ans ) et avoir compris tout ca, chapeau

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  9. #9
    Membre régulier
    Bonjour ...

    Citation Envoyé par jpbbricole Voir le message
    Bonjour Jacques


    Le terme "lourd" voulait dire "difficile à gérer", autrement dit, si tu dois ajouter un bouton ou une aiguille, essaye d'imaginer tout ce que doit modifier dans ton programme. Une programmation un peu mieux structurée, permet de faire, ce type de modification, seulement à une ou 2 places.
    Je te ferais un exemple.
    Cela étant dit, débuter l'Arduino à 75 ans (je suis presque aussi jeune que toi, 72 ans ) et avoir compris tout ca, chapeau


    J'ai utilisé le terme lourd à bon escient ! mon code est lourd ! mais il fonctionne !
    je vais juste rajouter quelques instructions de débogage pour au cas ou et pour savoir comment se déroule mon programme.
    C'est vrai que je ne possède pas l'instruction nécessaire pour être un programmeur, dans tous les sens du terme !
    Pour ce qui est de notre âge, un humoriste belge bien connu, à dit : " Nous, les vieux, nous avons eu la jeunesse, mais la jeunesse actuelle n'est pas sur d'être vieux !"
    J'accepterai volontiers un exemple plus succinct de ce type de code. Je suppose le code avec un tableau à 3 dimensions pour les bp et les aiguillages.
    Un grand merci à toi ... professeur et bon WE !
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  10. #10
    Membre expérimenté
    Bravo pour le travail de découverte de ce monde de la programmation. A nos ages ça fait travailler les neurones et c'est bien.

    dans votre code il y a des trucs louches sur l'usage du Bounce. Par exemple vous faites un
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
      btn.attach(bp) ;		// la broche du bouton poussoir
    mais bp est un tableau de pins.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    uint8_t bp[] = {5, 6, 7, 8, 9, 10, 11, 12} ; // Boutons poussoirs Normalement Ouvert (NO)
    et vous avez aussi d'ailleurs masqué temporairement cette variable en utilisant aussi bp comme indice dans la boucle for
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
      // Initialisation des boutons poussoirs et des aiguillages
      for (uint8_t bp = 0; bp <= 7; bp++) {
        pinMode(bp, INPUT) ;
      }


    faudrait regarder cela de plus près si btn sert vraiment à quelque chose parce que vous lisez les pins directement
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
     buttonState = digitalRead(bp[i])


    -----

    En parlant de l'IDE Arduino, je regrette qu'on ne sois pas en mesure de faire du "step by step" pour débugger un programme.
    pas avec l'IDE arduino et les petits UNO ou MEGA, c'est possible avec des cartes plus avancées qui ont une connexion spécifique de debug (il faut pouvoir parler à la carte et écouter ce qu'il se passe dessus en temps réel). Les cartes à base de SAMD21 par exemple ont cette possibilité

    L'IDE dit "PRO" d'Arduino aura cette fonctionnalité (que l'on retrouve dans d'autres outils plus professionnels). Ils en ont fait une petite vidéo que vous retrouverez ici

  11. #11
    Membre expérimenté
    Bonjour Jacques

    Voilà comment je vois la chose, c'est une solution fonctionnnelle, testée avec un Mega.
    L'intialisation, au début, est un peu fastidieuse, mais après, pour programmer les actions, c'est plus facile.
    Si tu dois modfifier le nombre de boutons ou d'aiguilles, c'est uniquement au début que tu dois intervenir.
    Je te laisse découvrir et poser des questions. Tu verras comment éviter les répétitions comme la mise à On/Off d'un moteur d'aiguillage
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    digitalWrite(22, HIGH) ; delay(timer) ; digitalWrite(22, LOW) ;  // aiguillage G1 D

    remplacés par la fonction motAigMouvement et le traitement des bp par la fonction bpPresseAction
    Pour adapter le programme à tes commandes bp et moteur, c'est les variables:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    #define bpEtatPresse LOW     // Etat lu du bouton presse
    #define motEtatOn HIGH       // Etat pour moteur ON


    Le programme:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    #define bpNombreMax 8        // Nombre de boutons
    #define bpMotNombreMax 4     // Nombre de moteurs max par bouton
    #define bpEtatPresse LOW     // Etat lu du bouton presse
     
    #define motAigNombreMax 17   // Nombre de moteurs d'aiguilles
    #define motEtatOn HIGH       // Etat pour moteur ON
    #define motEtatOnTemps 50    // Moteur, temps de l'impulsiom ON
     
    //------------------------------------- Structure de l'objet moteur/aiguiulle (motAig
    struct motAigDefinition  
    {String nom[motAigNombreMax]; byte port[motAigNombreMax];};
    /*
    	Enumeration des aiguilles pour faciliter leur appel
    	leur nombre = motAigNombreMax
    */
    const byte maNU = -1;              // Pour position non utilisee
    enum motAigIndex 
    {    maG1_D, maA1_G, maA1_D, maA2_G, maA2_D, maA3_G, maA3_D, maA4_G, maA4_D, maB1_G, maB1_D, maB2_G, maB2_D, maB3_G, maB3_D, maB4_G, maB4_D};
     
    /*
    	remplissage de la structure des moteurs/aiguilles motAig[0] a bp[motAigNombreMax-1]
    	dans l'ordre motAig[n].nom,  motAig[n].port
    */
    motAigDefinition motAig = {
    	{"G1 D", "A1 G", "A1 D", "A2 G", "A2 D", "A3 G", "A3 D", "A4 G", "A4 D", "B1 G", "B1 D", "B2 G", "B2 D", "B3 G", "B3 D", "B4 G", "B4 D"},
    	{  22,     23,     24,     25,     26,     27,     28,     29,     30,     31,     32,     33,     34,     35,     36,     37,     38}
    };
     
    //------------------------------------- Structure de l'objet bouton poussoir (bp)
    struct bpDefinition                                                  
    {String nom; byte port; byte motPort[bpMotNombreMax];};
    /*
    	remplissage de la structure des boutons bp[0] a bp[bpNombreMax-1]
    	dans l'ordre bp[n].nom,  bp[n].port,   bp[n].moteurs[0] a bp[n].moteurs[motNombreMax-1]
    */
    bpDefinition bp[] = {
    {"C1_V1",  5, maG1_D, maA1_G, maA3_D, maNU},
    {"C1_V2",  6, maG1_D, maA1_D, maA4_D, maNU},
    {"C2_V1",  7, maB1_G, maB3_D, maA2_G, maA3_G},
    {"C2_V2",  8, maB1_G, maB3_D, maA2_D, maA4_G},
    {"C2_V3",  9, maB1_D, maB4_D, maNU, maNU},
    {"C3_V1", 10, maB2_G, maB3_G, maA2_G, maA3_G},
    {"C3_V2", 11, maB2_G, maB3_G, maA2_D, maA4_G},
    {"C3_V3", 12, maB2_G, maB4_G, maNU, maNU},
    };
     
    void setup()
    {
    	Serial.begin(115200);
     
    	//--------------------------------- Initialisation des bp
    	for (int b = 0; b < bpNombreMax; b ++)
    	{
    		pinMode(bp[b].port, INPUT_PULLUP);                           // Pour bpEtatPresse LOW
    	}
    	//--------------------------------- Initialisation des moteurs d'aiguilles
    	for (int ma = 0; ma < motAigNombreMax; ma ++)
    	{
    		pinMode(motAig.port[ma], OUTPUT);
    		digitalWrite(motAig.port[ma], !motEtatOn);                   // Moteur a l'arrêt
    	}
     
    	gareInitialisation();
    }
     
    void loop()
    {
    	for (int b = 0; b < bpNombreMax; b ++)                           // Balayage des bp          
    	{
    		if (digitalRead(bp[b].port) == bpEtatPresse)
    		{
    			bpPresseAction(b);
     
    			while(digitalRead(bp[b].port) == bpEtatPresse){}         // Attente du relâchement du bp
    			delay(100);                                              // Pour eviter les rebonds au relachement
    		}
    	}
    }
     
    //------------------------------------- Initialisation de la gare
    void gareInitialisation()
    {
    	Serial.println(F("\tC2_V1"));
    	Serial.println(F("Initialisation de la gare"));
    	motAigMouvement(maG1_D, true); // aiguillage G1 D
    	motAigMouvement(maA1_G, true); // aiguillage A1 G
    	motAigMouvement(maA3_G, true); // aiguillage A3 G
     
    	Serial.println(F("\tC2_V2"));
    	motAigMouvement(maB1_G, true); // aiguillage B1 G
    	motAigMouvement(maB3_D, true); // aiguillage B3 D
    	motAigMouvement(maA2_D, true); // aiguillage A2 D
    	motAigMouvement(maA4_G, true); // aiguillage A4 G
     
    	Serial.println(F("\tC3_V3"));
    	motAigMouvement(maB2_D, true); // aiguillage B2 D
    	motAigMouvement(maB4_G, true); // aiguillage B4 G	
    }
     
    //------------------------------------- Action quand bouton bpNumero est pressé
    void bpPresseAction(int bpNumero)
    {
    	Serial.print(F("Bouton\t"));
    	Serial.print(bp[bpNumero].nom);
    	Serial.print(F("\tPresse\t aiguilles\t"));
     
    	for (int m = 0; m < bpMotNombreMax; m ++)                             // Lister tout les ports moteur du bp bpNumero
    	{
    		int motAigIndex = bp[bpNumero].motPort[m];                        // Numero du port moteur
    		if (motAigIndex != maNU)                                          // Si port utilise
    		{
    			Serial.print(motAig.nom[motAigIndex]); Serial.print("\t");
    			motAigMouvement(motAigIndex, false);
    		}
    	}
    	Serial.println("");	
    }
     
    //------------------------------------- Moteur aiguille mouvement
    void motAigMouvement(byte motAigIndex, boolean echoCmd)
    {
    	byte motAigPort = motAig.port[motAigIndex];
    	digitalWrite(motAigPort, motEtatOn);       // Moteur ON
    	delay(motEtatOnTemps);
    	digitalWrite(motAigPort, !motEtatOn);      // Moteur NOT ON
    	delay(motEtatOnTemps);
     
    	if (echoCmd)
    	{
    		Serial.print(F("Aiguille ")); Serial.println(motAig.nom[motAigIndex]);
    	}
    }


    Citation Envoyé par Jsiorat Voir le message
    En parlant de l'IDE Arduino, je regrette qu'on ne sois pas en mesure de faire du "step by step" pour débugger un programme.
    Avez-vous connaissance d'un IDE qui puisse faire ça ? un plugin peut-être ?
    Du "step by step" je ne connais pas, mais, avec l'IDE Arduino, un Serial.begin(115200); dans setup() et quelques Serial.println(....); par ci, par là, permettent, déjà, de faire un sacré boulot. Je travaille uniquement comme ceci, sauf, qu'en matière d'IDE, j'utilises Atmel Studio 7.0 avec l'extension Visual Micro.

    PS: Si ton pupitre est susceptible de s'étendre, par l'ajout d'aiguilles et de boutons, une solution est d'utiliser des interfaices E/S sur bus i2C, ainsi, toute le "torche" est dans le pupitre et tu n'as plu que 4 fls (GND VCC SDA SCL) qui vont à l'Arduino. L'interface est le MCP23017 qui a 16 E/S programmables et tu peux en mettre 8 (= 8x16 E/S sur ces 4 fils). Ce circuit est très aisé à "insérer" dans ton programme.

    A ta disposition
    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  12. #12
    Membre expérimenté
    @jp

    avec ce code
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		if (digitalRead(bp[b].port) == bpEtatPresse)
    		{
    			bpPresseAction(b);
     
    			while(digitalRead(bp[b].port) == bpEtatPresse){}         // Attente du relâchement du bp
    			delay(100);                                              // Pour eviter les rebonds au relachement
    		}
    si le bouton a des rebonds, le while() ne va pas attendre le relâchement du bouton mais va capturer le premier rebond et ensuite le delay() va ignorer tous les autres rebonds ==> le code n'a pas vraiment attendu le relâchement du bouton

    Si vos boutons ont du rebond, un moyen de le voir serait de maintenir le bouton enfoncé, ça devrait relancer l'action (sauf si le temps d'exécution de bpPresseAction() a été assez long pour gommer les rebonds)

    l'autre souci si vous attendez de manière active le relâchement du bouton c'est qu'on ne peut pas appuyer sur un autre bouton pendant ce temps

  13. #13
    Membre régulier
    Citation Envoyé par Jay M Voir le message
    @jp

    Si vos boutons ont du rebond, un moyen de le voir serait de maintenir le bouton enfoncé, ça devrait relancer l'action (sauf si le temps d'exécution de bpPresseAction() a été assez long pour gommer les rebonds)
    Mais comment faites-vous pour penser à ce genre de problème et le transformer en code ... Je suis admiratif !
    Vous avez messieurs une expérience que je n'aurai jamais ! je vous tire mon chapeau !
    Ce temps de bpPresseAction, on peut l'estimer à combien en milli secondes ? plus que le delay qui suit ?
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

  14. #14
    Membre expérimenté
    Salut Jay M

    Toujours à l'affut !

    Pour ce qui est des rebonds, avec de mauvais boutons, ça fonctionne très bien.
    Pour la nécessité de pouvoir presser plusieurs boutons, ce n'est spécifié nulle part. Cet exemple se veut une base de départ et n'oublies pas que Jacques débutes et on pourras toujours faire évoluer vers du multi boutons.


    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  15. #15
    Membre expérimenté
    Bonsoir Jacques
    Citation Envoyé par Jsiorat Voir le message
    Ce temps de bpPresseAction, on peut l'estimer à combien en milli secondes ? plus que le delay qui suit ?
    Je te rassure, ce temps est suffisant pour éviter les rebonds, au pire, si tes boutons sont vraiment mauvais, l'ordre part 2 fois. Ça ne m'est pas arrivé.
    J'ai choisi cette façon de faire pour faire au plus simple. on pourra toujours plus tard, faire plus évolué pour "assurer".

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  16. #16
    Membre expérimenté
    @JP -> À l’écoute, pas à l’affût.


    Pour faire au plus simple et éviter tout doublon il suffit d’insérer une attente aussi avant (15 à 20ms suffisent pour la majorité des boutons) comme cela c’est symétrique Et cohérent à l’appui et au relâchement
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (digitalRead(bp[b].port) == bpEtatPresse) {
      bpPresseAction(b);
      delay(20);  // Pour éviter les rebonds d’appui 
      while(digitalRead(bp[b].port) == bpEtatPresse) {}         // Attente du relâchement du bp
      delay(20);  // Pour éviter les rebonds au relachement
    }


    Si on se fiche d’envoyer plusieurs fois la commande, on peut ne pas mettre d’attente du relâchement et faire juste
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
     if (digitalRead(bp[b].port) == bpEtatPresse) bpPresseAction(b);


    Concernant cette remarque
    Pour la nécessité de pouvoir presser plusieurs boutons, ce n'est spécifié nulle part. Cet exemple se veut une base de départ et n'oublies pas que Jacques débutes et on pourras toujours faire évoluer vers du multi boutons.
    Bien sûr c’était juste un point pour que Jacques note ce fait. Avec de nombreuses voies on peut jouer à plusieurs ou à deux mains pour aiguillages combinés

  17. #17
    Membre expérimenté
    Bonjour Jay M
    Citation Envoyé par Jay M Voir le message
    Pour faire au plus simple et éviter tout doublon il suffit d’insérer une attente aussi avant (15 à 20ms suffisent pour la majorité des boutons) comme cela c’est symétrique Et cohérent à l’appui et au relâchement
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (digitalRead(bp[b].port) == bpEtatPresse) {
      bpPresseAction(b);
      delay(20);  // Pour éviter les rebonds d’appui 
      while(digitalRead(bp[b].port) == bpEtatPresse) {}         // Attente du relâchement du bp
      delay(20);  // Pour éviter les rebonds au relachement
    }

    Ce nouveau délais (delay(20);) vient ajouté aux 2x delay(motEtatOnTemps)(dans motAigMouvement() à chaque mouvement d'aiguille, donc dans le plus simple des cas comme C2_V3 aevc 2 aiguilles, on a 2x2xmotEtatOnTemps donc 4 x 50Msec.?

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  18. #18
    Membre expérimenté
    oui, comme dit précédemment si bpPresseAction(b); est suffisamment long alors il n'y a pas de souci.

    Comme vous le dites, dans ce cas précis ce n'est pas nécessaire puisque s'il n'y a aucun moteur attaché, appeler plusieurs fois la fonction n'est pas un pb (ça ne fait rien) et s'il y en a au moins un on aura des attentes actives suffisamment longues pour gommer les rebonds d'appui. (pas sûr que le second delay(motEtatOnTemps); soit nécessaire, j'ai cru comprendre que le premier c'était le temps que l'aiguillage se déplace et ensuite on éteint la commande)

    L'objectif est juste pédagogique puisque Jacques débute, mentionner qu'il faut tenir compte des rebonds dans les deux sens (cf sa remarque d'ailleurs). Vous l'aviez explicité pour le relâchement, l'idée était de rendre visible ce besoin aussi lors de l'appui et une façon générale simple de faire est de rajouter ce delay(20); avant et après l'attente active (voire delay(15); ça ne m'a jamais joué de mauvais tour avec mes boutons)

    L'autre option qui me semble était l'intention inachevée de Jacques au départ (d'après le code posté) serait d'utiliser la bibliothèque de Thomas Ouellet Fredericks (bounce) pour gérer les boutons (Personnellement je préfère la biblio de @bricoleau du forum arduino qui a l'avantage d'être compacte et en français ou alors celle de Matthias Hertel (OneButton)).

    ==> ça permet de cacher toute cette complexité et de se concentrer sur le coeur de code, ce qui est sympathique quand on débute.


    on a l'embarras du choix !

  19. #19
    Membre expérimenté
    Citation Envoyé par Jsiorat Voir le message
    ces boutons-poussoirs doivent actionner des moteurs nommés comme suit :
    C1_V1 => G1, A1, A3 ;
    C1_V2 => G1, A1, A4 ;
    C2_V1 => B1, B3, A2, A3 ;
    C2_V2 => B1, B3, A2, A4 ;
    C2_V3 => B1, B4 ;
    C3_V1 => B2, B3, A2, A3 ;
    C3_V2 => B2, B3, A2, A4 ;
    C3_V3 => B2, B4 ;
    bonjour

    A titre de curiosité, comment fonctionnent ces moteurs ? vous en avez deux par aiguillage on dirait, mécaniquement comment cela se passe-t-il ?

    (ou est-ce qu'il n'y a en fait qu'un seul moteur et la pin active un certain sens ?)

  20. #20
    Membre régulier
    Citation Envoyé par Jay M Voir le message
    bonjour

    A titre de curiosité, comment fonctionnent ces moteurs ? vous en avez deux par aiguillage on dirait, mécaniquement comment cela se passe-t-il ?

    (ou est-ce qu'il n'y a en fait qu'un seul moteur et la pin active un certain sens ?)
    Bonjour en ce WE encore ensoleillé !
    ce sont des des moteurs à solénoïdes, c'est ce qu'il y a de plus simples : un côté droit, un côté gauche.
    Achetés en Allemagne, chez TILLIGBAHN.
    Être vieux, c'est être jeune depuis plus longtemps que les autres !

###raw>template_hook.ano_emploi###