LOCODUINO

Discussions Générales => Présentez vous ! => Discussion démarrée par: Minimir09 le septembre 11, 2020, 04:26:31 pm

Titre: À votre avis ...
Posté par: Minimir09 le septembre 11, 2020, 04:26:31 pm
Bonjour à toutes et tous,

Avec le matériel (photo ci-jointe) est-il possible de commander plusieurs moteurs d'aiguillage à solénoïde avec le même relais ?
Explication : je prévois de passer par plusieurs aiguillages pour aller d'un point A jusqu'à un point B et j'aimerai que, avec un seul bouton de commande, tous les aiguillages permettent le passage d'une rame sans avoir à manipuler les commandes de chacun des aiguillages.
Exemple : pour aller de C3 en voie 1
Merci pour vos réponses
Jacques
Titre: Re : À votre avis ...
Posté par: Dominique le septembre 11, 2020, 05:48:58 pm
Chez moi j’utilise 2 relais par aiguille : un pour le sens et un pour l’impulsion de commande :
 http://forum.locoduino.org/index.php?topic=290.msg3412#msg3412 (http://forum.locoduino.org/index.php?topic=290.msg3412#msg3412)

De plus il faut éviter de commander plusieurs aiguilles en même temps ce qui provoquait un appel de courant fort.
Ca se fait par soft avec une file d’attente des commandes d’aiguilles.
Titre: Re : À votre avis ...
Posté par: msport le septembre 11, 2020, 07:10:52 pm
Pour se faire l'avocat du diable, on peut regarder les étiquettes et les notices :

Fleischmann / ROCO indique pour un aiguillage en N : 0,7A sous 14 à 16 V (~), donc plus en continu (12 ohms) .

Pour aller de C3 à V1, il y a 4 aiguillages, soit 2,8 A, soit ~ 50W.

Donc c'est possible si le transfo alternatif fait au moins 50W, puisque chaque relais est marqué 10A.

Maintenant est-ce raisonnable ? Moi, je ne le ferai pas, surtout dans un environnement Arduino.

Dominique a donné la solution.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 11, 2020, 07:53:22 pm
Une idée qui me passe par la tète à la lecture de vos réflexions ...
Dominique : "un pour le sens et un pour l’impulsion de commande".
-- Ne pourrait-on provoquer l'action sur l'aiguille suivante une fois que la précédente a terminé ?

ça se réalise sur les moteurs d'aiguilles de chez Tillig Bahn (n° d'article : 86112) voir le schéma ci-dessous, c'est du branchement direct et ça n'utilise pas Arduino.
Qu'en pensez-vous vous les Maîtres es Arduino ?
Titre: Re : À votre avis ...
Posté par: msport le septembre 11, 2020, 08:50:42 pm
ça doit dater d'avant l'invention de l'Arduino ?
Titre: Re : À votre avis ...
Posté par: Dominique le septembre 11, 2020, 09:11:18 pm
Vu le prix des relais par 8 ou 16, je garde mon conseil comme proposition et ça marche depuis plusieurs années  :D
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 12, 2020, 05:21:07 pm
Permettez-moi d'insister sur ce problème ... (qui n'en est peut-être pas un !)
serait-il possible de programmer un temps de latence entre chaque commande envoyé au relais, par exemple une attente d'une seconde ?
ceci dans le but d'éviter les inconvénients cités dans la réponse de msport ?
- envoi cde relais 1
-- attente 1 seconde
--- envoi cde relais 2
---- attente 1 seconde
----- envoi cde relais 3
etc ... une seconde, c'est peut-être bien ou beaucoup ou pas assez ...
alors, possible ou pas possible ? faisable ou pas faisable ?
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 12, 2020, 06:15:00 pm
Pour reprendre mon message précédent,
j'ai trouvé le document écrit par JPClaude en 2015 ou on peut trouvé le code qui je crois devrait convenir à mon interrogation.
Étant un programmeur nul et très mauvais, à 75 ans c'est très difficile de se dénouer le cerveau (!), à quel endroit de ce code pourrait-on inclure une pause d'une seconde, voire d'1/2 seconde pour obtenir le résultat désiré ?
Titre: Re : À votre avis ...
Posté par: msport le septembre 12, 2020, 11:19:27 pm
Vous devez adapter ce qui est déjà écrit, ce que nous faisons tous, malgré nos nombreux printemps.
Pour cela, il faut au moins que vous maitrisiez les bases : lire un bouton, allumer une LED ...

