Auteur Sujet: Problème tempo passage à niveau  (Lu 19497 fois)

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Problème tempo passage à niveau
« le: mars 17, 2019, 05:36:52 pm »
Bonjour,
Première réalisation de programme avec Arduino, je bute sur un petit problème.
Il s'agit d'un passage à niveau sans feux clignotant (juste les barrières) détecté par un ILS pour l'ouverture, la fermeture s'effectuant au bout d'une temporisation.
Seulement, lorsque le train arrive sur le capteur, il se passe un certain temps avant que les barrières se ferment, de ce fait elles sont complètement fermées quand le train commence à quitter le pn. Que dois-je changer sur le programme ?
Sinon elles se referment bien au bout de la tempo

Voici le programme

/*
   Gestion d'un passage à niveau avec 2 capteurs ILS.

   Bibliothèques utilisées :
   - SlowMotionServo pour les barrières
   - LightDimmer pour le clignotement du feu du PN

*/

#include <Servo.h>
#include <SlowMotionServo.h>

/*
 * Décommentez la ligne ci-dessous pour avoir l'affichage
 * de l'état courant de l'automate sur les broches 8 à 12
 */
// #define AVEC_AFFICHAGE_ETAT

/*-------------------------------------------------------------------*/
/* Les états possible pour le PN */
enum { PN_OUVERT, PN_SE_FERME, PN_FERME, PN_TEMPO, PN_S_OUVRE };

/*-------------------------------------------------------------------*/
/* Les pin des capteurs et les informations renvoyées                   */
const byte capteurPin1 = 2;
const byte capteurPin2 = 6;
const byte trainPresent = LOW;
const byte trainAbsent = HIGH;




/*-------------------------------------------------------------------*/
/* Les pins des servos */
const byte barriere1Pin1 = 4;
const byte barriere2Pin1 = 5;
const byte barriere1Pin2 = 4;
const byte barriere2Pin2 = 5;

/* Les positions cibles des barrières */
const float positionOuverteBarriere1 = 0.0;
const float positionFermeeBarriere1 = 1.0;
const float positionOuverteBarriere2 = 0.0;
const float positionFermeeBarriere2 = 1.0;

/* Les servos */
SMSSmooth barriere1;
SMSSmooth barriere2;

/*-------------------------------------------------------------------*/
/* La temporisation entre la fin du train et l'ouverture des barrières
   en ms
*/
const unsigned long temporisationOuverture = 3000;

#ifdef AVEC_AFFICHAGE_ETAT
const byte ledEtat = 8;

void initAffEtat()
{
  for (byte i = ledEtat ; i < ledEtat + 5; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }
}

void afficheEtat(const byte etat)
{
  for (byte i = ledEtat ; i < ledEtat + etat; i++) {
    digitalWrite(i, LOW);
  }
  for (byte i = ledEtat + etat + 1 ; i < ledEtat + 5; i++) {
    digitalWrite(i, LOW);
  }
  digitalWrite(ledEtat + etat, HIGH);
}

#define INITAFFETAT() initAffEtat()
#define AFFICHEETAT(e) afficheEtat(e)
#else
#define INITAFFETAT()
#define AFFICHEETAT(e)
#endif

/*-------------------------------------------------------------------*/
/* Intialisations */
void setup()
{
  /* capteur de présence */
  pinMode(capteurPin1, INPUT_PULLUP);
  pinMode(capteurPin2, INPUT_PULLUP);
 
  /* les barrières */
    barriere1.setPin(barriere1Pin1);
    barriere1.setPin(barriere1Pin2);
    barriere1.setSpeed(1.0);
    barriere1.setInitialPosition(0.5);
    barriere1.goTo(positionOuverteBarriere1);
    barriere2.setPin(barriere2Pin1);
    barriere2.setPin(barriere2Pin2);
    barriere2.setSpeed(1.0);
    barriere2.setInitialPosition(0.5);
    barriere2.goTo(positionOuverteBarriere2);   
  INITAFFETAT();
}

