Une débutante dans le décor - Ep4 - Kitbashing d’une fosse d'inspection

Bonjour Julie,

C’est super, et bien expliqué en plus. Ton câble rouge sur le rail Trix, tu le soudes sur une des parties du 24360 ?

Bonne continuation

A+

Manu

Bonjour Manu,

Merci. J’aime bien écrire mais surtout je me suis aperçue que d’écrire (de décrire) ce que je fais, j’ai des idées pour faire mieux ou différemment.

Plus simplement, je lui met une cosse et je l’enfile à l’endroit prévu d’un côté ou de l’autre de la connectique du 24361. Je mettrais une photo à ce sujet dans la suite du tutoriel.

Bon dimanche !

Episode 4.4 - Alimentation pour la traction

Reprenons notre réalisation de là où nous l’avions laissé hier.

Nous allons réaliser les piliers pour soutenir les deux traverses qui porte les rails et le rail central.

Il faut 7 piliers dans cette nouvelle version de 15 mm de haut. Ce sont toujours des poutres Evergreen en H de 4,8 mm, découpé au massicot.

J’ai changé de méthode en utilisant un gabarit : je pose la poutre et les piliers que j’ajuste délicatement à leur position puis je laisse couler une petite goutte de colle plastique - j’utilise la référence Faller 170490 - j’attends quelques secondes, je contrôle la perpendularité et puis c’est tout !

La poutre fait 240 mm et la position des piliers est indiquée sur mon gabarit en mm (15, 45, 75 …) à partir de la marche du bas (lol). Il faut donc ajouter 15 mm à mes chiffres depuis le bord de la poutre … (pourquoi faire simple quand on peut faire compliqué).

L’étape suivante est de repérer la position des piliers (hint : la poutre doit se trouver à 13 mm du bord) et de pointer l’emplacement du trou pour le passage de l’alimentation du rail central (le fil rouge !) :

Un petit coup de perceuse délicatement avec un foret de 2.5 mm, le montage bien calé sur mon établi de fortune :

Puis préparation pour passer en atelier peinture pour l’apprêt avec protection des zones qui ne doivent pas être peintes. J’ai choisi un apprêt gris foncé en bombe Prince August :

Après une heure de séchage, direction l’atelier de peinture gris muraille (toujours Prince August). Sur cette photo, on voit bien le avant et le après (pas encore sec) :

Après une nouvelle heure de séchage, nous pouvons passer au collage et montage.

On commence par les deux bords que l’on hésite pas à aider à rester en place pendant quelques minutes de pression :

On remarque au passage que le fil rouge a été peint en noir, pour se fondre plus facilement dans la fosse. Pas d’embrouille, il est laissé rouge en sortie du coupon :slight_smile:

Et comme je voulais être sur du bon collage sur toute la longueur de l’ouvrage, j’ai demandé l’aide de Bérénice (pour connaisseurs avertis hein !) :

Positionnement de l’ensemble avant l’installation du rail central :

Petite gymnastique pour emboiter la bordure, le coupon, le rail central avec son câble, tout cela dans le bon ordre pour que l’ensemble s’auto-bloque. Et bien sur encoller l’ensemble, à la colle plastique pour les plastiques/plastiques et à la cyano21 pour les plastiques/rails :

J’ai fait appel à nouveau à Bérenice pour m’assurer d’un collage impeccable.

Le module est prêt, il faut établir la connexion de l’élément qui se comporte comme un rail contact avec un fil bleu. Et l’alimentation du rail minitrix (le fil rouge) est assurée par le connecteur B de la connectique du coupon :

Et finalement les tests de mise en production :

Il reste à modifier l’automatisme pour plus de réalisme et quelques finitions (par exemple il y a un léger espace entre la poutre et les rails que je vais combler avec des attaches de traverses démontées de la voie C, ce n’est que de l’esthétique).
Il faut aussi une légère patine pour embellir l’ensemble.

Bon pour livraison à Obourg !

4 « J'aime »

Bonjour Julie,

Toutes mes félicitations pour cette construction “from scratch” : du grand art !

J’avoue être fort intrigué et intéressé par la solution “frotteur tête bêche” …

P.-S. : j’envie ton rythme d’enfer, moi qui avance plutôt à un train de sénateur

Amicalement,

Fred

Bonjour Fred,

En fait c’est une innovation Aas Blau avec dépôt de brevet en cours, monsieur Gaston ne serait pas content s’il devait se divulguer de pareils secrets … :zipper_mouth_face:

Si tu sais garder un secret, je vais néanmoins t’en parler, confidentiel hein !

Je prends un frotteur de locomotive qui se déplace sur une goulotte dont le fond est conducteur (plaque de cuivre par exemple). Et je fixe un frotteur à l’envers sur lequel vient s’appuyer le frotteur de la locomotive utilisant la fosse.

A l’inverse du montage sous table avec un chariot mobile, la locomotive qui passe dans un sens doit repasser dans l’autre sens pour remettre le système à l’état 0. Donc ce système n’est pas valable pour une fosse en voie d’entrée ou voie de sortie. Mais au contraire est valable pour une fosse empruntée dans les deux sens, qui emmène à une remise par exemple.

