Quintilien

Quis, quid, ubi, quibus auxiliis, cur, quomodo, quando

 

Informatique, électronique et train miniaturePour en savoir plus

Détection de la position d'un train miniature

 

Principe de la détection par consommation de courant :

  • La zone de détection correspond à une portion de rail isolée du reste du circuit ;
  • on alimente ce rail en passant par un dispositif qui va mesurer la consommation de courant ;
    • consommation : une locomotive est présente sur la zone ;
    • pas de consommation : pas de locomotive présente.

Remarques :

  • dans un circuit « classique », une locomotive ne se déplace que si elle est sous tension ; elle consomme alors du courant. En d'autres termes, si le système détecte une consommation de courant, c'est qu'une locomotive est en mouvement sur la zone de détection ;
  • dans un circuit « digital », la voie est constamment alimentée ; c'est le décodeur installé dans la locomotive qui commande le sens de marche, le démarrage, l'accélération, la vitesse et l'arrêt ; une locomotive peut donc consommer même si elle est à l'arrêt.
  • pour être précis, il convient de noter que les locomotives ne sont pas les seuls éléments susceptibles de consommer du courant : il en va de même pour les wagons munis d'un éclairage.

 

Passage d'un courant et chute de tension

  • Pour détecter un courant, il suffit d'insérer une diode dans le circuit qui alimente la portion de voie en question ;
  • le passage d'un courant provoque une chute de tension (de l'ordre de 0,5 à 0,8 V pour les diodes habituelles).

Remarques :

  • on utilise une diode et non pas une résistance car la chute de tension aux bornes d'une diode est constante (ou à peu près ...) quelle que soit l'intensité du courant qu'on y fait passer ;
  • si on employait une résistance, la chute de tension à ses bornes serait proportionnelle à l'intensité du courant (cf la loi d'Ohm).

Pour des raisons qui seront expliquées plus loin, la chute de tension, pour quelle soit détectable, doit être supérieure à 0,7 V.

Il suffit de mettre deux diodes en série et le tour est joué.

Il faut garder à l'esprit que la caractéristique principale d'une diode est de ne laisser passer le courant que dans un sens.

Or

  • dans un circuit « classique », le sens de marche de la locomotive est déterminé par la polarité appliquée sur la voie (le positif sur le rail de droite et le négatif sur le rail de gauche par rapport au sens de marche) ;
  • dans un circuit « digital », la tension change alternativement de polarité un certain nombre de fois par seconde.

Pour ces deux raisons, on ne peut pas se contenter de ne placer que deux diodes en série : la locomotive ne fonctionnerait que dans un sens sur un circuit classique et ne fonctionnerait pas du tout sur un circuit digital.

Il est par conséquent nécessaire de prévoir deux groupes de deux diodes (un groupe dans chaque sens).

Une fois le courant détecté, « il n'y a plus qu'à » ...

La tension de 1,4 V aux bornes du « pont » de diodes est envoyée aux bornes d'un petit circuit appelé « optocoupleur », via une résistance de 22 Ω de manière à limiter le courant dans le circuit (cf la loi d'Ohm, I = U / R ≈ 1,4 / 22 ≈ 63 mA).

Le rôle de l'optocoupleur est d'isoler le circuit de « puissance » (la voie) du circuit « logique » (le micro-contrôleur). On utilisera par exemple un 4N35

L'optocoupleur étant basé lui aussi sur une diode (électroluminescente dans ce cas-ci), la tension nécessaire en entrée doit être supérieure à 0,7 V pour que le système fonctionne (d'où la nécessité de placer au moins deux diodes dans le « pont » décrit plus haut).