/*-------------------------------------------------------------------*/
/* Contrôle du PN */
void loop()
{
  static byte etatPN = PN_OUVERT;
  static unsigned long dateOuverture;

  /* Fait fonctionner les servos */
  SlowMotionServo::update();

  AFFICHEETAT(etatPN);
 
  switch (etatPN)
  {
    case PN_OUVERT:
      /* lecture du capteur pour détecter un train */
      if (digitalRead(capteurPin1) == trainPresent || digitalRead(capteurPin2) == trainPresent) {
        /* train présent */
        /* On ferme les barrière */
        barriere1.goTo(positionFermeeBarriere1);
        barriere2.goTo(positionFermeeBarriere2);
        /* Le PN est en train de se fermer */
        etatPN = PN_SE_FERME;
      }
      break;

    case PN_SE_FERME:
      /* Si les deux servos sont arrêtés, le PN a terminé de se fermer */
      if (barriere1.isStopped() && barriere2.isStopped()) {
        etatPN = PN_FERME;
      }
      break;

    case PN_FERME:
      /* lecture du capteur pour détecter le départ du train */
      if (digitalRead(capteurPin1) == trainAbsent && digitalRead(capteurPin2) == trainAbsent) {
        dateOuverture = millis() + temporisationOuverture;
        etatPN = PN_TEMPO;
      }
      break;

    case PN_TEMPO:
      /* Un train est présent, on retourne à l'état PN_FERME */
      if (digitalRead(capteurPin1) == trainPresent || digitalRead(capteurPin2) == trainPresent){
        etatPN = PN_FERME;
      }
      else {
        /* Si la date est arrivée, on ouvre */
        if (millis() >= dateOuverture) {
          /* On ouvre les barrière */
          barriere1.goTo(positionOuverteBarriere1);
          barriere2.goTo(positionOuverteBarriere2);
          etatPN = PN_S_OUVRE;
        }
      }
      break;

    case PN_S_OUVRE:
      /* Un train est présent, on retourne à l'état PN_SE_FERME et on ferme la barrière */
      if (digitalRead(capteurPin1) == trainPresent || digitalRead(capteurPin2) == trainPresent) {
        barriere1.goTo(positionFermeeBarriere1);
        barriere2.goTo(positionFermeeBarriere2);
        etatPN = PN_SE_FERME;
      }
      else {
        /* Si les deux servos sont arrêtés, le PN a terminé de s'ouvrir */
        if (barriere1.isStopped() && barriere2.isStopped()) {
          etatPN = PN_OUVERT;
        }
      }
      break;

    default:
      /* normalement impossible */
      break;
  }
}

Merci pour vos réponses

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #1 le: mars 18, 2019, 08:45:06 am »
Je ne vois à priori pas de problème.