Mon test a-t-il-vraiment échoué : oui, je ne n’ai pas été capable de faire une seule longueur “propre” avec ma fidèle DHG 700 C. Dans les principaux problèmes : un soulèvement du mécanisme en fin de course ou un déplacement en crabe chaotique.

Pourquoi mon test a échoué : une somme de petits détails et donc il faut tout reprendre de zéro :

  • frotteur du bas pas assez large (j’ai pris un Piko que j’avais sous la main, trop étroit)
  • goulotte trop large permettant de débattement trop important au pied du montage
  • absence d’un mécanisme de guidage au niveau supérieur -> effet de balancier
  • en fin de course il faut une légère montée pour s’assurer que le mécanisme ne se soulève pas
  • poids de l’ensemble (j’avais bricolé une fixation semi rigide entre les deux frotteurs, trop lourd)

Faut-il remplacer le frotteur du bas par un petit chariot mobile sur un rail unique ultra fin (minitrix ou plus petit) pour diminuer les frottements ?

Je revisiterais le sujet quelque part en 2021, j’ai envie d’avancer sur d’autres sujets passionnants. Je dois terminer l’automatisme éclairage de la fosse (avec un Arduino nano) et la motorisation du pont. Ensuite j’attaque une première remise que je voudrais actionnable au niveau des portes (servo moteurs). Tout un programme …

Bonne journée :slight_smile:

Bonjour Julie,

A quoi correspondent les 3 modules électroniques illustrés plus haut ?
Sinon, je vois que Bérénice profite de la séance de séchage pour faire l’auto-promotion de ton livre … :+1:

Bonjour Bertrand,

De gauche à droite :

  • un convertisseur analogique 0-25 V --> 0-5 V pour être compatible avec une pin d’IO digital
  • un Arduino nano
  • une platine à relais compatible Arduino bien sur

Je souhaite avoir un petit automatisme assez simple :

  1. fosse normalement éteinte sauf si forçage par une entrée (par exemple une commande d’un M83 - bouton vert)
  2. une locomotive passe sans s’arrêter, la fosse reste éteinte sauf si le forçage est en cours
  3. une locomotive stationne, au bout d’un temps programmable, la fosse s’allume
  4. la fosse allumée s’éteint au bout d’un certain temps programmable, économie d’énergie oblige
  5. une locomotive repart, la fosse allumée s’éteint au bout d’un temps programmable
  6. une autre entrée pour un forçage éteint même si des locomotives stationnent (un autre commande d’un M83 - bouton rouge)

J’ai acheté pour quelques euros un circuit qui devait faire tout ça mais il a beaucoup de mal et de fait il est réduit à l’automatisme suivant :

  1. une locomotive arrive, la fosse s’allume
  2. la locomotive passe ou repart, la fosse s’éteint au bout d’un temps programmable

Il aurait fallut que je bricole, que j’ajoute un autre circuit devant, etc. Un ami m’a dit : prends un automate programmable …

Donc je me suis décidée avec un peu d’avance à acheter un Arduino nano que je vais programmer (quelques lignes de code) pour réaliser exactement la séquence dont j’ai besoin. Et il coute à peine plus cher que le circuit figé qui ne fait pas ce que je veux.

Ça sera aussi une bonne initiation sur un truc simple, et je verrais plus tard si je généralise l’utilisation des Arduino car j’ai prévu pas mal d’automatismes partout (portes des remises, lumières …).

Et puis à plus long terme, faire ma propre Redbox like me tente bien.

Ah oui, j’avais pas vu :wink:

Bonne journée,

Hello,Je suis FAN !
Hyper FAN !

Chris

1 « J'aime »

C’est remarquable … et je me rends compte à quel point je suis nul en électronique, je n’y comprends rien …
Bravo pour la réalisation.

Amitiés
Thierry

Bonjour Thierry,

Tsss. Des cartes achetées dans le commerce pour quelques euros, un branchement très facile (y aura même pas besoin de fer à souder) et une programmation basique.

A la portée de toute personne capable de connecter une voie C avec une MS2 :slight_smile: Je vais montrer tout ça dans un petit tutoriel à suivre !

Bonne journée,

1 « J'aime »

Hello manu,

J’ai reçu les Auhagen, ils sont vendus par pair. A première vue ils sont adaptables pour faire un coupon 24361 version cheap :slight_smile:

Ça tombe bien il me fallait quatre fosses :

  • une fosse d’inspection bien visible, objet du présent tutoriel,
  • une fosse pour l’atelier moteur,
  • deux fosses techniques pour la double remise technique.

Pour la fosse de l’atelier moteur, je vais recycler :recycle: le prototype du présent tutoriel et le noyer dans la chape de béton qui va accueillir le bâtiment de l’atelier moteur. Bâtiment plutôt moderne pour l’époque avec une bonne visibilité sur l’intérieur du bâtiment,

Pour la double remise, je vais utiliser les Auhagen car je ne vais pas faire des fosses trop abouties en terme de réalisation car elles seront moins visibles et se laisseront deviner au travers des fenêtres plus réduites d’un bâtiment époque I - 1918, rénové après guerre pour les besoins de l’héritière.

