Remarques :
Remarques :
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
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).
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
... 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
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.
L'optocoupleur peut éventuellement être soudé directement, sans socket.
Attention au sens ainsi qu'à la numérotation des bornes.
En optimisant, il est possible de placer jusqu'à 12 détecteurs sur une seule plaque de prototypage.
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.
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é.
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 :
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 :
timer=Timer()
timer.init(freq=5, callback=check_detect)
Rien de bien compliqué : un Timer appelle la fonction check_detect cinq fois par seconde.