Une débutante dans le décor - Ep6 - Quelques automatismes (Arduino Nano)

Hello,

J’ai fait plutot canapé, vodka des bisons :wink: et U2 “Until the End of the World”

J’ai au moins un lecteur intéressé :star_struck: !

Oui j’ai voulu rajouter un afficheur (optionnel), ça permet d’afficher l’état en cours, c’est mieux pour s’assurer que l’automatisme est opérationnel que de ressortir le cable USB et le PC. C’est un afficheur à 2.16 € (par lot de 5), c’est pas un surcout inintéressant pour ma fosse et ultérieurement d’autres automatismes que j’envisage (portes des remises, pompe à eau, …).

Le temps de package ce tutoriel …

Add-on Tuto7

Toujours en prévision de l’automatisme pour la fosse d’inspection, j’ai décidé d’ajouter un petit afficheur 4 digits 7 segments avec un composant TM1637, toujours une référence chez AZ-Delivery, cout unitaire 2.16€, vendu par lot de 5 afficheurs.

https://www.amazon.fr/gp/product/B078S8SGW2/

Pour utiliser cet afficheur, il faut télécharger la documentation de AZ-Delivery sur leur site, lien ici.

Comme pour les autres composants, la documentation est extrêmement bien faite, et l’exemple permet de créer très rapidement sa propre application.

Le branchement de l’afficheur est facile :

  • broche GND vers la GND de l’Arduino
  • broche VCC vers le +5V de l’Arduino
  • broche DIO vers D8 de l’Arduino (on peut choisir un autre Dx que l’on paramètre)
  • broche CLK vers D9 de l’Arduino (on peut choisir un autre Dx que l’on paramètre)

Comme indiqué dans la documentation, Il faut aussi installer une librairie dans l’IDE Arduino pour le composant TM1637. Il en existe plusieurs, il faut choisir celle de Avishay Orpaz dans le menu Outils → Gérer les bibliothèques.

Ensuite on peut créer un objet display et utiliser trois fonctions principales :

  • setSegments() : pour allumer des segments particuliers pour chacun des digits
  • encodeDigit() : pour donner la liste des segments à allumer pour afficher un chiffre particulier
  • clear() : pour effacer l’afficheur

Pour mon exemple, j’ai dédié le premier digit à l’état de la voie :

  • o : occupée
  • L : libre
  • 5 : STOP

Et les trois digits suivant affichent la tension lue sur l’entrée analogique. Attention c’est la valeur ramenée dans la plage 0 - 5V sur une échelle de 0 à 1023. Il faudrait une règle de trois pour trouver la valeur réelle.

Cet affichage est réalisé par la fonction AfficheEtatVal() dans le source suivant. Le reste du programme est calqué sur le Tuto06 précédent.

Pour la définition des SEG_A … SEG_G, voici la matrice de mapping avec les 7 segments du digit :

Et le programme (ou sketch dans la terminologie Arduino) :

// Tuto07
// Exemple pour le forum 3rails / Julie Dumortier / Licence GPL
// 
// extrait du programme Fosse v1.5
//   afficher l'état de la voie sur le rail contact : STOP, libre ou occupé
//    sortie D3 -> relais (LOW = voie libre, HIGH = voie occupée)
//    sortie D13 -> led interne (LOW = voie alimentée, HIGH = voie STOP) EXPERIMENTAL
//   utiliser un afficheur 7 segments 4 digits
//
// Retrouvez ce tutoriel sur le lien : https://forum.3rails.fr/t/une-debutante-dans-le-decor-ep6-quelques-automatismes-arduino-nano/18361
// version 14 mai 2021 : l'état de la voie est prise directement sur le signal

// défini la broche (pin) utilisée pour commander le relais : D3
int relaisPin = 3;

// défini la broche (pin) utilisée pour lire la valeur analogique : A3
int Pin_etatRail = 3;

#include <Arduino.h>
#include <TM1637Display.h>

#define CLK   9
#define DIO   8

TM1637Display display(CLK, DIO);
uint8_t segments[] = {0xff, 0xff, 0xff, 0xff};

// variable pour stocker le seuil de déclenchement
int seuilSignal = 384;

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

// on va filter le signal bas pendant 192 ms pour décider que la voie est libre
int msFiltre = 192;

// 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

// AfficheEtatVal
//  affiche l'état et une valeur
//

void AfficheEtatVal(int etat,int val)
{
  // 1er segment : Etat
  switch (etat) {
    case voie_Libre:
      segments[0] = SEG_F | SEG_E | SEG_D;
      break;

    case voie_Occupee:
      segments[0] = SEG_C | SEG_E | SEG_D | SEG_G;
      break;

    case voie_STOP:
      segments[0] = SEG_A | SEG_C | SEG_D | SEG_F | SEG_G;
      break;

    default:
      display.clear();
      break; 
  }
  segments[1] = display.encodeDigit((val / 100) % 10);
  segments[2] = display.encodeDigit((val / 10) % 10);
  segments[3] = display.encodeDigit(val % 10);
  display.setSegments(segments);  
}