Donc mon cher Manu, si tu as un peu de patience, je compléterais le présent tutoriel d’une version mons scratch et plus kit bashing en utilisant ces références qui sont plutôt répandues et accessibles en terme de prix.

Dis moi juste si tu veux les équiper d’un éclairage ou pas (peut être j’en ferais un avec éclairage et l’autre sans, il me reste des leds en bande à placer).

@+

Wahou ! C’est classieux ! Du beau boulot.

1 « J'aime »

Bonsoir Thierry,

Le tutoriel est paru :slight_smile: ici :

Grand merci Julie
Je vais étudier cela très attentivement
Bonne fin de weekend
Thierry

Episode 4.5 - Automatisme et finitions

Il est temps de finir notre fosse de visite. La partie qui suit est optionnelle, elle consiste à ajouter un automatisme pour l’éclairage de la fosse. Une solution plus simple consiste juste à brancher + et - des bandeaux de leds à l’alimentation des accessoires.

14 mai 2021 : simplification du montage et amélioration du filtre pour lire l’état de la voie (cf Tuto05)

Pour cet automatisme je me suis donnée le cahier des charges suivants :

  • si la voie est STOP, la fosse est éteinte, quelque soit son état d’occupation.
  • lorsqu’une locomotive se présente sur la fosse, elle ne s’éclaire qu’après un laps de temps (8s avec mon paramétrage). Cela permet de laisser la fosse éteinte quand la locomotive ne fait que passer.
  • de manière symétrique, lorsqu’une locomotive quitte la fosse allumée, celle-ci s’éteint après un laps de temps (8s avec mon paramétrage).
  • lorsque la fosse est allumée, un mode veille se déclenche qui éteint la fosse au bout de 6 minutes.
  • deux entrées en pull up (mettre un interrupteur à GND) permettent de forcer l’allumage ou l’extinction.

Un afficheur optionnel affiche l’état de la fosse et l’éventuel décompte en cours :

  • “5 -” : la voie est STOP
  • “E xx” : la fosse est éteinte mais la séquence d’allumage est enclenchée - il reste xx secondes avant allumage
  • “A xx” : la fosse est allumée mais la séquence d’extinction est enclenchée - il reste xx secondes avant extinction
  • “Ax:xx” : la fosse est allumée mais la séquence de mise en veille est enclenchée - il reste xxx secondes avant la mise en veille
  • " : " : l’éclairage de la fosse est en veille
  • “U xx” : l’état xx n’est pas connu (ça ne devrait jamais s’afficher !)
  • “FA” : la fosse est forcée allumée
  • “FE” : la fosse est forcée éteinte

La liste du matériel comprend (on peut aussi acheter directement chez AZ Delivery mais j’ai profité de mon abonnement Prime chez Amazon pour ne pas payer de frais de port) :

  • un Arduino Uno (AZ Delivery) : Amazon.fr
  • une carte relais 1 canal 5V (AZ Delivery) : Amazon.fr
  • une carte capteur de tension 0-25 V (Stemedu) : Amazon.fr
  • un lot de connecteurs (AZ Delivery) : Amazon.fr
  • un afficheur optionnel 4 digits 7 segments TM1637 (AZ Delivery) : Amazon.fr

Soit un automatisme qui va couter unitairement moins de 14 euros.

Le schéma de connexion est une simple évolution du tutoriel Tuto07, avec deux entrées de forçage supplémentaire :

Le sketch (pour utiliser la terminologie Arduino, c’est à dire le programme) est assez conséquent mais facile à suivre (très commenté et la suite logique du tutoriel progressif de l’épisode 6).

La vraie nouveauté est l’implémentation d’une machine à état finis (Finite State Machine) pour s’assurer de l’exhaustivité des situations rencontrées par l’automatisme. C’est un objet informatique moins classique mais que toute personne pratiquant l’automatisme devrait connaitre.

On trouvera plus d’information sur les machines à états finis sur Google, et on commencera par la page Wikipedia Automate fini — Wikipédia

// Fosse v1.5
// (c) Julie Dumortier, 2020-2021
// licence GPL
//
// Evolutions
// v1.0 première version sur plateforme de démonstration
// v1.5 détection STOP sur la voie et afficheur optionnel (v20201222)
// 14 mai 2021 : lecture de l'état STOP directement sur le rail !

// mettre à 1 pour un debug dans la console série
#define debug 1

// D3 : input : forçage allumé (pullup) (par défaut, l'allumage n'est pas forcé)
// D4 : input : forçage éteint (pullup) (par défaut, l'extinction n'est pas forcée)
// D5 : output : allumage des bandeaux de leds (COMMON - NC)

int Pin_forcageAllume = 3;
int Pin_forcageEteint = 4;
int Pin_allumageLeds = 5;

// A3 : input : état d'occupation de la fosse (rail contact / fil bleu)
int Pin_etatRail = 3;

// Temps avant allumage (en secondes) : 4 (debug) ou 8
int tempsAvantAllumage = 8/(1+debug);

// Compteur de temps avant l'ellumage (en millisecondes)
unsigned long timeAllumage = 0; 