Ici, il faut lire un bouton itinéraire dans le loop (à déclarer), et déclencher en séquence les quatre aiguillages.

Si l'auteur était disponible, il proposerait certainement mieux.

En en-tête :
int boutonItineraire = A5;

Dans le setup :
   pinMode(boutonItineraire,INPUT_PULLUP);

le loop
void loop() {
  for (int i = 0;i<NB_TURNOUT;i++) {if (boutonTest(i))  activation_aiguillage(i);  }
  if (digitalRead(boutonItineraire) == LOW){
    for (int i=0; i<NB_TURNOUT; i++){
        digitalWrite(turnout[i].bobine1,TRAVAIL);      // activation, bobine à choisir
        delay(ACTIVATION);                          // duree de l'activation
        digitalWrite(turnout[i].bobine1,REPOS);       // arret de l'activation
        delay(1000);
    }
  }
}

Mais je crains qu'à Locoduino, on n'écrive pas de programme pour une demande particulière.

Attention, vous avez perdu la fin du programme ... Et mieux vaut donner le lien vers l’article d'origine, Locoduino est vaste.
https://www.locoduino.org/spip.php?article142
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 13, 2020, 05:34:08 am
Merci pour cette fin du code.
Pour info, je ne veux pas qu'on me fasse mon programme ça ne me servirait pas pour comprendre ce que je lis.
Dans le cas présent, je demande simplement à quelle endroit il faut placer le code nécessaire pour procéder à une attente d'une seconde, voire d'1/2 seconde pour ne pas surcharger la carte.
Tout ce que je peux lire et comprendre de votre part à tous, est un tour de visse supplémentaire dans ma compréhension du code !
Un grand merci pour vos réponses
Titre: Re : À votre avis ...
Posté par: msport le septembre 13, 2020, 03:23:47 pm
Pouvez vous expliciter ce que vous voulez faire ?

1. une commande d'itinéraire donc commander les 4 aiguillages en séquence avec un bouton. Ce que je pensais avoir compris et proposé avec l'exemple à minima. A noter que ce n'est pas une fin de programme mais des instructions qui doivent être placées aux endroits indiqués. (le loop est remplacé)

ou

2. empêcher d'envoyer avant une seconde de temps une deuxième commande après une première.

là, il me semble que l'analyse du programme aurait du vous permettre de trouver la solution :
ajouter en ligne 96 , donc avant l'accolade qui passe à la ligne suivante.
    delay(1000);

mais c'est inutile, car le programme étant exécuté séquentiellement avec des delays, il ne commande pas deux bobines en même temps.
Titre: Re : À votre avis ...
Posté par: Dominique le septembre 13, 2020, 05:23:42 pm
Si vous n’y arrivez pas je publierai ma solution de commandes multiples d’aiguilles pour itinéraires avec délai entre aiguilles et 2 relais par aiguille (fleischmann en N). Les commandes (via Can) sont mises en tampon et exécutées successivement les unes après les autres.

Laissez moi le temps d’une mise au point après retour de vacances.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 16, 2020, 02:31:02 pm
Voilà, ça avance doucement ...
Avec le principe du "chenillard", voilà 2 photos d'une partie de mon tableau de commande encore en cours de conception.
Comme vous pouvez le constater, un seul bouton poussoir pour créer un itinéraire  ;D
Il me reste à créer sur le même principe, le TCO "Triage" :)
On avance, on avance ...  8)
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 17, 2020, 10:34:22 am
Bonjour à toutes et tous,

Hier soir, j'ai saisi ce code. Ce n'est pas parfait loin de là, mais pour un débutant ... y a très certainement mieux mais c'est plus cher !
Je ne comprends pas les erreurs qui ressortent :
====================================
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
==============================================
Pouvez-vous m'aider à résoudre ces erreurs ?
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 17, 2020, 10:37:36 am
petite précision :
 je vais utiliser une carte MEGA 2560 R3 pour le nombre de pins  !
Titre: Re : Re : À votre avis ...
Posté par: Thierry le septembre 17, 2020, 02:33:13 pm
En réalité les deux erreurs et le warning proviennent du même problème.

