lunedì 23 dicembre 2019

Controlliamo gli scambi con Arduino su Xpressnet

Dopo la pubblicazione del palmare Multiloco per sistemi Xpressnet©, molti mi hanno chiesto di dotare lo stesso della capacità di poter pilotare gli scambi.
L' esigenza del palmare multi loco, come ho avuto modo di spiegare nel primo articolo, è nata dal fatto di poter avere a disposizione i comandi "basic" a portata di mano per controllare più di una loco, su plastici medio piccoli, senza alcuna navigazione in menù o combinazioni di tasti.
Dotare il Palmare Multiloco della funzionalità di comando scambi avrebbe un pò fatto venir meno questo principio per cui ho preferito venire incontro alle esigenze di qualche amico pensando ad un progetto ex-novo, ovvero un Arduino che avesse la possibilità di pilotare gli scambi tramite una serie di pulsanti.
Il progetto che verrà descritto quindi è un controllore di scambi per sistemi basati sul protocollo Lenz Xpressnet©, qualcosa di simile a quanto già progettato e pubblicato da Paco Canada con il suo "XTCO".
Il progetto utilizza un Arduino Nano, data la semplicità del codice, esso è facilmente applicabile ad Arduino Uno o meglio ancora (vista la quantità di pin) Arduino Mega.
Anche in questo caso ho fatto uso delle librerie di Philipp Gahtow (http://pgahtow.de) che ancora una volta è stato molto disponibile nel fornire supporto e al quale vanno i miei ringraziamenti.

Lo schema è il seguente:

Schema di connessione


Lo schema riporta solo 4 degli 8 pulsanti che sono stati configurati nello sketch, esso rappresenta effettivamente il prototipo che ho realizzato per le prove.
Per connettersi al bus Xpressnet© è stata utilizzata l' interfaccia del palmare Multiloco con qualche lieve modifica per aggiungere un LED che indica la presenza della tensione 5V:






Lo sketch da caricare su Arduino è molto semplice, in pratica viene letto in loop lo stato dei pulsanti e quando viene rilevata la pressione di uno di questi cambia lo stato dello scambio ad esso associato.




Ogni pulsante quindi agisce da "toggle" per lo scambio cui è stato associato: premendo il pulsante lo scambio cambia stato, da corretto tracciato va in deviato o viceversa. La scelta di un solo pulsante per scambio (e non due pulsanti associati alle due condizioni, "corretto tracciato" e "deviato") è stata fatta per avere un numero sufficiente di scambi pilotabili da Arduino Nano che mette a disposizione un discreto numero di pin I/O (D3-D13 digitali, A0-A7 Analogici). Lo scketch proposto configura 8 pin come input:
int turnout_pin[num_turnout] = { 3, 4, 5, 6, 7, 8, 9, 10};

questa riga di codice elenca i pin associati ai pulsanti. Nulla vieta di aggiugere altri pin, occorre però ricordarsi anche di aggiornare la variabile di configurazione che indica il numero di scambi gestiti da Arduino:

#define num_turnout 8


Ad ogni scambio va poi associato un indirizzo che corrisponde all' indirizzo del decoder cui è connesso il motore dello scambio stesso.

E' necessario fare una premessa: in ambito DCC, ci sono diversi modi di gestire l' indirizzamento dei decoder accessori (PADA, MADA etc), quello utilizzato dipende dalle varie centraline in commercio o autoscostruite che fanno parte del nostro impianto. Un'ottima spiegazione è riportata nella wiki del noto software Rocrail© di Robert Versluis (link).
In pratica può capitare che uno stesso decoder sia visto con indirizzi diversi a seconda del dispositivo che lo piloti: ad esempio nel mio impianto, che è equipaggiato con la centralina NanoX di Paco Canada, uno stesso scambio ha indirizzi diversi se viene comandato dall' XTCO di Paco Canada o dal software RocRail© tramite interfaccia PC.

Nello sviluppo dello sketch, utilizzando le librerie di Philipp Gahtow, ho riscontrato ancora una differenza: per muovere lo scambio programmato con indirizzo 2, ho dovuto indicare come indirizzo 5 e così via per tutti gli altri: esiste una differenza di "3" costante. Probabilmente ciò avviene perchè i vari costruttori/programmatori interpretano gli indirizzi di partenza da 0 o da 1 con logiche e principi diversi. L'unica cosa è... provare!

Fatta questa premessa, l' indirizzo associato ai vari pulsanti/pin è contenuto nella variabile:

int turnout_pin[num_turnout] =  { 3, 4, 5, 6, 7, 8, 9, 10};
int turnout_add[num_turnout] = { 1, 2, 3, 4, 5, 6, 7,  8}; 

l' array che contiene gli indirizzi segue quello che indica i pin, al pin 3 è associato l' indirizzo 1, al pin 4 indirizzo 2 etc.
Per ovviare alla differenza di indirizzi che si può avere fra l' indirizzo del decoder e l'indirizzo che effettivamente viene inviato dallo sketch alla centralina è stata utilizzata la variabile:

int address_offset = 3;

tale valore viene somamto all' indirizzo programmato nella variabile turnout_add[num_turnout] e può essere cambiata a seconda delle esigenze. Come ho anticipato, occorre fare delle prove per definire l' esatto valore della variabile "address_offset".

Arduino Nano dispone di una sola porta seriale e nel progetto descritto in questo articolo essa è utilizzata per scambiare messaggi sul bus Xpressnet tramite il chip MAX485. Allo stesso tempo però tale interfaccia è quella utilizzata da Arduino per caricare gli sketch da PC, poichè il MAX 485 se connesso ad Arduino non permette a questi di colloquiare con il PC tramite la porta USB, occorre disconnetterlo ogni volta che vogliamo caricare un nuovo sketch sul nostro Arduino Nano.

Questa una foto del prototipo realizzato:












6 commenti:

  1. Sarebbe possibile collegare anche dei led che indichino la posizione attuale degli scambi, in modo da poter costruire un quadro sinottico completo?

    RispondiElimina
    Risposte
    1. Questo commento è stato eliminato dall'autore.

      Elimina
    2. Ciao,
      certamente si può associare un led allo stato dello scambio, il vettore turnout[num_turnout] contiene infatti lo status corrente dello scambio, si possono quindi definire alcuni pin di Arduino come uscita e associare ad essi lo stato del vettore, ad esempio:

      pinMode(, OUTPUT); --> nella sezione "setup"
      pinMode(, OUTPUT);

      e quindi nel loop principale:

      digitalWrite(,turnout[]);
      digitalWrite(,!turnout[]);

      in questo modo i led risulteranno accesi/spenti a seconda dello stato del deviatoio. E' chiaro che occorre una versione di Arduino con molti pin a disposizione (Mega) oppure utilizzare come ha già suggerito Stefano, un espansore I2C.
      Tuttavia consiglierei di utilizzare un altro metodo per fare un sinottico, ovvero prendendo l' informazione direttamente dallo scambio utilizzando la polarizzazione del cuore come indicato qui --> https://model-railroad-hobbyist.com/node/25604?page=1
      In questo modo infatti l' informazione della posizione dello scambio è effettivamente derivata dal campo.
      saluti :)

      Elimina
  2. Assolutamente si, anche se il Nano ha pochi pin a disposizione. Tuttavia si potrebbe facilmente espandere via I2C con un Port Expander. Altra via è utilizzare un Mega.

    RispondiElimina
  3. Buonasera, sto provando a contattarla tramite il form presente nella pagina ma senza risultato.
    Sono completamente a digiuno di elettronica ma nonostante tutto sto cercando di realizzare lo schema da lei proposto ma, chiedo venia nel caso di errori :
    1) devo seguire il disegno fritzing o lo schema?
    2) arduino da cosa viene alimentato?
    Sperando di non aver detto eresie complete ed attendendo uno sperato aiuto la ringrazio.

    Saluti

    RispondiElimina
    Risposte
    1. lo schema elettrico e lo schema fritzing sono la medesima cosa, uno in forma schematica e l'altro in forma grafica.
      Arduino viene alimentato dalla tensione di 12V presente nella porta Xpressnet ai pin 5 e 2, opportunamente sabilizzata ai 5Vdc mediante il 7805

      Elimina