// Mise en veille (en secondes) : 8 (debug) ou 180
int tempsAvantVeille = 60*6/(1+(43*debug));

// Compteur de temps avant la Veille (en millisecondes)
unsigned long timeVeille = 0; 

// Temps avant extinction (en secondes) : 4 (debug) ou 8
int tempsAvantExtinction = 8/(1+debug);

// Compteur de temps avant l'extinction (en millisecondes)
unsigned long timeExtinction = 0; 

// Filtre bas du signal d'occupation
int msFiltre = 192;

// variable pour compter les déclenchements
int nbFiltre = 16;

// Seuil de déclenchement du signal d'occupation
int seuilSignal = 384;

// inclus une librairie toute simple pour l'afficheur
#include <Arduino.h>
#include <TM1637Display.h>

// Connexion de l'afficheur sur lAarduino : CLK sur D9 et DIO sur D8
#define CLK   9
#define DIO   8

// Crée l'objet display pour interagir avec l'afficheur
TM1637Display display(CLK, DIO);

// structure globale avec le contenu de l'afficheur
uint8_t segments[] = {0xff, 0xff, 0xff, 0xff};

// FSM (Machine à etats finis) Etats possibles des lumières de la fosse
// cf https://fr.wikipedia.org/wiki/Automate_fini
// Ce type d'approche permet d'implémenter un automatisme robuste

#define state_Eteint        0
#define state_Allume        1
#define state_ForceEteint   2
#define state_ForceAllume   3
#define state_enAllumage    4
#define state_enExtinction  5
#define state_enVeille      6

// La FSM est complétée par l'état de la voie
// Les différents états possibles pour la voie sur le rail contact
//  voie_Occupee la voie est occupée
//  voie_Libre   la voie est libre
//  voie_STOP    la voie est en STOP (CSx ou MSII)

#define voie_STOP    99
#define voie_Occupee  0
#define voie_Libre    1

// AfficheSegVal
//  affiche des segments sur le premier digit et une valeur sur les trois autres digits
//  seg : encodage du 1er digit 
//  val : valeurs à afficher sur les trois digits suivant
//  dp  : allume le double point

void AfficheSegVal(uint8_t seg,int val,boolean dp=false)
{
  uint8_t b1;
  uint8_t b2;
  
  // prépare la structure des segments
  segments[0] = seg;

  if (val>0) {
    b1 = (val / 100) % 10;
    segments[1] = b1?display.encodeDigit(b1):0x00 | (dp?0x80:0x00);
    segments[2] = (b1||b2) ? display.encodeDigit((val / 10) % 10) : 0x00;
    segments[3] = display.encodeDigit(val % 10);
  } else {
    segments[1] = (dp?0x80:0x00);
    segments[2] = 0x00;
    segments[3] = SEG_G;
  }
  // appel la librairie pour envoyer les segments sur l'afficheur
  display.setSegments(segments); 
}

// AfficheEtatVal
//  affiche l'état de la voie et une valeur (tension sur la voie) en dV
//  etat : etat de la voie
//  val  : valeur de la tension (0 - 1023)

void AfficheEtatVal(int etat,int val)
{
  uint8_t seg;  // segments du 1er digit
  float   temp; // variable temporaire pour la conversion
 
  // conversion de val en dixième de Volts (dV)
  // capteur de tension est sur une plage 0-25V
  temp = (250.0*val)/1024.0; 
  val = (int)temp;
  
  // construire le 1er segment selon l'état de la voie
  switch (etat) {
    case voie_Libre:
      // (L)ibre
      seg = SEG_F | SEG_E | SEG_D;
      if (debug) { Serial.print("voie_Libre val="); Serial.println(val);}
      break;

    case voie_Occupee:
      // (O)ccupée
      seg = SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F;
      if (debug) { Serial.print("voie_Occupee val="); Serial.println(val);}
      break;

    case voie_STOP:
      // (S)top + val
      seg = SEG_A | SEG_C | SEG_D | SEG_F | SEG_G;
      if (debug) { Serial.print("voie_STOP val="); Serial.println(val);}
      break;

    default:
      // (U)nknown + etat
      seg = SEG_B | SEG_C |SEG_D | SEG_E |SEG_F ;
      val = etat;
      if (debug) { Serial.print("voie_"); Serial.print(val); Serial.print("? val="); Serial.println(val);}
      break; 
  }

  // affiche le contenu
  AfficheSegVal(seg,val); 
}

// EtatVoie
// retourne l'état de la voie (voie_Occupee,voie_Libre, voie_STOP)
//
// L'algorithme est assez trivial
// Lecture des entrées analogiques vr Rail contact et vt Rail traction
// Si on trouve au moins un vr supérieur à un seuil, le rail contact est occupé
// Si on ne trouve aucun vt supérieur à un seuil, le rail traction est STOP
// Sinon le rail contact est libre
//
// NB : quand le rail traction est STOP, il n'est pas possible de savoir si le
// rail contact est libre ou occupé. 