Le compilateur relève que vous déclarez un 'int bp[]', donc une matrice d'entiers signés, que vous utilisez comme argument alors que digitalRead() attend un uint8_t, c'est à dire un simple entier non signé . Donc première action, changer votre int bp[] en uint8_t bp[]. Seconde action, à la fois pour le digitalRead et le switch, décider lequel de ces entiers vous voulez utiliser : bp[0], bp[1], bp[2]...

Attention aussi aux rebonds. Un bouton poussoir ou un interrupteur ne passent pas proprement d'un état à l'autre. Pendant quelques millisecondes leur état navigue entre les deux et n'est pas déterminé. c'est pourquoi il faut utiliser une bibliothèque comme 'Bounce2' ou 'OneButton' qui vont introduire un délai
entre le premier changement d'état, et l'état définitif stabilisé: voir l'article "https://www.locoduino.org/spip.php?article176"
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 17, 2020, 03:12:45 pm
Merci Thierry,
"Seconde action, à la fois pour le digitalRead et le switch, décider lequel de ces entiers vous voulez utiliser : bp[0], bp[1], bp[2]..." ???
 là, je n'assimile pas !
digitalRead ... c'est bien la lecture de l'état du bouton ? si j’appuie sur ce bp, l'état doit passé de 0 à 1 (LOW à HIGH ?)
Je pense que ce "digitalRead" est mal placé et aussi mal défini.
Comment définir l'état d'un (et d'un seul) bp sur lequel on a appuyé parmi les 8 du tableau ?

Il me semble avoir lu que les cartes Arduino géraient maintenant le rebond en interne ? exact ou pas !
merci pour votre aide qui m'est très précieuse
Titre: Re : À votre avis ...
Posté par: Thierry le septembre 17, 2020, 04:06:48 pm
Là on rejoint les bases du développement : digitalRead(broche) retourne l'état d'une et une seule broche. Et l'argument sert à lui dire de quelle broche de l'Arduino on veut récupérer l'état. Si broche vaut 3, on prend l'état de la broche 3. Mais en aucun cas la broche ne peut être multiple ! Il faut donc faire une boucle sur la liste de broches 'bp' pour interroger successivement chacune d'elle. Et ça tombe bien, on a déjà une boucle qui tourne et recommence à l'infini !

digitalRead est bien placé, mais son argument est faux.

On a deux solutions pour la boucle :

Soit on se sert de loop() qui boucle tout le temps, et on traite une broche (ou un bp) à chaque passage :

int i = 0

loop()
{
  buttonState = digitalRead(bp[i]);
  ....
  i++;
  if (i >= 8)
    i = 0;
}

Soit on fait une vraie boucle à chaque loop() :

loop()
{
  for(int i = 0; i < 8; i+)
  {
    buttonState = digitalRead(bp[i]);
    ...
  }
}

Et non, les Arduino ne gèrent pas les rebonds vu qu'ils ne savent pas ce que l'on connecte au bout de leur broches... C'est le programme qui doit gérer ça.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 17, 2020, 05:23:02 pm
Ah que ! comme disait le chanteur !
Je commence à comprendre ... que j'ai encore de nombreux jours de lecture sur Locoduino !
Avant de passer à l'anti rebond, j'ai une dernière erreur que je n'arrive pas à solutionner :
=======================
F:\PROGRAMMATION PERSO\TEST_Boutons-poussoirs-et-Aiguillages\TEST_Boutons-poussoirs-et-Aiguillages.ino: In function 'void loop()':
TEST_Boutons-poussoirs-et-Aiguillages:43:17: error: switch quantity not an integer
       switch (bp) // debut de la structure
                 ^
exit status 1
switch quantity not an integer
=======================
Pourtant la variable "bp" est bien en integer !! pourquoi "switch" ne l'accepte pas ? merci pour l'aide, je m'instruis de + en + !

ci-joint le code modifié avec la boucle loop()
// 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 ;

void setup() {
  // Initialisation
  for (uint8_t bp = 0; bp <= 12; bp++) {
    pinMode(bp, INPUT) ;
  }
  for (uint8_t aig = 0; aig <= 38; 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()
{
  loop() ;
  {
    for (int i = 0; i < 12; i++)
    {
      buttonState = digitalRead(bp[i]) ;


      // l'instruction break est en option

      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�faut
          // si aucune condition n'est vraie, le code par d�faut sera ex�cut�
          // le cas default est optionnel (non -obligatoire)
      }
    }
  }
}
Titre: Re : À votre avis ...
Posté par: msport le septembre 17, 2020, 06:41:23 pm
Comme le dit Thierry  Il faut donc faire une boucle sur la liste de broches 'bp' pour interroger successivement chacune d'elle.

c'est bp[n] qui est un entier pas bp

Le switch devra se faire sur un int n que vous aurez testé avec un if ( digitalRead(bp[ i ] == LOW) {n=i;} // 2e proposition de Thierry

pour les bp, voyez l'intérêt de INPUT PULLUP

Une remarque : si vous ne faites pas suivre le
  digitalWrite(37, HIGH) ; // aiguillage B4 G

par un   digitalWrite(37, LOW) ; // aiguillage B4 G
 avec un delay entre, il va griller ...

Vous devriez réfléchir sur l'exemple du site éditorial cité plus haut et bien voir ce qu'il fait.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 18, 2020, 07:02:02 am
Bonjour,
Eh ben voilà ... ce soir je vais me mettre au lit, un peu plus instruit  !  8)
Merci pour ces précisions et en particulier sur le faite de ramener à LOW la commande digitalWrite.
pour en revenir à l'origine de cette discussion, je n'avais pas tord en vous demandant votre avis sur le fait de diriger une rame en appuyant sur un seul bouton pour créer un itinéraire ...
Merci encore, à 75 ans j'en apprend toujours et encore !  :D
Titre: Re : À votre avis ...
Posté par: Thierry le septembre 18, 2020, 08:43:13 am
Attention aussi à bien faire une boucle de 0 (premier bouton) à 7 (dernier bouton). Vous la faite de 0 à 12 : vous allez au delà de la fin de la liste qui s'arrête à 7 ! Avec de la chance,  ça marchera probablement, mais le comportement sera indéterminé pour les broches de 8 à 12.
Idem dans le setup pour les initialisations : vous n'avez que 8 broches et 17 aiguillages à initialiser.

Il faut comprendre que 'bp' est un contenant, pas un contenu.
Pour faire une analogie, imaginez une étagère avec des cubes numérotés. L'étagère s'appelle 'bp' et contient 8 cubes. Lorsque vous voulez savoir ce qui se trouve sur l'étagère, vous parcourez les cubes depuis le premier, le 0 (c'est comme ça en C++...) au dernier le 7, puisque ça commence à 0. Peu importe les numéros marqués sur les cubes, vous avez toujours vos huit cubes ! Par contre, pour utiliser l'un des cubes, vous devez préciser lequel. Avec bp[3], vous utilisez la valeur du quatrième cube, quelle qu'elle soit.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 18, 2020, 09:56:25 am
Merci Thierry.
TOUT fonctionne grâce à vous, et un grand merci à msport qui m'a bien "aiguillé" aussi ! ;D
Je constate que quand on a à faire à des maîtres en la matière, on y gagne nécessairement ! 8)

 2 questions pour parfaire l'enseignement !!!!