Remarques

  • dans un circuit « classique », la détection ne se fait que dans un seul sens de marche (étant donné que la chute de tension n'est détectée que si le rail est alimenté en positif; pour détecter également en sens inverse, il suffit de prévoir un deuxième optocoupleur branché en sens inverse (c-à-d en permutant les pin 1 et 2) ;
  • dans un circuit « digital », la détection se fait quel que soit le sens de marche.

 

Entre la sortie de l'optocoupleur et le micro-contrôleur ...

... il est indispensable de placer des résistances de rappel.

Vous trouverez plus d'informations sur ces résistances de rappel - souvent appelées résistances « pull up » et « pull down » - sur le site Developpez.net.

 

Cliquer sur l'image pour l'agrandir  •   Source : Developpez.net

 

En pratique

On l'a vu, on alimente la zone de détection en passant par un « pont de diode ».

Toutefois, si on se contentait de cela, il y aurait une différence de tension d'alimentation entre la zone de détection et le reste du circuit de voie ! Cela se traduirait inévitablement par une différence de vitesse de la locomotive selon qu'elle est ou pas sur la zone de détection.

Pour éviter cela, il suffit d'insérer un deuxième « pont de diode » de manière à ce que le reste du circuit soit alimenté par une tension identique.

Ce deuxième pont de diode n'est là que pour corriger la tension d'alimentation ; il n'est donc pas couplé à un circuit de détection.

Réalisation pratique : côté composants ...

L'optocoupleur peut éventuellement être soudé directement, sans socket.

Attention au sens ainsi qu'à la numérotation des bornes.

 

... et côté soudures

Regroupement des détecteurs

En optimisant, il est possible de placer jusqu'à 12 détecteurs sur une seule plaque de prototypage.

 

Du point de vue software

On l'a vu plus haut, la détection d'un courant se traduit par l'envoi d'un signal sur un des GPIO de notre micro-contrôleur (le GP 2 dans notre exemple).

On peut bien entendu prévoir plusieurs zones de détection distinctes, raccordées chacune sur un GPIO différent.

Du point de vue du software, le signal reçu par le GPIO va être traité comme une interruption (en anglais, un interrupt).

Voir à ce sujet https://microcontrollerslab.com/pir-motion-sensor-raspberry-pi-pico-external-interrupts-tutorial/ pour plus de détails.

 

Code MicroPython - partie 1


def interrupt(ix):
    global lpin, retrosig, prevretro
    ii =  int ( ( str(ix).split(',')[0] ).split('Pin(GPIO')[1] )
    retrosig[ lpin.index(ii) ] = 1

Dans cette première partie, on se contente de définir une fonction qui va mettre un élément d'une liste à la valeur 1 dès qu'un interrupt est reçu.

La variable « ii » contient le numéro du GPIO sur lequel l'interrupt a été détecté.

 

Code MicroPython - partie 2


lpin = [2, 3, 4, 5, 6, 7]    # list of pins assigned to retrosignalisation
retrosig  = [0] * len (lpin)
prevretro = [0] * len (lpin)
rpin = list()                
for i in lpin: 
    rpin.append( Pin(i, Pin.IN) ) 
for i, tmp in enumerate(rpin):
   rpin[i].irq(trigger=Pin.IRQ_RISING, handler = interrupt)

Il s'agit ici de la définition des variables utilisées :

  • lpin contient la liste des GPIO utilisés pour les différentes détections (le GPIO 2 correspond à la première zone, le GPIO 3 à la deuxième zone et ainsi de suite) ;
  • retrosig est une liste de même longueur ; ses éléments seront à la valeur 1 ou 0 (selon qu'un interrupt a été détecté ou pas sur le GPIO correspondant)
  • prevretro est une liste destinée à recevoir les valeurs précédentes de retrosig (la comparaison régulière entre les valeurs « actuelles » et les valeurs « précédentes » permettra de détecter une variation d'état ; voir plus loin).
  • rpin est la liste des GPIO définis comme PIN d'entrées (Pin.IN) ; chacune de ces PINs est en outre associée à la détection d'un interrupt.

 

Code MicroPython - partie 3


def check_detect(x):
    global lcd, lpin, retrosig, prevretro
    if retrosig != prevretro:

        # example
        if retrosig[0] == 1:
            set_speed(speed=0, deceleration=5) 
        #         

        lcd.fill_rect( 0,0,100,10,0 )            # fill_rect( x, y, w, h, c )
        for i, v in enumerate (retrosig):
            if v == 0:
                lcd.fill_rect( i*10,0,10,10,0 )  # black background
                lcd.text(str(v), i*10,1,1)       # column * 10 , white digit 
            else: 
                lcd.fill_rect( i*10,0,10,10,1 )  # white background
                lcd.text(str(v), i*10,1,0)       # black digit
        # print (retrosig)
        prevretro = list(retrosig)
    retrosig  = [0] * len (lpin)

C'est la partie la plus « fun » du code !

Dès qu'une variation d'un des états est détectée, on décide quoi faire.

Pour mémoire, en Python on numérote à partie de zéro : retrosig[0] signifie premier élément de la liste, retrosig[1] deuxième élément et ainsi de suite.

Dans cet exemple :

  • si un interrupt est détecté sur retrosig[0], premier GPIO de la liste (donc le GPIO 2 dans ce cas-ci), on ralentit le convoi jusqu'à la vitesse 0 : il s'arrête (voir la page informatique, électronique et train miniature pour le code relatif la fonction set_speed).
  • on rafraîchit l'affichage de l'état des différents détecteurs : "1" (actif) ou "0" (inactif) sur l'afficheur Oled (cf la page informatique, électronique et train miniature pour plus de détail sur la gestion de l'affichage.

 

Code MicroPython - partie 4


timer=Timer()

timer.init(freq=5,  callback=check_detect)

Rien de bien compliqué : un Timer appelle la fonction check_detect cinq fois par seconde.

 

 


Retourner en début de page