int EtatVoie()
{
  int n = msFiltre; // nombre de fois que l'on va s'assurer que le rail contact est libre
  int c = 0;
  
  int vr = 0; // valeur analogique sur le Rail Contact
  int vt = 0; // valeur analogique sur le Rail traction

  // flag pour savoir si on a recu un signal de traction
  int traction = 0;
  
  // tant que le signal est bas on continue
  while (n>0) {
    // lit les deux entrées : rail contact et rail normal
    vr = analogRead(Pin_etatRail);
    vt = vr; // analogRead(Pin_etatTraction);

    // la voie de traction est-elle alimentée ?
    if (vt>1) {
      traction = vt;
    }

    // le rail de contact est-il libre ?
    if (vr>seuilSignal) {
      c = c + 1;
    }
    if (c>nbFiltre) {
      // la voie est encore occupée

      // attends la fin du compteur pour une fonction à temps défini (environ filtreBas ms)
      delay(n);

      // met à jour l'afficheur
      if (debug) AfficheEtatVal(voie_Occupee,vr);
      
      // et retourne l'état d'occupation
      return voie_Occupee;
    }

    // attends 1 ms
    delay(1);

    // et boucle
    n = n - 1;
  }

  // on a eu un signal de traction
  if (traction>0) {
    // le rail contact est resté bas --> la voie est libre

    // met à jour l'afficheur
    if (debug) AfficheEtatVal(voie_Libre,traction);
    
    return voie_Libre;
  }

  // pas de traction

  // met à jour l'afficheur
  if (debug) AfficheEtatVal(voie_STOP,0);
  
  return voie_STOP;
} 

// Etat courant de la machine à état finis (FSM)
// A l'initialisation de l'Arduino, tout est censé être éteint
int state = state_Eteint;

// FSM Séauences (cahier des charges) :
// 1. fosse normalement éteinte sauf si forçage par D3 (M83 - bouton vert - au commun==GND)
// 2. une locomotive passe sans s’arrêter, la fosse reste éteinte sauf si le forçage est en cours
// 3. une locomotive stationne, au bout d’un temps programmable, la fosse s’allume
// 4. la fosse allumée s’éteint au bout d’un certain temps programmable, économie d’énergie oblige
// 5. une locomotive repart, la fosse allumée s’éteint au bout d’un temps programmable
// 6. D4 pour un forçage éteint même si des locomotives stationnent (M83 - bouton rouge - au commun==GND)

// allumeLeds
void allumeLeds()
{
  // relais COMMON - NC (led verte allumée)
  digitalWrite(Pin_allumageLeds,LOW);
}

// eteintLeds
void eteintLeds()
{
  // relais COMMON - NO (led verte eteinte)
  digitalWrite(Pin_allumageLeds,HIGH);
}

// Eteint la fosse
void EteintFosse()
{  
  switch (state) {
    case state_enAllumage:
      // la fosse était en phase d'allumage quand l'ordre d'éteindre arrive
      // on stoppe le timer d'allumage et on passe en statut Eteint
      timeAllumage = 0;
      state = state_Eteint;

      // par acquis de conscience, on éteint les leds (censées être eteintes)
      eteintLeds();

      if (debug) Serial.println("EteintFosse() state:enAllumage -> Eteint");
      break;
      
    case state_ForceEteint:
      // éteint immédiatement les leds si ce n'est pas déjà fait
      eteintLeds();

      if (debug) Serial.println("EteintFosse() state:ForceEteint");
      break;

    case state_enVeille:
      // la fosse passe en veille
      // on stoppe le timer de veille et on passe en statut Eteint
      state = state_Eteint;
      timeVeille = 0;
      
      // éteint immédiatement les leds si ce n'est pas déjà fait
      eteintLeds();

      if (debug) Serial.println("EteintFosse() state:enVeille -> Eteint");
      break;
    
    case state_Eteint:
      // la fosse est déjà Eteint, ça ne change pas grand chose
      
      // par acquis de conscience, on éteint les leds (censées être eteintes)
      eteintLeds();

      if (debug) Serial.println("EteintFosse() state:Eteint");
      break;

    case state_Allume:
      // La fosse est allumée, il faut démarrer la séquence d'extinction
      // et amorcer le timer d'extinction
      state = state_enExtinction;
      timeExtinction = millis()+tempsAvantExtinction*1000L;
      
      if (debug) Serial.println("EteintFosse() state:Allume -> enExtinction");
      break;

    case state_ForceAllume:
      // l'ordre d'éteindre doit être ignoré et
      // allume immédiatement les leds si ce n'est pas déjà fait
      allumeLeds();

      if (debug) Serial.println("EteintFosse() state:ForceAllume");
      break;

    case state_enExtinction:
      // l'ordre d'extinction est donné alors que la fosse se prépare à s'éteindre
      
      // il faut vérifier si le timer est échu -> phase d'extinction terminée ?
      if (timeExtinction < millis()) {
        // effectivement, le temps est écoulé, on remet le timer à 0 et on éteint tout
        timeExtinction = 0;
        state = state_Eteint;
        
        eteintLeds();
        
        if (debug) Serial.println("EteintFosse() state:enExtinction -> Eteint");
      } else {
        // le temps n'est pas écoulé, on attend avant d'éteindre
        
        if (debug) {
          Serial.print("EteintFosse() state:enExtinction millis=");
          Serial.print(millis());
          Serial.print(" timeExtinction=");
          Serial.println(timeExtinction);
        }
        
       }
      break;
      
    default:
      if (debug) { 
          Serial.print("EteintFosse() state:unknown state ");
          Serial.println(state);
      }
      // ne fait rien
      break;  
  }
}

