Principe du cantonnement avec Arduino


dans les fondamentaux du ferroviaire, il est un élément très important qui permet de réaliser la fonction d'espacement des trains. Les risques sur la sécurité sont issus principalement des collisions par rattrapage, prise en écharpe et nez à nez.
Une technique simple et efficace est de réaliser un cantonnement pour éviter ces risques.
Afin de bien comprendre cette technique, nous vous proposons de réaliser un petit montage, avec un Arduino et des composants simples.

Figure 1: le cantonnement avec 3 signaux

Principe

Pour bien comprendre avec un montage simple, nous allons partir sur une base de 3 cantons avec 3 signaux de bloc (3 feux).
Le canton est une section d'une longueur déterminée qui est occupée par un train.
Pour déterminer si un train occupe ou non un canton, il faut d'abord réaliser une détection du train.
A partir de cette détection, il faut simplement appliquer une logique pour commander les feux.

La logique de commande est décrite ci-après:





Images réalisées par E. Cadieu

Le canton est aussi nommé block section en anglais.

La détection

Cette fonction peut être réalisée par des moyens différents:
 - optique (barrière infra-rouge)
 - ultra-sons (voir article précédant)
 - détection de courant
 - magnétique

Nous avons choisi la détection magnétique qui est assez fiable et simple à mettre en œuvre.
Pour cela nous avons trouvé un petit capteur ACS715 pour Arduino. C'est un capteur de courant à effet Hall. En résumé, il permet de détecter soit un courant, soit un champ magnétique et de le convertir en une tension qui est linéaire.

 Figure 2: Le capteur ACS715

Pour une utilisation en détecteur magnétique, il suffit d'utiliser les 3 broches VCC, OUT, GND.
Les broches VCC (+5V) et GND (Masse) sont pour l'alimentation du capteur. 
La broche OUT est la tension de sortie qui est à relier à une entrée analogique du Arduino.

Il est nécessaire de déterminer le seuil de détection des capteurs. Pour cela le plus simple est de les brancher est d'utiliser un petit programme qui affiche dans la console série les valeurs lues.
Théoriquement la valeur maximale est de 1024 et la minimale de 0.
En utilisant un aimant, que l'on positionne au dessus du capteur, on observe que la valeur décroit.
La valeur de 480 correspond à (1024 (échelle maxi) /2) - 5%.

Le Câblage

Pour les feux, vous pouvez connecter les fils de couleurs (rouge, jaune, vert) aux sorties et la masse comme indiqué dans les précédents articles.
Les détecteurs sont tous munis d'une nappe 3 fils qui est reliée à une platine de connexion pour faciliter les tests. Cette platine n'est pas indispensable et une fois les tests réalisés, il est souhaitable de faire un câblage définitif avec des borniers.

Le VCC des 3 capteurs (en rouge) est relié au +5V du Arduino.
La masse des 3 capteurs (en noir) est relié au GND du Arduino.
Les sorties OUT des 3 capteurs (en gris) sont reliées aux entrées analogiques 3, 4, 5 du Arduino.

Figure 3: câblage

Le programme

Le programme est réalisé sur la même éditeur que lors des précédents montages. Vous pouvez faire un copier-coller de celui-ci:

/*
 * Programme pour arduino uno
 * par A. ZANDER Avril 2018
 *
 * Ce programme fait fonctionner des feux tricolores avec une détection à capteur magnétique
 * Signal 1 : 3 LED (vertes, oranges et rouge) sont reliées aux sorties D49, D51, D53
 * Signal 2 : 3 LED (vertes, oranges et rouge) sont reliées aux sorties D43, D45, D47
 * Signal 3 : 3 LED (vertes, oranges et rouge) sont reliées aux sorties D37, D39, D41
 */
    
// Initialisation des variables
// Signal 1
const byte A1V = 49 ;
const byte A1O = 51 ;
const byte A1R = 53 ;
// Signal 2
const byte B1V = 43 ;
const byte B1O = 45 ;
const byte B1R = 47 ;
// Signal 3
const byte C1V = 37 ;
const byte C1O = 39 ;
const byte C1R = 41 ;

//Délai des différents temps mis en const pour changer facilement
// si le délai imparti ne vous satisfait pas. Il s'agit de millisecondes
const long TempsAttenteFeuRouge = 2000;
const long TempsAttenteFeuVert = 2000;
const long TempsAttenteFeuOrange = 2000;


