LOCODUINO

Un automatisme de Passage à Niveau

Avec un simple Pro Mini

. Par : Dominique, JPClaude

Le cahier des charges Le passage à niveau doit protéger une double voie, dont l’une des branches est en "Y". Il y a donc 5 sections de voies de part et d’autre du passage à niveau. Sur chaque branche, sont disposés 2 détecteurs de type interrupteur à lame souple, "ILS". Il y en a donc 10 au total. Le plus proche du passage à (…)

Retourner à l'article

Vous répondez à :

Un automatisme de Passage à Niveau 13 mai 2019 15:53, par Dominique

Raccordés comment ? Mécaniquement, électriquement, à quoi, comment ?

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

24 Messages

  • Un automatisme de Passage à Niveau 2 mai 2016 10:34, par Jean VEDIE

    Tout est parfait le seul regret est la détection par ILS ! celle par détecteur de consommation de courant ? qui éviterai de coller des aimants sous le matériel roulant et plus discret !

    Répondre

  • Un automatisme de Passage à Niveau 2 mai 2016 14:42, par Dominique

    Merci pour le compliment !

    Les ILS sont le choix du modéliste qui a installé le passage à niveau. Il fait ses détections par ILS. La solution décrite dans cet article peut supporter toutes sortes de détecteurs auxquels il faudra adapter le schéma et le logiciel.

    D’ailleurs vous en verrez d’autres dans les prochains articles.

    Je vous encourage à nous faire part de vos choix et réalisations sur le Forum Locoduino.

    Répondre

  • Un automatisme de Passage à Niveau 2 mai 2016 14:53, par Dominique

    La discussion sur le forum est là.

    Voir en ligne : http://forum.locoduino.org/index.ph...

    Répondre

  • Un automatisme de Passage à Niveau 18 juin 2018 15:34, par lionel

    Bonjour.
    merci pour cet article, et les commentaires détaillés du programme !

    Avez-vous des nouvelles de la sonnerie du PN ?
    (la gestion de la carte SD m’intéresse ...)

    Répondre

  • Un automatisme de Passage à Niveau 13 mai 2019 15:39, par Philippe

    Bonjour,
    pourrait on raccordés deux servos pour commandé la fermeture des barrières ?

    Répondre

  • Un automatisme de Passage à Niveau 13 mai 2019 17:00, par Philippe

    Électriquement à l’arduino

    Répondre

    • Un automatisme de Passage à Niveau 13 mai 2019 17:37, par JPClaude

      J’avais fait un programme dans ce genre pour une traversée de PN en un seul sens, cela peut peut être vous donnez des idées pour votre cas.
      Voici le programme, ATTENTION les deux servos sont tête bêche ce qui veut dire qu’ils tournent en sens inverse cela est dû à la limite de leur emprise en les couchant sur le coté.

      /*****************************************************************************
       * Gestion d'une barriere dans un seul sens de direction par
       * 2 capteurs un pour l'entree du train et l'autre pour la sortie, ILS, detecteur de consommation ou autre
       * 2 servos de type SG90 mis tete beche sur leur cote afin de limiter leur emprise
       * ce qui fait que quand un servo tourne dans un sens l'autre tourne dans l'autre sens
       * et 2 feux routiers qui clignotent
       ***************************************************************************/
      
      
      #include <Servo.h>
      #include <Bounce2.h>
      
      #define PIN_CAPTEUR_OUVRE 2   
      #define PIN_CAPTEUR_FERME 3   
      #define INTERVAL 50
      
      #define PIN_FEU_DROIT 4
      #define PIN_FEU_GAUCHE 5
      #define ALLUME 0
      #define ETEINT 255
      #define VITESSE_CLIGNOTEMENT 250
      
      #define PIN_SERVO_DROIT A2  
      #define PIN_SERVO_GAUCHE A3 
      
      // a regler en fonction des servos
      
      #define VITESSE_SERVO 80
      #define ANGLE_FERMETURE 1300
      #define ANGLE_OUVERTURE 1900
      #define PAS_ANGULAIRE 20
      
      /***********************************************************************
       * les feux routiers
       **************************************************************************/
       
      int cycle = 0;                                        // cycles de clignotement
      int changement = VITESSE_CLIGNOTEMENT;                // vitesse de clignotement
      unsigned long timerLed = millis();                    // timer pour le clignotement
      
      /******************************************************************************
       * les capteurs
       ********************************************************************************/
      
      Bounce capteurOuverture;                              // anti rebond
      Bounce capteurFermeture;                              // anti rebond
      
      /************************************************************************************
       * les servos
       **************************************************************************************/
      
      int angleFerme = ANGLE_FERMETURE;                     // angle de fermeture
      int angleOuvre = ANGLE_OUVERTURE;                     // angle pour l'ouverture
      int angleDroit;                                       // angle actuel du servo 1
      int angleGauche;                                      // angle actuel du servo 2
      int pasServo = PAS_ANGULAIRE;                         // pas angulaire
      enum mode {montee,descente,arret};
      mode sens = arret;                                    // sens du mouvement de la barriere
      enum etat {ouvert, ferme, encours};
      etat situation = ouvert;                              // situation de la barriere
      bool actif = false;                                   // etat de la manoeuvre                                      
      unsigned long timerServo;                             // timer pour le servo
      int duree = VITESSE_SERVO;                            // vitesse des servos            
      Servo servoDroit;                                     // servo de la premiere barriere
      Servo servoGauche;                                    // servo de la seconde barriere
      
      /*****************************************************************************
       * clignotement des feux routiers
       ***************************************************************************/
       
      void clignote() {
      if (timerLed + changement < millis())     // vitesse de clignotement
          {
          timerLed = millis();                  // reinit le timer
          switch (cycle) {
                  case 0 : {analogWrite(PIN_FEU_DROIT,ALLUME); analogWrite(PIN_FEU_GAUCHE,ALLUME);cycle = 1;break;}      // on allume
                  case 1 : {analogWrite(PIN_FEU_DROIT,ETEINT); analogWrite(PIN_FEU_GAUCHE,ETEINT);cycle = 0;break;}      // on eteint
              }
          }
      }
      
      /*****************************************************************************
       * initialisation de l'ouverture des barrieres
       *****************************************************************************/
       
      void ouverture() {
      if (situation != ouvert) {                      // si pas deja ouvert
          servoDroit.attach(PIN_SERVO_DROIT);           // on attache les servos
          servoGauche.attach(PIN_SERVO_GAUCHE);  
          actif = true;                               // on devient actif           
          angleDroit = angleFerme;                    // une des barrieres va vers le bas (inversion des servos)
          angleGauche = angleOuvre;                   // l'autre en symetrie va vers le haut
          timerServo = millis();                      // MAJ du timer
          sens = montee;                              // on monte           
          situation = encours;                        // manoeuvre en cours
          }
      }
      
      /**************************************************************************
       * initialisation de la fermeture des barrieres
       ***************************************************************************/
       
      void fermeture() {
      if (situation != ferme ) {                      // si pas deja ferme
          servoDroit.attach(PIN_SERVO_DROIT);                          // on attach les servos
          servoGauche.attach(PIN_SERVO_GAUCHE);
          actif = true;                               // on devient actif
          angleDroit = angleOuvre;                        // une des barrieres va vers le haut (inversion des servos)
          angleGauche = angleFerme;                        // l'uatre en symetrie vers le bas
          timerServo = millis();                      // MAJ des timers
          timerLed = millis();
          sens = descente;                            // on descend           
          situation = encours;                        // manoeuvre en cours   
          }
      }
      
      /*******************************************************************************
       * manoeuvre de la bbariere
       *********************************************************************************/
       
      void manoeuvre() {
        if (actif){
          if ((timerServo + duree) < millis()){             // vitesse des servos
                  if (sens == montee) {angleDroit += pasServo; angleGauche -= pasServo;          // on monte
                                      if (angleDroit >= angleOuvre) {           // en bout de course
                                          actif = false;                    // on n'est plus actif
                                          sens = arret;                     // on est a l'arret
                                          situation = ouvert;               // la barriere est ouverte
                                          analogWrite(PIN_FEU_DROIT,ETEINT);           // on eteint les feux routiers
                                          analogWrite(PIN_FEU_GAUCHE,ETEINT);
                                          servoDroit.detach();                  // on detache les servos
                                          servoGauche.detach();
                                          return;}                          // termine
                                      }
                  if (sens == descente) {angleDroit -= pasServo; angleGauche += pasServo;      // on descend
                                      if (angleDroit <= angleFerme) {         // en bout de course
                                        actif = false;                    // on n'est plus actif
                                        sens = arret;                     // on est a l'arret
                                        situation = ferme;                // la barriere est fermee
                                        servoDroit.detach();                  // on detache les servos
                                        servoGauche.detach();
                                        return;}                          // termine
                                      }
                  servoDroit.writeMicroseconds(angleDroit);                       // on avance de l'angle  
                  servoGauche.writeMicroseconds(angleGauche);
                  analogWrite(PIN_FEU_DROIT,ALLUME);                                   // on allume les feux routiers
                  analogWrite(PIN_FEU_GAUCHE,ALLUME);
                  timerServo = millis();
              }
          }
      }
      
      /*******************************************************************
       * setup
       ******************************************************************/
       
      void setup()
      {
          servoDroit.attach(PIN_SERVO_DROIT);servoDroit.writeMicroseconds(angleOuvre);
          servoGauche.attach(PIN_SERVO_GAUCHE);servoGauche.writeMicroseconds(angleFerme);
          pinMode(PIN_CAPTEUR_OUVRE,INPUT_PULLUP);capteurOuverture.attach(PIN_CAPTEUR_OUVRE);capteurOuverture.interval(INTERVAL);
          pinMode(PIN_CAPTEUR_FERME, INPUT_PULLUP);capteurFermeture.attach(PIN_CAPTEUR_FERME);capteurFermeture.interval(INTERVAL);
          analogWrite(PIN_FEU_DROIT,ETEINT);
          analogWrite(PIN_FEU_GAUCHE,ETEINT);
      }
      
       /*******************************************************************
        * la boucle
        ********************************************************************/
        
      void loop()
      {    
           if (situation == ferme) { clignote();}
           if (capteurOuverture.fell()) {ouverture();}
           if (capteurFermeture.fell()) {fermeture();}
           if (situation == encours) {manoeuvre();}
           capteurOuverture.update();
           capteurFermeture.update();
           
       }

      Répondre

  • Un automatisme de Passage à Niveau 13 mai 2019 17:43, par Philippe

    Merci beaucoup

    Répondre

  • Un automatisme de Passage à Niveau 9 décembre 2019 01:41, par tresorier21000

    Bonjour

    Nouveau venu, je découvre ce site et ce forum très intéressant.

    Pour information, sur le fonctionnement d’un PN à SAL :
    les feux :

    • s’allument dès le déclenchement de l’arrivée du train
    • s’éteignent dès le début de l’ouverture des barrières

    Les barrières :

    • commencent la fermeture 7s après le déclenchement de l’arrivée du train (et donc 7s après l’allumage des feux)
    • se ferment et s’ouvrent en 8 à 10s

    Les sonneries :

    • fonctionnent dès le déclenchement de l’arrivée du train et l’allumage des feux
    • s’arrêtent quand les barrières sont fermées.

    J’aurai sans doute des questions sur l’usage d’arduino !
    A bientot

    Répondre

  • Un automatisme de Passage à Niveau 9 décembre 2019 07:04, par Dominique

    Merci pour ces précisions, et pouvez-vous en mentionner la source et l’époque.

    Répondre

    • Un automatisme de Passage à Niveau 9 décembre 2019 11:58, par tresorier21000

      Bien sur !

      La source, c’est le référentiel IN323 du 15/10/1980 de la SNCF (Equipement des PN et réglementaiton article 9) que je ne peux pas diffuser ici. Il est en cours de réécriture pour tenir compte de l’arrêté ministériel du 18/03/1991 rectifié en 2017. Mais rien ne changera sur cette partie de fonctionnement.
      Vous pouvez vous poster à un PN pour constater ces valeurs.
      Je n’ai pas mis toutes les tolérences, mais pour le préavis (7s indiqué avant la descente des barrières) c’est 6 à 8s.

      Par contre, je n’utiliserai pas les détections individuelles, puisque le vrai cablage d’un PN totalise l’ensemble des provenances des trains (les relais d’annonce) sur un seul relais (la commande de la signalisation routière). C’est donc celui-ci qui servira à commander les feux, barrières et sonneries.
      Le réarmement de chaque annonce se fait par un passage sur le PN (1 zone courte par voie) qui réarme l’annonce déclenchée et par extension le relais totalisateur des annonces.

      Pour être précis, la signalisation, les postes d’aiguillage et les PN, c’était mon métier pendant 40 ans !
      J’ai encore une petite activité de recherche sur les PN et j’ai besoin de faire un maquettage, d’où mon besoin d’un arduino.

      Au plaisir

      Répondre

  • Un automatisme de Passage à Niveau 9 décembre 2019 14:03, par Dominique

    Alors là, bravo !

    En cas de besoin, on sera là pour vous aider.

    Cordialement

    Répondre

    • Un automatisme de Passage à Niveau 9 décembre 2019 18:19, par tresorier21000

      De même !

      Par contre, je n’ai pas de connaissance en modélisme.
      J’ai joué en vrai dans des postes d’aiguillage, des TCO, des PN,...

      A bientot

      Répondre

    • Un automatisme de Passage à Niveau 12 février 2020 14:40, par tresorier21000

      Bonjour

      Je suis en train de réaliser un passage à niveau au plus près de la réalité.
      Tout fonctionne correctement (il me manque encore le son), mais je me heurte à un problème d’affichage sur un écran.

      Je voudrais afficher en permanence sur un écran LCD I2C, l’état de 4 relais pour indiquer l’état du PN.
      J’arrive bien à faire fonctionner mon affichage dans un programme isolé en utilisant la fonction delay().
      Par contre, il n’est pas possible de bloquer l’ensemble du programme avec cette fonction.
      Comment pourrais-je m’en sortir ?
      J’avais pensé à utiliser MsTimer2, mais là, je suis bloqué !

      Merci de votre aide

      mon croquis ecran :

      /* Fonctionnement d’un ecran LCS I2C sur Mega *****************
      * Branchement en +VCC, GND, SDA (20) et SLC (21)
      * Informations provenant de 4 contats de relais
      * branchés en A0, A1, A2 et A3 avec Resistances et capa
      * pour gérer les rebonds (avec un trigger sur la carte finale
      * ***********************************************************/

      /* programme non compatible avec le reste du passage à niveau
      * du fait de l’utilisation de la fonction delay(1000) pour
      * l’affichage des différents états à l’écran (blocage du prog)
      * *********************************************************/

      #include <LiquidCrystal_PCF8574.h>
      #include <Wire.h>
      #include <MsTimer2.h>

      LiquidCrystal_PCF8574 lcd(0x27) ; // set the LCD address to 0x27 for a 16 chars and 2 line display
      int show = -1 ;
      #define PIN_S0 A0
      #define PIN_S1 A1
      #define PIN_S2 A2
      #define PIN_S3 A3
      boolean etat0 ;
      boolean etat1 ;
      boolean etat2 ;
      boolean etat3 ;
      int etatbouton = 1 ;

      void setup()
      // declaration des boutons en entrée
      pinMode (PIN_S0, INPUT) ;
      pinMode (PIN_S1, INPUT) ;
      pinMode (PIN_S2, INPUT) ;
      pinMode (PIN_S3, INPUT) ;

      // MsTimer2 : : set (1000, ecran) ; periode de 1s
      // MsTimer2 : : start() ;

      int error ;
      Serial.begin(115200) ;
      Serial.println("LCD...") ;
      // wait on Serial to be available on Leonardo
      while (!Serial) ;
      Serial.println("Dose : check for LCD") ;
      // Voir http://playground.arduino.cc/Main/I... pour tester le port I2C.
      Wire.begin() ;
      Wire.beginTransmission(0x27) ;
      error = Wire.endTransmission() ;
      Serial.print("Error : ") ;
      Serial.print(error) ;
      if (error == 0)
      Serial.println(" : LCD found.") ;
      show = 0 ;
      lcd.begin(16, 2) ; // initialize the lcd
      else
      Serial.println(" : LCD not found.") ;
      // fin if
      // fin setup()

      void loop()
      etat0 = digitalRead(PIN_S0) ;
      etat1 = digitalRead(PIN_S1) ;
      etat2 = digitalRead(PIN_S2) ;
      etat3 = digitalRead(PIN_S3) ;
      lcd.setBacklight(255) ;
      lcd.home() ;
      lcd.clear() ;

      Serial.print(etat0) ;
      Serial.print(etat1) ;
      Serial.print(etat2) ;
      Serial.print(etat3) ;

      switch (etatbouton)
      case 1 : if (etat0 == LOW) //HIGH avec bascule de schmitt (inversion du signal) sinon LOW
      lcd.setCursor(0, 0) ;
      lcd.print(" PN a 298 metres ") ;
      lcd.setCursor(0, 1) ;
      lcd.print(" ") ;

      case 2 : if (etat1 == LOW)
      lcd.setCursor(0, 0) ;
      lcd.print(" PN a 240 metres ") ;
      lcd.setCursor(0, 1) ;
      lcd.print(" Ferme") ;

      case 3 : if (etat2 == LOW)
      lcd.setCursor(0, 0) ;
      lcd.print(" Danger ") ;
      lcd.setCursor(0, 1) ;
      lcd.print(" Ne pas franchir ") ;

      case 4 : if (etat3 == LOW)
      lcd.setCursor(0, 0) ;
      lcd.print(" Route barree") ;
      lcd.setCursor(0, 1) ;
      lcd.print(" travaux") ;

      case 5 : if (etat0==HIGH && etat1==HIGH && etat2==HIGH && etat3==HIGH)
      lcd.setCursor(0, 0) ;
      lcd.print(" Etat du PN ") ;
      lcd.setCursor(0, 1) ;
      lcd.print(" indetermine") ;

      delay(1000) ;

      //fin de loop

      Répondre

      • Un automatisme de Passage à Niveau 12 février 2020 17:18, par msport

        Bonjour,
        vous avez fait le bon diagnostic avec delay.
        A sa place, mettez la mise à jour de votre lcd dans un if genre millis > old_millis + raffraichissement et màj de old_millis ...
        Utilisez plutôt le forum, cela vous évitera de voir vos accolades disparaitre.

        Répondre

  • Un automatisme de Passage à Niveau 3 avril 2020 18:56, par M. Resse jean pierre

    Bonjour.
    Ce tuto m’intéresse beaucoup car j’ai un PN un peut dans cette configuration mais plus "compliqué".
    En effet, deux voies à double sens avec chacune une sortie dont un croisement pour le dépôt en sortie du PN.
    Ma question est de savoir si il y a possibilité de remplacer les ILS pas des LEDS Infra Rouge ( il y en a qui se placent entre les traverses) pour ne pas avoir à instaler des aimants sur tout le matériel roulant.
    Merci pour votre réponse et bravo pour ce site.
    Cordialement JP.

    Voir en ligne : http://locoduino.org/spip.php++cs_INTERRO++article117

    Répondre

    • Un automatisme de Passage à Niveau 3 avril 2020 20:16, par Dominique

      Oui c’est possible en respectant la logique des capteurs (équivalent à un ILS du point de vue logique). Pour le reste vous pouvez adapter le programme à votre réseau.

      Répondre

  • Un automatisme de Passage à Niveau 4 avril 2020 10:39, par M. Resse jean pierre

    Bonjour.
    Merci pour votre réponse rapide, je vais essayé d’adapter ce montage avec les IR et je vous teins au courent de la suite .
    A bientôt JP.

    Répondre

  • Un automatisme de Passage à Niveau 29 octobre 2020 19:48, par Frédéric

    Bonjour,

    J’ai réalisé un PN simple pour un train LGB. Gestion de deux servos moteur, du clignotement de deux LED, détection par ils. Lors du rajout ultérieur de la sonnerie sur une carte arduino uno avec un DFplayer mini, j’ai observé qu’à la lecture du fichier son mp3, les servos étaient perturbés par cette lecture (notamment au démarrage de la lecture sur la carte SD). J’avais logiquement utilisé la librairie softwareserial pour émuler une nouvelle connexion série pour ma carte DFplayer avec l’arduino UNO, celui ci ne disposant nativement que d’une seule sortie série (déjà utilisée par la connexion USB)
    Je précise que les servos étaient alimentés par une alimentation régulée 5V dédiée avec un GND commun sur l’arduino
    J’avais choisi le DFplayer mini car celui ci est peu couteux, facile à programmer avec la bibliothèque DFRobotDFPlayerMini, et disposant d’un petit amplificateur intégré.
    Disposant d’une carte MEGA, J’ai reconnecté le DFplayer sur la sortie serial2. Dans ce contexte, je n’observe plus aucune perturbation de fonctionnement sur les servos, tout fonctionne parfaitement. Pour autant c’est un peu dommage d’utiliser une carte MEGA pour une application finalement assez simple
    Je tenais à vous faire part de ce retour d’expérience, je pense qu’il doit être possible de tout réunir sur une carte UNO, mais à l’instant je ne trouve pas la solution
    Pourriez vous me donner votre avis sur ce sujet

    Votre site est une vrais source d’inspiration, je vous félicite pour tout ce travail réalisé

    Frédéric

    Répondre

  • Un automatisme de Passage à Niveau 10 mai 2021 11:31, par Pierre

    Bonjour, cela fait quelques jours que j’essais de remplacer les relais par des servos, mais je sèche. Auriez-vous une piste à me proposer ?
    Merci.

    Répondre

  • Un automatisme de Passage à Niveau 10 mai 2021 14:28, par msport

    Bonjour,
    vous n’avez pas vu le 8e commentaire ?
    sinon, lisez la série d’articles Passage à niveau géré par Arduino (1 à 5)
    Et pour un dépannage passez sur le forum.
    Cordialement

    Voir en ligne : Passage à niveau géré par Arduino (5)

    Répondre

Rubrique Projets

Les derniers articles

Les articles les plus lus