// Allume la fosse
void AllumeFosse()
{  
  switch (state) {
    case state_enAllumage:
      // l'ordre d'allumage est donné alors que la fosse se prépare à s'allumer

      // il faut vérifier si le timer est échu -> phase d'eallumage terminée ?
      if (timeAllumage < millis()) {
        // effectivement, le temps est écoulé, on remet le timer à 0 et on allume tout
        timeAllumage = 0;
        state = state_Allume;
        allumeLeds();

        // et on amorce le timer pour le mode veille !
        timeVeille = millis() + tempsAvantVeille*1000L;
        
        if (debug) Serial.println("AllumeFosse() state:enAllumage -> Allume");
      } else {
        // le temps n'est pas écoulé, on attend avant d'allumer
        if (debug) {
          Serial.print("AllumeFosse() state:enAllumage millis=");
          Serial.print(millis());
          Serial.print(" timeAllumage=");
          Serial.println(timeAllumage);
        }
      }
      break;
      
    case state_ForceEteint:
      // éteint immédiatement les leds si ce n'est pas déjà fait
      eteintLeds();

      if (debug) Serial.println("AllumeFosse() state:ForceEteint");
      break;
      
    case state_Eteint:
       // les leds sont éteintes, il faut démarrer la séquence d'allumage
       // avec le timer d'allumage
      state = state_enAllumage;
      timeAllumage = millis()+tempsAvantAllumage*1000L;
      
      if (debug) Serial.println("AllumeFosse() state:Eteint -> enAllumage");
      break;

    case state_Allume:
      // en état allumé, nous devons vérifier l'échéance du timer de veille

      // le timer de veille est-il échu ?
      if (timeVeille<millis()) {
        // oui -> la veille doit se déclencher
        timeVeille = 0;
        state = state_enVeille;

        // on peut éteindre les leds
        eteintLeds();
        
        if (debug) Serial.println("AllumeFosse() state:Allume -> EnVeille");
      } else {
        // le timer veille n'est pas encore échu
        
        // par acquis de conscience, on allume les leds (censées être allumées)
        allumeLeds();
        
        if (debug) {
          Serial.print("AllumeFosse() state:Allume millis=");
          Serial.print(millis());
          Serial.print(" timeVeille=");
          Serial.println(timeVeille);
        }
      }
      break;

    case state_ForceAllume:
      // allume immédiatement les leds si ce n'est pas déjà fait
      allumeLeds();

      if (debug) Serial.println("AllumeFosse() state:forceAllume");
      break;

    case state_enExtinction:
      // l'ordre d'allumage est reçu alors que nous étions en phase d'extinction
      // annule la phase d'extinction
      timeExtinction = 0;
      state = state_Allume;
      
      // par acquis de conscience, on allume les leds (censées être allumées)
      allumeLeds();

      if (debug) Serial.println("AllumeFosse() state:enExtinction -> Allume");
      break;

    case state_enVeille:
      // éteint immédiatement les leds si ce n'est pas déjà fait
      eteintLeds();

      if (debug) Serial.println("AllumeFosse() state:enVeille");
      break;
      
    default:
      if (debug) { 
          Serial.print("AllumeFosse() state:unknown state ");
          Serial.println(state);
      }
      // ne fait rien
      break;  
  }
}

// AfficheEtatVal
//  affiche l'état de la FSM et un décompte représentatif
//  le mode veille affiche le double point
//

void AfficheEtatFSM(int ev) 
{
  // vérifie si la voie est sous-tension
  if (ev==voie_STOP) {
    // (5)top
    AfficheSegVal(SEG_A | SEG_C | SEG_D | SEG_F | SEG_G,0);
    return;
  }

  // sinon, affiche l'état de la FSM et de l'éventuel décompte en cours
  switch (state) {
      case state_Eteint:
        // (E)teint
        AfficheSegVal(SEG_A | SEG_G | SEG_D | SEG_E | SEG_F,0);
        break;

      case state_Allume:
        // (A)llume + décompte veille
        AfficheSegVal(SEG_A | SEG_F | SEG_B | SEG_E | SEG_C | SEG_G,(timeVeille-millis())/1000,true);
        break;

      case state_ForceEteint:
        // FE
        segments[0] = SEG_A | SEG_F | SEG_G | SEG_E ; 
        segments[1] = SEG_A | SEG_G | SEG_D | SEG_E | SEG_F ;
        segments[2] = 0x00;
        segments[3] = 0x00;
        display.setSegments(segments);
        break;

      case state_ForceAllume:
        // FA
        segments[0] = SEG_A | SEG_F | SEG_G | SEG_E ; 
        segments[1] = SEG_A | SEG_B | SEG_C | SEG_G | SEG_E | SEG_F;
        segments[2] = 0x00;
        segments[3] = 0x00;
        display.setSegments(segments);
        break;
        
      case state_enAllumage:
        // (E)teint + décompte d'allumage
        AfficheSegVal(SEG_A | SEG_G | SEG_D | SEG_E |SEG_F,(timeAllumage-millis())/1000);
        break;
        
      case state_enExtinction:
        // (A)llumé + décompte d'extinction
        AfficheSegVal(SEG_A | SEG_F | SEG_B | SEG_E | SEG_C | SEG_G,(timeExtinction-millis())/1000);
        break;
        
      case state_enVeille:
        // :
        AfficheSegVal(0,0,true);
        break;

    default:
      // (U)nknown + state
      AfficheSegVal(SEG_B | SEG_C |SEG_D | SEG_E |SEG_F,state);
      break;
  }
}

