Comando completo per deviatoio

Torna alla pagina CONTROLLO

Introduzione

Come funzionano nella realtà i deviatoi? Gli aghi sono di acciaio più tenero rispetto alle rotaie e sono mossi da motori elettrici potenti. Quando l'operatore muove un deviatoio tramite gli apparati il motore entra in moto, un ronzio di controllo è trasmesso alla cabina degli apparati mentre il motore gira; al termine il ronzio si ferma e cambiano aspetto le spie indicative della posizione se tutto va bene. In caso contrario si attivano gli allarmi opportuni.


Nei plastici

Cosa avviene nei nostri plastici? la gestione è molto più semplice, ma possiamo affinarla. Andiamo per gradi. Per primo, analizziamo il caso classico. Ci troviamo ad avere un deviatoio mosso da un elettromagnete o relé bistabile. Due pulsanti eccitano alternativamente le due parti dell'avvolgimento muovendo un'ancoretta a cui sono connessi gli aghi:

I deviatoi dell'ultima generazione sono dotati di fine corsa, pertanto non restano eccitati una volta terminato il movimento. In questo modo non si corre il rischio di bruciare gli avvolgimenti del solenoide. Al posto dei pulsanti possiamo collocare un commutatore. Se esso muove anche altri contatti possiamo avere sul quadro le spie indicative della posizione assunta:

Sarebbe meglio avere almeno due alimentazioni alternate distinte, la prima deputata al movimento dei deviatoi e motori vari (power), la seconda destinata alle sole luci (light); in questo modo il sovraccarico termporaneo causato dall'eccitazione dell'elettromagnete non abbassa l'intensità delle luci:

 

 

Azionamento lento

Alcune ditte producono gli elettromagneti da collocare sottoplancia. Si può fare ancora di meglio; ci sono in commercio infatti motori a corrente continua (Bemo, Fulgurex, il famoso Tortoise della Circuitron, ecc...) che permettonoc il movimento degli aghi lento come nella realtà:

La foto mostra un modello Tortoise posto in opera. Si notino gli otto contatti che esso pilota. Tali motori, dotati anch'essi di fine corsa, hanno normalmente due coppie di contatti associati. Ad una di esse si collega di solito il cuore che risulta così polarizzato, il secondo commutatore può essere usato per indicare la posizione raggiunta dal deviatoio. Ci avviciniamo pertanto di molto alla realtà: le spie indicative si accendono solo al termine del movimento dei motori dando quindi non solo l'indicazione della posizione, ma anche un riscontro di movimento andato a buon fine:

Si noti il doppio deviatore impiegato ad alimentare il motore elettrico; infatti questi motori invertono la rotazione in corrispondenza dell'inversione di polarità. Un ponte raddrizzatore è collocato a monte. L'alimentazione power  si occupa così di tutti i dispositivi in movimento, anche quelli in corrente continua. La polarizzazione del cuore ha il vantaggio di permettere movimenti di locomotive corte (quelle da da manovra) sul deviatoio, ma ha lo svantaggio di andare in corto se il deviatoio è tallonato.

 

Comando digitale