// EtatVoie
// retourne l'état de la voie

int EtatVoie()
{
  int n = msFiltre;
  int c = 0;
  
  int vr = 0;
  int vt = 0;

  // 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);

    if (vt>1) {
      traction = vt;
    }
    
    if (vr>seuilSignal) {
      c = c + 1;
    }

    if (c>nbFiltre) {
      // la voie est encore occupée

      // attends la fin du compteur-> la fonction EtatVoie() est à temps d'exécution constant (ce délai peut être supprimé)
      delay(n);

      // met à jour l'afficheur
      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
    Serial.println("voie libre");

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

  // pas de traction

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

// code executé une seule fois au démarrage du module (ou après un reset)
void setup() {

  // programme la sortie digitale D3 en sortie
  // le In du relais est connecté à cette sortie D3
  pinMode(relaisPin, OUTPUT);

  // Led 13 interne : rouge si STOP détecté, éteinte sinon
  pinMode(LED_BUILTIN, OUTPUT);

  // 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 !
  Serial.begin(57600);

  // relais COMMON - NC (led verte allumée)
  digitalWrite(relaisPin,LOW);

  // regle l'intensité de l'affichage
  display.setBrightness(0x0f);
  display.clear();
}

// code executé en permanence (une boucle)
void loop() {

  int etat;

  etat = EtatVoie();

  switch (etat) {
    case voie_Libre:
      // relais COMMON - NC (led verte allumée)
      digitalWrite(relaisPin,LOW);
      
      // led 13 éteinte - voie alimentée
      digitalWrite(LED_BUILTIN,LOW);
      
      Serial.println("Voie libre");
      break;

    case voie_Occupee:
      // relais COMMON - NO (led verte eteinte)
      digitalWrite(relaisPin,HIGH);

      // led 13 éteinte - voie alimentée
      digitalWrite(LED_BUILTIN,LOW);
      
      Serial.println("Voie occupée");
      break;

    case voie_STOP: // EXPERIMENTAL
      // relais COMMON - NO (led verte eteinte)
      digitalWrite(relaisPin,HIGH);

      // led 13 allumée - voie STOP
      digitalWrite(LED_BUILTIN,HIGH);

      Serial.println("Voie STOP");
      break;

    default:
      Serial.print("Voie état inconnu = ");
      Serial.println(etat);
      break;
  }

  delay(250);

}

A noter que le programme fonctionne parfaitement bien même en l’absence de l’afficheur.

Et comme à chaque fois, une petite vidéo pour illustrer ce tutoriel (vous remarquerez que ce tutoriel est réalisé directement sur la fosse de visite … mais il fonctionnera parfaitement avec le montage de voie C précédent) :

Un dernier mot : si vous voulez afficher la tension de la voie en dixième de volt, vous pouvez ajouter ces quelques lignes en tête de la fonction AfficheEtatVal :

void AfficheEtatVal(int etat,int val)
{
  // conversion de val en dixième de Volts (dV)
  float temp;

  temp = (250.0*val)/1024.0; // capteur de tension est sur une plage 0-25V
  val = (int)temp;
  ...

Ce dernier exemple clôture notre Episode 6 ! La suite côté fosse de visite.

Bonjour Julie,

C’est très obscur pour moi ces arduinos maisj’ai l’impression que les possibilités sont énormes…

Il faudra que je m’y mette un jour…

Bonne continuation

Thomas

Bonjour Thomas,

Oui les possibilités sont énormes et je peux t’assurer que leur mise en oeuvre n’est pas si compliquée. Il faut juste se lancer. Et au travers de ce tutoriel, je découvre l’Arduino au fur et à mesure.

Je n’avais pas fait d’électronique depuis mes 25 ans (68HC11 à l’époque et c’était nettement plus compliqué à cabler et à programmer). Là il suffit de brancher des broches (pins) en suivant le manuel …

Il y a encore quelques jours je n’aurais même pas imaginé y mettre un afficheur par exemple. Et finalement je trouve la programmation d’un M83 via les CV bien plus compliqué que mettre en oeuvre un Arduino Nano. En plus le logiciel de programmation arrive avec une foultitude d’exemples tous très bien documentés.

Tsss. Y en a pour 12 euros d’achats et 1 heure de mise en oeuvre … pourquoi repousser ça à la saint glinglin :wink:

Je trouve que ça change les perspectives de ce que l’on peut faire sur un module : simulation d’un poste de soudure à l’arc, ouverture automatique des portes d’une remise, contrôle d’une grue à eau …

J’ai finit l’automatisation de mon pont tournant avec le kit Locomotech avant de mettre en oeuvre cet Arduino. Mais je me faisais la réflexion que je pouvais faire la même chose avec un Arduino Nano, un capteur photo-électrique et deux relais pour le 1/4 du prix … Bon c’est fait mais si c’était à refaire …

Bonne journée :slight_smile:

Julie a raison, c’est simple à mettre en oeuvre et pas cher. J’ai fait un simulateur de soudure à l’arc sans problème. Tu peux aussi gérer des diodes RGB pour une affiche lumineuse, etc…
Sur le site locoduino, il y a plein d’exemple du plus simple à la gestion de locos DCC.
Belle journée Jean-Luc

1 « J'aime »

L’automatisme de la fosse d’inspection est publié ici :

Enjoy.

Hello Julie,
Très intéressant tes explications concernant l’Arduino Uno.
Comme je suis uniquement en analogique, peux-t-on l’utiliser pour travailler avec les signaux et voies de garage, etc, ou il faut absolument une MS2 ou CS2 ?
Moi je n’y connais rien en électronique donc …
Amicalement
Serge

Bonsoir Serge,

Dans le cadre de l’automatisme de la fosse, je n’utilise aucune fonction dite numérique de la voie. Je ne fais que lire sa tension pour savoir si elle est alimentée ou non. Et dans ma vidéo j’utilise la MS2 juste pour mettre la voie en Stop ou en service.

A priori cela devrait fonctionner en analogique mais ne connaissant absolument pas ce domaine ancien de Marklin, je ne serais pas affirmative.

Bonne soirée,

1 « J'aime »

Aucune raison que ça ne fonctionne pas en analogique, l’utilisation de l’Arduino n’a nul besoin du digital pour fonctionner.
Jean-Luc

1 « J'aime »

Merci Jean-Luc pour ces infos, mais ce qui coince pour moi c’est les branchements, pour éviter de cramer les signaux. Y a-t-il des modes d’emploi pour les branchements ?
Serge

Si tu suis le tutoriel, aucun problème. L’Arduino ne fait que lire une tension au travers d’une petite carte analogique qui converti le 0-25V en 0-5V la tension d’entrée de l’Arduino. Au pire, c’est l’Arduino que tu vas cramer si tu le branches directement sur la voie … (mésaventure qui m’est arrivée).

Après tu peux faire comme moi : tu te montes un bout de maquette sur une table avec quelques rails et tu fais tes essais et tes mises au point. Aucun risque pour ton réseau principal/

@+

Merci Julie,
J’espère que l’on trouve ce genre de matos en Suisse, car pour l’instant rien vu, peut-être sur Ebay, mais le port est conséquent je trouve.
Amicalement

J’ai vu quelque chose sur le Net, je vais regarder de près. Mais quoi prendre comme platine au départ, mystère.
Serge

J’ai pris chez Amazon, avec Prime les frais de port sont 0. Et chez AZ Delivery les frais de port ne sont pas très important non plus.

3.90 € en livraison premium (3 à 4 jours de délais) et gratuit pour plus de 15 € d’achats …

@+

Annexe C - Les fichiers des tutoriels Tuto01 à Tuto07

Versions du 21 mai 2021 :

Merci, c’est cool de les avoir en pdf.
Joyeux Noël !
Jean-Luc

1 « J'aime »

Bonjour Julie

Tu as 99% de chance de le fumer accidentellement.
Il n’y a pas de problème de relier la masse (GND) de l’Arduino à la masse ‘O’ du circuit. Faire attention néanmoins de ne pas avoir une boucle par l’ordinateur si celui-ci est également branché à la centrale.

Par contre les entres/sortie de l’Arduino ne doivent jamais dépasser la plage de tension -0.5V à VCC + 0.5V. Pour un rail de contact quand tout va bien la tension c’est soit 0V soit en l’air. Mais la probabilité d’avoir un retour de la tension numérique est proche de 100% (Ne serait-ce que par une loco qui perd brièvement le contact avec l’autre rail. Et dans ce cas l’Arduino va fumer de manière quasi instantanée.

Il faut un circuit de protection entre le rail de contact et l’entrée Arduino. On le trouve sur tous les schémas des S88 et similaires.

Bonne suite

Sylvain

Merci Sylvain,

Effectivement il y a un risque non nul sur un retour même si j’ai prévu des diodes de protection sur le rail de contact ?

Je vais devoir mettre cette protection sur chaque entrée digitale. :slight_smile:

Je vais voir s’il n’existe pas un module tout fait pour interfacer un nano avec ce genre de protection. Car je veux rester dans une démarche plug and play avec un petit coût.

J’ai trouvé une carte bornier mais elle est en prise directe, sans aucune protection.

A+

Bonjour Julie,

Très instructif ton tuto sur l’Arduino. Qqs questions en vrac

Le fil bleu est branché sur un rail (un seul rail à isoler bien sur ?) et non sur le picot central. Exact ?(apparemment puisque tu parles d’essieu conducteur mais bon …).
Ds le programme les lignes précédées de // sont des commentaires (sans action sur le prog lui même) tandis que celles sans // sont celles du prog proprement dit Exact?
Penses tu que l’Arduino puisse piloter un relais double contacts (puissance < à 150-200mA)
Y a-t-il un “dictionnaire” des termes à utiliser pour la programmation de l’Arduino (tous les digitalWrite, serial.println, delay etc…)
Cet Arduino peut-il être commandé par une CS3 dans la réalisation d’événements (un peu comme les M83 pour les aiguilles) ?

Bon assez pour aujourd’hui les questions !!

Cordialement,
Claude papaciela

Bonjour Claude,

Merci pour tes questions en vrac, elles sont très intéressantes pour compléter ce petit tutoriel. Allons-y l’une après l’autre.

J’ai fait un montage similaire à un rail à contact : les plots centraux (ou le rail central pour la fosse) sont connectés au B (Bahn) et l’un des deux rails est connecté au O. L’autre rail est effectivement un fil bleu sur lequel on va détecter la présence d’une tension lorsque qu’un essieu aura établi un contact entre les deux rails (en 3 rails les essieux sont conducteurs). Bien évidemment les deux rails sont isolés en amont et en aval.

Voir le maintenant classique montage avec une éventuelle diode de protection contre les retours de courant :

Tu peux voir aussi le montage que j’ai fait pour la fosse d’inspection ici : Une débutante dans le décor - Ep4 - Kitbashing d’une fosse d'inspection - #36 par Julaye

L’Arduino (tous modèles) se programme en un langage C / C++ (au contraire du Rasberry Pi qui se programme en Python). Parce que le C est le langage le moins gourmand en ressource et particulièrement efficace pour le petit embarqué contraint avec des tailles mémoires petites et des puissances de calcul limitées.

En C et C++, // marque une ligne avec un commentaire et /* */ encode une section de commentaires. Pour ma part, je n’utilise que le //.

Les autres lignes sont du source en langage C / C++ qui est transformé (on dit compilé) en code binaire exécutable par le logiciel Arduino de ton PC (ou de ton Mac), code téléchargé sur la carte pour être exécuté.

Il te faut un relais qui se commande en 0-5V. Arduino propose du double - canal (en réalité c’est une carte avec deux relais indépendant). En fonction de ton usage que je devine, il faut plutot un relais 2RT, et on en trouve en 0-5V pour la commande.

Oui la documentation est très complète : toutes les fonctions de base et les fonctions en bibliothèque (ou encore appelée la librairie qui n’est chargée sur la carte que si besoin).

Tu peux commencer avec ce lien :

Pour chaque fonction comme digitalWrite(), une explication détaillée des paramètres et de la fonctionnalité avec un ou plusieurs exemples d’utilisation.

L’Arduino possède beaucoup d’entrées digitales et certaines peuvent être utilisées pour recevoir des ordres depuis un M83 ou M84, en entrée Pull-up. C’est comme ça que j’ai mis des commandes de forçage allumé / éteint pour mes fosses depuis ma MS2.

L’étape suivante est de faire discuter l’Arduino avec la centrale (ou la mobile Station), en protocole Motorola ou DCC. Mais ceci est une histoire un peu plus compliquée que tu peux trouver sur un site dédiée : https://www.locoduino.org

Ici, je me contente d’utiliser l’Arduino pour réaliser des petits automatismes sympa pour pas cher.

Je vais même rappeler l’esprit de mes tutoriels Arduino : je souhaite utiliser l’Arduino comme petit automate sans utiliser de fer à souder : uniquement des petits modules pas chers que je connecte entre eux autour de cet Arduino Nano, comme un “lego” électronique.

Au besoin, il est toujours possible de prendre une sortie d’un M83 ou un M84 pour lancer une séquence d’un automatisme particulier, par exemple. J’aime bien le M84 configuré en mode 2, il permet d’avoir jusqu’à 8 commandes pull-up par exemple pour autant de fonctions digitales sur l’Arduino.

Mon prochain tutoriel avec un Arduino sera justement de remplacer un servo contrôler horriblement cher de chez Faller pour commander jusqu’à 6 servo moteurs avec cette petite carte de 5 € … (ça marche déjà sur mon petit bureau de Dakar). Et réaliser des petits automatismes du style la locomotive approche, la porte de la remise s’ouvre. Et avoir quand même une commande ouverture de porte depuis un M84.

A suivre,