// code executé une seule fois au démarrage du module (ou après un reset)
void setup() {
  // programme les différentes Pin en entrée ou sortie
  pinMode(Pin_forcageAllume,INPUT_PULLUP);
  pinMode(Pin_forcageEteint,INPUT_PULLUP);
  
  pinMode(Pin_allumageLeds,OUTPUT);
  eteintLeds();

  // au démarrage il est probable que la voie soit STOP
  pinMode(LED_BUILTIN,OUTPUT);
  digitalWrite(LED_BUILTIN,HIGH);    
  
  // ouvre le port série (console de l'outil) avec la vitesse 57600 bauds
  // attention que le paramètre sur la console soit bien 57600 !
  if (debug) Serial.begin(57600);

  // Annonce la version
  Serial.println("Fosse v1.5 - (c) Julie Dumortier - Licence GPL");

  // On démarre avec la fosse éteinte et la voie STOP
  state = state_Eteint;
  timeExtinction = 0;
  timeVeille = 0;
  timeAllumage = 0;

  // regle l'intensité de l'affichage
  display.setBrightness(debug?0x0f:0x0d);
  display.clear();

  EteintFosse();
}

// code executé en permanence (une boucle)
void loop() {
  
  int ev; // état de la voie

  // demande de forçage eteint ?
  if (digitalRead(Pin_forcageEteint)==LOW) {
    // demande d'etre eteint en permanence
    state = state_ForceEteint;
    
    if (debug) Serial.println("loop() IN: state:ForceEteint");
  } else {
    if (state==state_ForceEteint) {
      // fin du forçage eteint
      state = state_Eteint;
      
      if (debug) Serial.println("loop() state:ForceEteint -> Eteint");
    }
  }

  // demande de forçage allumé ?
  if (state!= state_ForceEteint) {
    if (digitalRead(Pin_forcageAllume)==LOW) {
      // demande d'etre allumé en permanence
      state = state_ForceAllume;
      
      if (debug) Serial.println("loop() IN: state:ForceAllume");
    } else {
      if (state==state_ForceAllume) {
        // fin du forçage allumé, amorce le timer de veille
        state = state_Allume;
        timeVeille = millis() + tempsAvantVeille*1000L;
        
        if (debug) Serial.println("loop() state:ForceAllume -> Allume");
      }
    }
  }

  ev = EtatVoie();
  switch (ev) {
    case voie_Occupee:
      // indique que la voie est sous-tension
      digitalWrite(LED_BUILTIN,LOW);    

      // déclenche la FSM d'allumage de la Fosse
      AllumeFosse();
      break;

    case voie_STOP:
      // Modifie l'état de la FSM pour demander une extinction immédiate
      state = state_Eteint;
      timeExtinction = 0;
      
      // déclenche la FSM d'extinction de la Fosse
      EteintFosse();

      // indique que la voie est STOP
      digitalWrite(LED_BUILTIN,HIGH);    
      break;
 
    case voie_Libre:
      // indique que la voie est sous-tension
      digitalWrite(LED_BUILTIN,LOW);    
      
      // déclenche la FSM d'extinction de la Fosse
      EteintFosse();
      break;
      
    default:
      if (debug) {
        Serial.print("loop() EtatVoie : unknown state =");
        Serial.println(ev);
      }
      break;
  }

  // pour avoir le temps de lire l'état de la voie
  if (debug) delay(500); 

  // affiche l'état de la FSM
  AfficheEtatFSM(ev);

  // pour avoir le temps de lire l'état de la FSM
  if (debug) delay(250); 

  // délai normal : la FSM est déclenchée 4 fois par seconde environ
  delay(250-msFiltre);

}

Pour télécharger le programme : fosse_v1.5.pdf (43,0 Ko)

Et comme d’habitude, une petite vidéo de démonstration de l’ensemble :

Ce chapitre clos la réalisation de notre fosse d’inspection. Mais le sujet n’est pas totalement clos, je travaille à une intégration propre des fosses Auhagen que je vais utiliser dans ma double remise.

Moins visible dans la remise, elles ne seront pas automatisées, seulement éclairées et fonctionnelles avec un “discret” rail minitrix en rail central.

A suivre donc …

2 « J'aime »

Chapeau bas !!!

Belle réalisation que cette fosse de maintenance.
A garder en mémoire pour un éventuel “copiage”.