void setup()
{
  pinMode (A1V, OUTPUT) ;
  pinMode (A1O, OUTPUT) ;
  pinMode (A1R, OUTPUT) ;
  pinMode (B1V, OUTPUT) ;
  pinMode (B1O, OUTPUT) ;
  pinMode (B1R, OUTPUT) ;
  pinMode (C1V, OUTPUT) ;
  pinMode (C1O, OUTPUT) ;
  pinMode (C1R, OUTPUT) ;
  Serial.begin(9600);
  // Les feux sont à voie libre
  digitalWrite (A1V, HIGH) ;
  digitalWrite (A1O, LOW) ;
  digitalWrite (A1R, LOW) ;
  digitalWrite (B1V, HIGH) ;
  digitalWrite (B1O, LOW) ;
  digitalWrite (B1R, LOW) ;
  digitalWrite (C1V, HIGH) ;
  digitalWrite (C1O, LOW) ;
  digitalWrite (C1R, LOW) ;
}

void loop()
{

  int capteur_1 = analogRead(3);
  int capteur_2 = analogRead(4);
  int capteur_3 = analogRead(5);

  Serial.print("Capteur 1: ");
  Serial.println (capteur_1);
  Serial.print("Capteur 2: ");
  Serial.println (capteur_2);
  Serial.print("Capteur 3: ");
  Serial.println (capteur_3);


  if (capteur_1 <= 480 && capteur_2 >= 480 && capteur_3 >= 480)
  {
    // Concerne le feu A1
    delay (TempsAttenteFeuRouge) ; // Temporisation
    digitalWrite (A1R, HIGH) ; // et allumage de A1R
    digitalWrite (A1O, LOW) ;
    digitalWrite (A1V, LOW) ;
    // Concerne le feu B1
    delay (TempsAttenteFeuVert) ; // Feu vert B1V pendant n secondes
    digitalWrite (B1V, HIGH) ;
    digitalWrite (B1O, LOW) ;
    digitalWrite (B1R, LOW) ;
  // Concerne le feu C1
    delay (TempsAttenteFeuVert) ; // Feu vert C1V pendant n secondes
    digitalWrite (C1V, HIGH) ;
    digitalWrite (C1O, LOW) ;
    digitalWrite (C1R, LOW) ;
  }
  if  (capteur_1 >= 480 && capteur_2 <= 480 && capteur_3 >= 480)
  {
    // Concerne le feu A1
    delay (TempsAttenteFeuOrange) ;
    digitalWrite (A1O, HIGH) ;
    digitalWrite (A1V, LOW) ;
    digitalWrite (A1R, LOW) ;
    // Concerne le feu B1
    delay (TempsAttenteFeuRouge) ;
    digitalWrite (B1R, HIGH) ;
    digitalWrite (B1O, LOW) ;
    digitalWrite (B1V, LOW) ;
    // Concerne le feu C1
    delay (TempsAttenteFeuVert) ;
    digitalWrite (C1V, HIGH) ;
    digitalWrite (C1O, LOW) ;
    digitalWrite (C1R, LOW) ;
  }
  if  (capteur_1 >= 480 && capteur_2 >= 480 && capteur_3 <= 480)
  {
    // Concerne le feu A1
    delay (TempsAttenteFeuVert) ;
    digitalWrite (A1V, HIGH) ;
    digitalWrite (A1O, LOW) ;
    digitalWrite (A1R, LOW) ;
    // Concerne le feu B1
    delay (TempsAttenteFeuOrange) ;
    digitalWrite (B1O, HIGH) ;
    digitalWrite (B1V, LOW) ;
    digitalWrite (B1R, LOW) ;
    // Concerne le feu C1
    delay (TempsAttenteFeuRouge) ;
    digitalWrite (C1R, HIGH) ;
    digitalWrite (C1O, LOW) ;
    digitalWrite (C1V, LOW) ;
  }
  delay (250);
}

Le Test

Au démarrage, bien vérifier que tous les feux sont verts (tous les cantons sont libres) et que les leds rouge des capteurs sont toutes allumées (capteur en fonctionnement).
Rien de plus facile et amusant que de faire ce test à l'aide d'un aimant qui est à positionner sur chaque capteur (sur le petit composant noir sur le capteur) pendant quelques secondes.
Vous verrez alors les LED des signaux s'animer conformément aux schémas présentés dans les principes.

Une petite vidéo illustre tout cela :


Les capteurs peuvent être positionnés entre les rails (à condition d'enlever le bornier vert) et vous obtiendrez ainsi un système de cantonnement fonctionnel aussi bien pour un réseau de train en HO qu'en G (train de jardin)! La seule contrainte est de mettre en aimant sous le dernier wagon/voiture.