Il faut prendre les choses dans l'ordre et ajouter des Serial.print() pour comprendre, tester que les capteurs renvoient bien ce qu'il faut, que l'on passe bien par les endroit attendus.
Cordialement

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #2 le: mars 18, 2019, 09:48:36 am »
Bonjour,
Merci pour cette réponse.
Seulement je suis novice. De plus je ne comprends pas l'anglais.
J'ai effectué une recherche sur le site d'Arduino pour comprendre Sérial.print() et j'ai tenté une traduction mais je n'ai pas compris où placer cette commande dans le programme.
Cordialement.

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #3 le: mars 18, 2019, 09:59:01 am »
Dans un premier temps, avez vous vérifié que vos ILS fonctionnent comme il faut ?
Cordialement

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #4 le: mars 18, 2019, 10:45:28 am »
Oui, je l'ai vérifié, ils fonctionnent correctement.
Merci pour votre aide.

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #5 le: mars 18, 2019, 11:07:24 am »
le premier truc à verifier est le changement d'état de PN_OUVERT à PN_SE_FERME s'effectue (ajout d'un print) :

    case PN_OUVERT:
      /* lecture du capteur pour détecter un train */
      if (digitalRead(capteurPin1) == trainPresent || digitalRead(capteurPin2) == trainPresent) {
        /* train présent */
        Serial.println("detection !"); /* Mettre un Serial.begin(9600); */
        /* On ferme les barrière */
        barriere1.goTo(positionFermeeBarriere1);
        barriere2.goTo(positionFermeeBarriere2);
        /* Le PN est en train de se fermer */
        etatPN = PN_SE_FERME;
      }
      break;
Cordialement

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #6 le: mars 18, 2019, 11:26:19 am »
Merci encore !
Je dois m'absenter mais j'essaierai ce soir et je vous tiens au courant.
Cordialement

savignyexpress

  • Invité
Re : Problème tempo passage à niveau
« Réponse #7 le: mars 18, 2019, 12:49:38 pm »
Bonjour,

Peut-être devrais-tu tracer le graphe de la machine d'états ce qui permettrait de mieux suivre ?

J'ai une question au sujet des 2 états suivants:

    case PN_OUVERT:
      /* lecture du capteur pour détecter un train */
      if (digitalRead(capteurPin1) == trainPresent || digitalRead(capteurPin2) == trainPresent) {
        /* train présent */
        /* On ferme les barrière */
        barriere1.goTo(positionFermeeBarriere1);
        barriere2.goTo(positionFermeeBarriere2);
        /* Le PN est en train de se fermer */
        etatPN = PN_SE_FERME;
      }
      break;

    case PN_SE_FERME:
      /* Si les deux servos sont arrêtés, le PN a terminé de se fermer */
      if (barriere1.isStopped() && barriere2.isStopped()) {
        etatPN = PN_FERME;
      }
      break;

Dans l'état PN_SE_FERME, on teste si les servos sont arrêtés et on en déduit que la fermeture est terminée. Cela suppose que suite aux 2 appels goTo de l'état PN_OUVERT, le mouvement des barrières a effectivement commencé. J'imagine que l'appel à SlowMotionServo::update();, avant le switch sur les états assure cela. Sinon, on passe directement à l'état PN_FERME où on teste à nouveau les ILS. Ce test surviendrait beaucoup trop tôt par rapport au précédent et on aurait un problème de rebond.

Comme déjà évoqué par Jean-Luc, il peut être bien d'afficher sur la ligne série, par exemple l'entrée dans l'état PN_SE_FERME, à généraliser pour tous les changements d'état:

#define DEBUG
...

void setup (void)
{
    ...
    #ifdef DEBUG
    Serial.begin (9600);
    #endif
    ...
}


void loop (void)
{
    ...
    case PN_OUVERT:
        ...
        etatPN = PN_SE_FERME;

        #ifdef DEBUG
        Serial.print (millis (), DEC);
        Serial.println (" -- PN_SE_FERME");
       #endif
       ...
    break;
    ...
}

Dans l'IDE Arduino, la combinaison de touches Ctrl-Shift-M ouvre le terminal de la ligne série. Avec le format de trace proposé, tu peux voir à quel moment la transition est effectuée.

Bonne suite.

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1691
    • Voir le profil
Re : Re : Problème tempo passage à niveau
« Réponse #8 le: mars 18, 2019, 12:54:19 pm »
Bonjour Marc-Henri

Peut-être devrais-tu tracer le graphe de la machine d'états ce qui permettrait de mieux suivre ?

Ce sketch est celui de mon article : http://www.locoduino.org/spip.php?article25
Cordialement

savignyexpress

  • Invité
Re : Re : Re : Problème tempo passage à niveau
« Réponse #9 le: mars 18, 2019, 01:06:13 pm »
...
Ce sketch est celui de mon article : http://www.locoduino.org/spip.php?article25

Merci Jean-Luc pour cette précision.

Je n'avais pas pensé au copier-coller, en soit tout à fait légitime, mais passé allègrement sous silence par Jojo 77. La moindre des choses aurait été de mentionner qu'il avait repris ce sketch de Locoduino.

Du coup ma question sur les 2 états dans mon message précédent tombe partiellement. Le fonctionnement de SlowMotionServo::update(); ne doit donc pas poser de problème. En revanche, je me demande si on ne devrait pas tout de même tenir compte d'éventuels rebonds sur les ILS.

Bon début de semaine.
« Modifié: mars 18, 2019, 02:30:08 pm par Marc-Henri »

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #10 le: mars 18, 2019, 06:58:11 pm »
Bonsoir,
J'ai en effet omis d'indiquer que j'avais repris le sketch de Jean-Luc qui m'a bien conseillé et je vous prie de m'en excuser.
Avant d'ouvrir cette nouvelle discussion, j'avais répondu au bas de la rubrique "Comment concevoir rationnellement votre système" pour expliquer mon problème.
Je ne l'ai peut-être pas fait au bon endroit.
En tout cas, merci à vous deux de votre patience car je ne suis pas très doué.
Je vais donc essayer vos conseils ce soir. Je vous tiendrais au courant des résultats demain.
Bonne soirée !
Cordialement

savignyexpress

  • Invité
Re : Problème tempo passage à niveau
« Réponse #11 le: mars 19, 2019, 08:26:16 am »
Bonjour,

Je n'ai pas eu le réflexe d'aller consulter le site éditorial et n'ai donc pas vu ta 1ère question.  :)

Tiens-nous au courant des résultats de tes investigations.

Bonne suite et meilleures salutations.

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #12 le: mars 19, 2019, 09:38:41 am »
Bonjour,
Nouveaux essais après modifications du sketch. Ajout d'un Serial.println.
La locomotive passe sur le capteur, la barrière se ferme une fois que le train à dépassé le pn.
Je vois donc deux réponses : soit agir sur la rapidité de fermeture de la barrière, soit, ce qui est pour moi le plus probable, j'aurais placé mes capteurs trop près du pn.
Qu'en pensez-vous ?

Cordialement

savignyexpress

  • Invité
Re : Re : Problème tempo passage à niveau
« Réponse #13 le: mars 19, 2019, 11:26:19 am »
... soit, ce qui est pour moi le plus probable, j'aurais placé mes capteurs trop près du pn...

Sur mon réseau en N, la détection de part et d'autre du PN se situe à ~80 cm. À l'échelle H0, cela correspondrait à ~147 cm. Cette longueur permet:
  • de faire clignoter les signaux avant de commencer à fermer les barrières;
  • de commencer à fermer les barrières avant que le train n'arrive au PN;
  • la durée de fermeture / ouverture des barrières est de 2.7 secondes. C'est calculé comme suit:
    • Position min servo: 1000 (impulsion de 1 ms, valeur pour le timer 16 bits)
    • Position max servo: 1900 (impulsion de 1.9 ms, valeur pour le timer 16 bits)
    • Différence: 900
    • Incrément / décrément servo: 20
    • Intervalle de temps entre chaque mise à jour servo: 60 ms
    • Durée fermeture / ouverture: 900 / 20 * 60 ms = 2.7 sec

Même avec cette distance et cette durée, on s'approche de la réalité, mais c'est encore trop court.

Cf le sujet sur mon PN sur le forum du N:
Bonne réalisation et meilleures salutations.
« Modifié: mars 19, 2019, 11:31:42 am par Marc-Henri »

jojo 77

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : Problème tempo passage à niveau
« Réponse #14 le: mars 19, 2019, 01:05:52 pm »
En effet, selon votre message, mes capteurs sont placés beaucoup trop près du pn.
Je vais donc les déplacer.
Je pense faire cela ce week-end à moins que je trouve le temps avant.
De toutes façons je vous tiens au courant.

Cordialement