Cdlt,

Claude papaciela

1 « J'aime »

Episode 4.6 - Version du coupon 24361 avec une fosse Auhagen

Je crois qu’il est temps de terminer ce tutoriel sur les fosses en voie C, enfin pour l’instant. C’est pas moins de 4 fosses différentes que j’aurais réalisé :

  • une fosse d’inspection from scratch avec un bel automatisme Arduino, objet de l’épisode 4.5 précédent,
  • le prototype initial kitbashing d’une fosse Régions & Compagnies, que j’ai amélioré pour la fosse de l’atelier moteur (vidéo à la fin de ce billet),
  • deux fosses d’entretien pour la double remise, sur la base d’un kit Auhagen référence 41612. Elles sont moins visibles dans cette remise, elles doivent surtout être fonctionnelles.

Je dois vous l’avouer, j’en ai marre des fosses ! :upside_down_face: mais j’y reviendrais plus tard, je n’ai pas abdiqué pour une solution différente pour ma fosse d’inspection, une solution sans rail central.

Pour les deux fosses d’entretien, j’ai relevé le défi de @Mulsanne : transformer en 3rails les deux fosses en moins de deux heures chrono en main :smiley:

C’est parti pour un coupon 24361 sur base Auhagen 41612 …

Je prends un coupon 24360 et mes fosses et j’en déduis précisément la longueur de plastique que je vais garder et je découpe avec la technique que j’ai déjà plusieurs fois présentée scie à métaux et on y va mollo sur la fin pour ne pas attaquer les deux rails :

Je positionne l’ensemble pour vérifier :

Attention quand vous insérez les rails dans les fixations Auhagen, elles sont très fragiles. Assurez vous que vos rails sont bien lisses.

Je ne garde qu’une extrémité en voie C puisque ce sont des coupons qui se terminent dans le fond de la remise. Mais si on veut faire une fosse d’inspection, il suffit de garder les deux extrémités et d’enlever précisément 180 mm de plastique correspondant à la longueur de la fosse Auhagen.

Maintenant on va s’occuper du rail central. Comme pour mes fosses, j’ai utilisé un rail minitrix que je démonte délicatement (le rail a tendance à se tordre facilement). Et surtout je vais garder des bouts de traverses sur lesquelles je vais découper à la pince Xuron les petites fixations que je vais utiliser ensuite :

Puis je pointe et je perce un trou pour le passage de l’alimentation qui sera positionnée au niveau d’un des deux piliers :

Je fixe mon cable rouge avec l’éclisse que j’ai récupéré et je mets un petit point de soudure :

Et je vais placer deux petits piliers pour soutenir le rail central. J’utilise des H Evergreen coupé à 8 mm de hauteur (pour une fosse qui fait 10 mm de profondeur) :

Et je teste l’ensemble avec les petites fixations et je colle à la Cyano !

Puis je pose un masque sur le rail central avant de passer en atelier peinture pour l’apprêt (une astuce qui m’a été indiquée par @Schwabisch me semble-t-il) :

En sortie de l’atelier peinture, les deux fosses Auhagen et la fosse de l’atelier moteur. On se rend bien compte de la différence … (mais ce n’est pas le même boulot !).

On retire le masque de protection du rail central :

On branche le fil rouge sur le B et hop on passe aux tests direct !

La vidéo de démonstration, les deux coupons 24361 Auhagen montés cul à cul :

On pourra y rajouter de la lumière (j’ai la flemme) en perçant des trous sur les côtés pour installer des leds. Je le ferais certainement au moment de leur intégration dans le plancher de la double remise, à suivre dans un prochain épisode.

Reste aussi à peindre et à patiner … on verra ça lors de leur intégration dans un plancher béton.

Pour clôturer cet épisode 4, je vous donne des nouvelles du prototype initial (cf épisode 4.2). J’ai légèrement amélioré la fixation du rail central, j’ai positionné l’éclisse à une extrémité et non pas contre un pilier :

Après un premier passage en peinture pour l’apprêt (la peinture définitive sera faite lors de son intégration dans le plancher de l’atelier moteur), la fidèle DHG 700 C valide complètement ce concept.

Finalement une version intéressante car bien éclairée, visuellement plutôt sympa avec une belle profondeur, très fonctionnelle mais sans aucun automatisme à ce stade. Il sera facile de greffer un nouvel Arduino ou de voir si le premier Arduino est capable de gérer les deux fosses (défi 2021 !).

La vidéo (j’ai volontairement pas monté le second bandeau de led ni branché l’éclairage … grosse flemme encore, ça sent la fin d’année :rofl:) :

THE END

2 « J'aime »

Bonjour Claude,

Avec plaisir, et n’hésites pas à me contacter sur le sujet au besoin.

Bonnes fêtes.

Et bien, tu modélise plus vite que ton ombre :astonished:

Bravo pour ces “fosses express” :smiley:

Heureux d’avoir donné un petit conseil qui se révèle pratique !

Joyeux Noël à toi. Je sens que le sapin :christmas_tree: va être garni de beaux cadeaux à faire rouler :wink:

Oh oh oh :santa:t2:

1 « J'aime »