1) en C++, plusieurs commandes sur une même ligne, commandes séparées par un ";" ... possible ou pas ?

2) serait-il nécessaire de déclarer une vitesse de transmission plus importante que le 9600 du port com ?
Pour le moment, je n'ai encore jamais branché la carte Mega 2560 en USB sur l'ordinateur.
Titre: Re : À votre avis ...
Posté par: Minimir09 le septembre 18, 2020, 10:03:29 am
La question n° 2 est sans objet !
le port comme est par défaut à 115200 !
Titre: Re : À votre avis ...
Posté par: Thierry le septembre 18, 2020, 01:56:32 pm
1) oui, mais ce n'est pas lisible. On passe souvent à côté d'une instruction parce qu'elle est au bout de la ligne... Donc en pratique, non.

2) Je ne sais pas quelle est la valeur par défaut, et peu importe d'ailleurs, mais il faut que la console soit à la même valeur que le Serial.begin() !
Titre: Re : Re : À votre avis ...
Posté par: msport le septembre 18, 2020, 03:22:21 pm
... en C++, plusieurs commandes sur une même ligne, commandes séparées par un ";"

N'allons pas trop vite, la syntaxe est celle du C, pour le C++, il faut revenir en 2e année. Moi, je n'y suis pas encore, il ne faut pas me surestimer.

PS : (au cas où) ne pas oublier les résistances pour les LED du TCO.

re PS ; et peut-être qu'il faut réinitialiser n à 0 une fois que l'ordre (les) a été exécuté pour éviter d'y revenir indéfiniment.