Che vantaggi ci possono essere con l'adozione dell'alimentazione digitale in questo caso? Innanzitutto lo schema digitale permette la razionalizzazione del cablaggio. Per esempio, lo schema appena illustrato potrebbe essere oneroso da allestire se il quadro si trovasse lontano dal binario con il deviatoio relativo. Se invece il bus con i moduli di retroazione corre lungo il tracciato, è molto comodo connettere i contatti del motore ai suoi ingressi. Le spie possono essere sostituite da simboli grafici sullo schermo del pc. Il vantaggio principale risiede nella possibilità di programmare gli itinerari. Il doppio deviatore può essere sostituito da un relé (ottimo l'articolo 3258 di Essemme) comandato da un indirizzo di un decoder a contatti temporanei (Uhlenbrock articolo 67500). Lo schema si trasforma allora così:

Il decoder di questo tipo comanda due deviatori con un unico indirizzo (nell'esempio vale 2). Anche se il decoder è di natura diversa e trasmette ai contatti la posizione in modo temporaneo, il suo comando è del tutto simile a quanto visto per i segnali precedentemente:

Sub PosizioneNormale

    Const Fine = 32
    Const L = 33

    With Me.MSComm1
        .Output = Chr$(L)
        .Output = Chr$(2)
        .Output = Chr$(Fine)
    End with
End Sub 

Sub PosizioneRovescia

    Const Fine = 32
    Const R = 34

    With Me.MSComm1
        .Output = Chr$(R)
        .Output = Chr$(2)
        .Output = Chr$(Fine)
    End with
End Sub 

 

Leggere gli ingressi

Per completare l'argomento resta da chiarire come fare a leggere via software i valori degli ingressi del dispositivo di retroazione. La centralina trasmette al pc gli ingressi letti in forma di caratteri (o byte). Ogni carattere è composto da 8 bit. Ogni modulo di retroazione ha 16 contatti di ingresso, quindi due caratteri contengono tutta l'informazione trasmessa. Potremmo avere collegati più moduli di retroazione, quindi occorre sapere a quale indirizzarsi per leggere il suo contenuto. Nel caso di un unico modulo installato è sufficiente la coppia di istruzioni seguente:

Me.MSComm1.Output = Chr$(192)
Me.MSComm1.Output = Chr$(193)

seguita immediatamente dalla lettura dei caratteri che il modulo trasmette:

strC = Me.MSComm1.Input

Per prima cosa occorre separare i due caratteri letti;

primoCarattere = Left(strC, 1)
secondoCarattere = Right(strC, 1)

Il passaggio che segue è detto in gergo spacchettamento, ed occorre per sapere il valore di ogni singolo bit corrispondente ai contatti di ingresso. I bit sono contati a partire da destra e dal valore zero:

 

Segue la tabella completa dei valori con la loro conversione in esadecimale e binario:

potenza valore esadecimale (&H) binario
0 1 1 1
1 2 2 10
2 4 4 100
3 8 8 1000
4 16 10 10000
5 32 20 100000
6 64 40 1000000
7 128 80 10000000

Con il sistema decimale rappresentiamo i numeri come somme di valori che sono potenze di dieci. Per esempio il valore 1956 si ottiene così:

1956 = 1 x 10^3 (migliaia) + 9 x 10^2  (centinaia) + 5 x 10^1 (decine) + 6 x 10^0 (unità)

Nel sistema decimale i simboli impiegati sono dieci (0..9). Analogamente i numeri naturali possono essere rappresentati come somme di valori che sono potenza di due. In questo caso i simboli impiegati sono due (0 e 1). Il carattere trasmesso alla seriale indica quali potenze sono attive (bit a 1) e quali no (bit a 0). Se per esempio il carattere trasmesso contiene il valore 45, esso è ottenuto come somma di potenze di due in un solo modo:

45 =  00101101 =  0 x 2^7 + 0 x 2^6 + 1 x 2^5 + 0 x 2^4 + 1 x 2^3 + 1 x 2^2 + 0 x 2^1 + 1 x 2^0

Se arriva tale valore, allora significa che i contatti 0, 2, 3 e 5 del modulo di retroazione sono chiusi, gli altri sono aperti. Tornando allo schema, se il contatto 1 è attivo, allora il deviatoio 13 è in posizione normale, se è invece attivo il 2, il deviatoio 13 è in posizione deviata o rovescia. Per sapere il contenuto di ogni bit eseguiamo un operazione logica che verifica lo stato di ogni singolo bit sollevato (1) o no (0):

If primoCarattere And &H1 Then
    Ingresso(1)= True
Else
    Ingresso(1)= False
End If

Analogamente facciamo per tutti i bit presenti; il nono bit è il primo del secondo carattere letto:

If primoCarattere And &H2 Then
    Ingresso(2)= True
Else
    Ingresso(2)= False
End If
 

If primoCarattere And &H4 Then
    Ingresso(3)= True
Else
    Ingresso(3)= False
End If
 

If primoCarattere And &H8 Then
    Ingresso(4)= True
Else
    Ingresso(4)= False
End If
 
 

If primoCarattere And &H10 Then
    Ingresso(5)= True
Else
    Ingresso(5)= False
End If

If primoCarattere And &H20 Then
    Ingresso(6)= True
Else
    Ingresso(6)= False
End If
 

If primoCarattere And &H40 Then
    Ingresso(7)= True
Else
    Ingresso(7)= False
End If
 

If primoCarattere And &H80 Then
    Ingresso(8)= True
Else
    Ingresso(8)= False
End If
 

If secondoCarattere And &H1 Then
    Ingresso(9)= True
Else
    Ingresso(9)= False
End If
 

If secondoCarattere And &H2 Then
    Ingresso(10)= True
Else
    Ingresso(10)= False
End If
 

If secondoCarattere And &H4 Then
    Ingresso(11)= True
Else
    Ingresso(11)= False
End If
 

If secondoCarattere And &H8 Then
    Ingresso(12)= True
Else
    Ingresso(12)= False
End If
 
 

If secondoCarattere And &H10 Then
    Ingresso(13)= True
Else
    Ingresso(13)= False
End If

If secondoCarattere And &H20 Then
    Ingresso(14)= True
Else
    Ingresso(14)= False
End If
 

If secondoCarattere And &H40 Then
    Ingresso(15)= True
Else
    Ingresso(15)= False
End If
 

If secondoCarattere And &H80 Then
    Ingresso(16)= True
Else
    Ingresso(16)= False
End If
 

 

Il comando completo, uso del timer

Mentre i comandi di uscita sono trasmessi una volta per tutte, il controllo degli ingressi deve avvenire in continuazione per riconoscere quando cambiano di stato. Non sappiamo infatti quanto tempo impiega il motore del deviatoio a terminare la sua corsa. Se poi ne abbiamo installato più di uno, per quanto la produzione sia industrializzata, è molto difficile trovare due motori che impieghino esattamente lo stesso tempo per effettuare la loro corsa. Infine, il montaggio del motore sottoplancia. per quanto preciso, ben difficilmente sarà nella stessa posizione relativa per ogni deviatoio del plastico. L'unica possibilità è quindi quella di leggere continuamente lo stato degli ingressi. Questa lettura deve essere indipendente da quanto l'operatore possa fare di altro col programma in esecuzione, cioè deve essere asincrona. VB ha tra i suoi controlli il timer pensato proprio per casi come questo: mentre il timer esegue le sue operazioni, legge cioè i vari ingressi presenti, il resto del programma continua ad essere usato indipendentemente. Il timer ha tra le sue proprietà la frequenza secondo la quale si attiva (interval). Ad ogni scadenza dell'intervallo impostato scatta un evento associato che noi possiamo integrare con le istruzioni che ci servono; per esempio, nel nostro caso leggiamo gli ingressi dei moduli di retroazione ogni dieci millisecondi:


Private Sub Timer1_Timer()

Dim strC As Variant
Dim intLetto1 As Integer
Dim intLetto2 As Integer

Dim j As Integer

Dim a(0 To 7)

Const cLeft = "L"
Const cRight = "R"
Const cON = "ON"
Const cOFF = "OFF"

'//

Me.Timer1.Enabled = False

a(0) = &H1
a(1) = &H2
a(2) = &H4
a(3) = &H8
a(4) = &H10
a(5) = &H20
a(6) = &H40
a(7) = &H80

'//
intLetto1 = 0
intLetto2 = 0
 

Me.MSComm1.Output = Chr$(192)
Me.MSComm1.Output = Chr$(193)
strC = ""
strC = Me.MSComm1.Input

intLetto1 = Left(strC, 1)
intLetto2 = Right(strC, 1)

'// spacchettamento
...

'//

If Ingresso(1) Then
    Call IndicaDeviatoio(13, "Normale")
End If

If Ingresso(2) Then
    Call IndicaDeviatoio(13, "Rovescio")
End If

Me.Timer1.Enabled = True

End Sub

Per evitare sovrapposizione di eventi, la prima istruzione sospende temporaneamente il timer stesso che verrà riattivato al termine della procedura. La routine IndicaDeviatoio riceve due parametri, quale deviatoio vogliamo rappresentare (13) e il suo stato. Essa mosterà sullo schermo in modo grafico o testuale l'informazione. Nel caso più semplice valorizziamo il controllo testuale txtOutDeviatoio inserito nella scheda frmMain:

Private Sub IndicaDeviatoio(byVal pDeviatoio as Integer, byVal pStato as String)

    frmMain.txtOutDeviatoio.text = "Il deviatoio " & Cstr(pDeviatoio) " è in stato " & pStato

End Sub

 

Più moduli presenti

Nella trattazione ci siamo limitati a considerare la presenza di un solo modulo di retroazione. Al bus Loconet possono invece essere aggiunti tanti altri moduli quanti ne servono. Se per esempio i 16 contatti non sono sufficienti per il nostro impianto, occorre aggiungere un altro modulo. Nel nostro impianto i moduli sono tre, per un totale di 48 contatti di ingresso. Leggeremo quindi tre parole di due caratteri ciascuna. Come si fa ad indirizzare e leggere senza ambiguità i tre moduli? La lettura dipende dall'ordine con il quale abbiamo connesso in serie i nostri moduli:


Me.MSComm1.Output = Chr$(192) 'terzo blocco
Me.MSComm1.Output = Chr$(193)
strC = ""
strC = Me.MSComm1.Input

Call Sleep(150)

Me.MSComm1.Output = Chr$(192) 'secondo blocco
Me.MSComm1.Output = Chr$(194)
strA = ""
strA = Me.MSComm1.Input

Call Sleep(150)

Me.MSComm1.Output = Chr$(192) 'primo blocco
Me.MSComm1.Output = Chr$(195)
strB = ""
strB = Me.MSComm1.Input

Call Sleep(150)

 

Torna all'inizio pagina

Torna alla pagina CONTROLLO