Treni LEGO PF a ricarica automatica (1ª parte)

Siamo partiti dal tentare di recuperare i motori guasti dei treni 9V, e siamo finiti con pacchi batterie “custom”, treni convertiti agli elementi Power Functions™, ricarica wireless per le batterie “custom”.

Cosa volere di più? Dipende, di cose da fare ce ne sono, tante le idee da sviluppare. Supponiamo di essere ad una esposizione per appassionati, dove abbiamo il nostro diorama ferroviario, e immaginiamo di avere il nostro bel treno, convertito agli elementi Power Functions, che ogni minuto fa una fermata alla stazione, dove si posiziona automaticamente sopra la bobina di carica Qi-Charger e ricarica la batteria a bordo per qualche decina di secondi, per poi ripartire, ed andare avanti così fino a che la batteria si trovi, nonostante le microricariche periodiche, con la carica troppo bassa, per cui alla fermata successiva rimane sulla bobina di carica per il tempo necessario a ricaricare fino all’80% la batteria, per poi ripartire. Tutto questo senza alcun intervento da parte nostra, il treno cammina e si regola da solo.

Fantascienza? No, è fatto e collaudato, e vi presento il progetto, completo di tutte le istruzioni per farlo funzionare su tutti i diorami ferroviari. Inoltre, cosa non da poco, se abbiamo realizzato il pacco batterie “custom” con la ricarica wireless abbiamo già quasi tutti gli elementi necessari, non serve molto altro. L’unico problema è che a questo punto occorre qualcuno che ne sappia di resistenze, condensatori ed altri componenti elettronici, almeno per quanto riguarda il montaggio e l’uso degli strumenti minimi necessari per la costruzione ed il collaudo: saldatore a stagno per l’elettronica, tester, “bruciare” un programma su un Arduino.

Andiamo a cominciare, dopo le consuete
Avvertenze: niente di quello che viene scritto e detto qui ha una garanzia di funzionamento o di utilità. Le operazioni richiedono esperienza nel campo, mentre i componenti utilizzati hanno limiti e precauzioni d’uso, e vanno maneggiati solo da persone con specifiche competenze. Non mi assumo nessuna responsabilità né sul funzionamento né su eventuali danni a persone o cose che possano derivare da usi impropri o imprudenti di quanto qui descritto. Gli accumulatori al Litio hanno specifiche precauzioni d’uso, riferirsi alle schede tecniche dei rispettivi produttori.

Il progetto

Ho creato due varianti: una con Arduino Nano ed una con Digispark, un micro-microcontroller compatibile con Arduino. Sono entrambe valide, ed hanno le stesse funzioni. L’unica differenza è la dimensione: l’Arduino Nano è circa il doppio del Digispark, e visto che le dimensioni possono essere un problema, ho preferito avere le due versioni. Il primo prototipo è stato fatto con Arduino Nano, poi ho realizzato il secondo con il Digispark: presenteremo gli schemi elettronici per entrambi, le fasi di costruzione saranno praticamente identiche per le due varianti, tranne che nella realizzazione del circuito.

I requisiti di progetto sono:

  • Uso degli elementi Power Functions™
  • Alimentazione a batteria con il pacco “custom” creato in precedenza
  • Il treno deve essere in grado di localizzare autonomamente la bobina di carica Qi-Charger
  • Il treno deve tenere sotto controllo il livello di carica della batteria, e procedere alla carica completa se necessario
  • Le modifiche agli elementi LEGO® devono essere limitate a quelle già fatte per la ricarica wireless ed il pacco batterie “custom”, ossia: la bobina di carica integrata nel binario PF dritto; la bobina ricevente incollata alla piastra 2×4; il cavetto di prolunga PF tagliato per portare alimentazione al ricevitore del telecomando LEGO
  • Il treno deve rimanere controllabile con il telecomando a infrarossi standard LEGO
  • Limitare i costi

La soluzione proposta sfrutta il fatto che qualcuno ha utilizzato le specifiche del protocollo dei telecomandi LEGO (pubblicate da LEGO stessa, e reperibili ad esempio sul sito di Philippe “Philo” Hurbain) per rendere la libreria IRremote per Arduino capace di emulare i telecomandi LEGO, quindi useremo il protocollo del telecomando dei treni per comandare il nostro, senza modificare nulla nel telecomando, nel ricevitore o nel motore.

L’ostacolo maggiore è l’individuazione e l’allineamento alla bobina di carica Qi-Charger: non c’è altro modo per capire se le bobine sono allineate che controllare se dalla bobina ricevente escono i 5V. O almeno non c’è un modo semplice. Inoltre, cosa non da sottovalutare, ci possono volere fino a tre secondi dal momento in cui le bobine sono allineate al momento in cui arrivano i 5V in uscita dalla bobina ricevente. Abbiamo quindi bisogno prima di un sistema che ci avverta quando siamo nelle vicinanze della bobina di carica e di un modo per allineare le due bobine lentamente fino ad avere i 5V in uscita.

Dopo aver escluso un sensore di prossimità come quello utilizzato nell’automazione di base, avrebbe imposto troppe limitazioni alla configurazione del circuito ferroviario, tentato con un sensore di colori TCS3200, troppo sensibile alle variazioni delle condizioni di illuminazione, nonostante i LED integrati, e troppo ingombrante da piazzare sotto il locomotore, alla fine ho tentato con un sensore magnetico ad effetto Hall, e si è rivelata la soluzione migliore, a patto di usare magnetini al Neodimio di dimensione ridotta, anche se piuttosto potenti.

Per l’occasione ho fatto qualche altro test sulle batterie al Litio per individuare il metodo migliore per capire la carica rimanente, e ne è scaturito un altro grafico. La soluzione è misurare la tensione della batteria senza carico, o con un carico ridotto, cosa che si può fare agevolmente nel momento in cui il treno si ferma per cercare la bobina di ricarica.

Li-ion e Li-po a confronto

La differenza principale fra gli accumulatori cilindrici (tipo 18650, detti Li-ion) e quelli piatti (tipici dei droni, detti Li-po) è che in questi ultimi la tensione a vuoto rimane sempre sopra i 3,6V per calare bruscamente ad accumulatore scarico, mentre gli accumulatori 18650 anche dopo che la tensione scende sotto i 3,4V possiedono ancora parecchi minuti di autonomia, quindi non è possibile basarsi sulla tensione a vuoto per definire la carica rimanente.

Di contro, misurare la tensione sotto carico può essere poco indicativo perché il valore letto dipende da molti fattori differenti, fra cui il carico, la resistenza interna, la capacità totale. Fra l’altro, dato che i treni LEGO usano il metodo PWM per modulare la tensione di alimentazione del motore e definire la velocità di rotazione, i valori letti hanno delle vistose fluttuazioni, come si vede dal grafico sotto, per via del modo in cui è erogata la corrente, ossia ad impulsi.

Il comportamento sotto carico (blu) a confronto con i valori letti a vuoto (rosso)

Questo succede perché le letture dei valori possono capitare casualmente nel momento in cui il motore riceve un impulso o nell’intervallo fra due impulsi, ed i due valori differiscono abbastanza. Anche facendo la media di più letture, i valori risultano abbastanza instabili. A vuoto, invece, le letture sono abbastanza affidabili e stabili.

Quindi rimane il problema di come determinare il livello di carica, cosa per nulla facile. Come sempre, la strategia migliore è andare a vedere le specifiche delle batterie e la documentazione di chi conosce molto bene gli accumulatori al litio. Da qui scaturisce che in teoria un accumulatore al litio ha vita lunghissima se si mantiene la carica fra il 65% ed il 75%: in questa situazione la capacità dell’accumulatore non diminuisce di molto anche dopo 8000 ricariche, rimanendo al di sopra del 90%.

Dai grafici sopra appare evidente che almeno su accumulatori “nuovi” ci sia una certa coincidenza dei valori di tensione letti a vuoto fra Li-Ion e Li-po, per cui sfrutteremo questa caratteristica per mantenere le batterie dentro limiti di carica e scarica adeguati a garantirne la massima vita utile.

Lo schema elettronico

Ci sono due schemi, uno per l’Arduino Nano ed uno per il Digispark. Per comodità, guarderemo lo schema con il microcontroller Digispark, ma al netto dei differenti piedini del controller usati, lo schema è assolutamente identico.

Il microcontroller Digispark
Un Arduino Nano

Partendo dalla sezione in basso a sinistra abbiamo il blocco di alimentazione con la batteria al Litio, il modulo di carica TP4056, il modulo elevatore di tensione MT3608 e il connettore per la bobina ricevente Qi-Charger. Praticamente questo blocco è identico a quello realizzato con la carica wireless. Vi sono aggiunti una resistenza (R3) da 10kΩ ed un condensatore di filtro (C3), che portano la tensione della batteria (Vbat) fino al piedino P2 del microcontroller, un ingresso di lettura analogico, per poter leggere lo stato della batteria.

Una seconda resistenza (R1) da 1kΩ porta la tensione di carica (Vcharge) al piedino P4 del microcontroller. Dato che su questo collegamento la tensione può avere solo due valori, 0V quando le bobine di carica non sono allineate e 5V quando lo sono, è sufficiente una lettura digitale: verrà letto “1” logico quando è presente la tensione di carica, ossia quando le bobine di carica sono allineate.

Il sensore ad effetto Hall

L’uscita del modulo MT3608 alimenta il microcontroller, che ha a bordo un regolatore a 5V e fornisce alimentazione per i due componenti aggiuntivi: il sensore Hall A3144 e il LED multicolore programmabile WS2812B (di cui parleremo fra poco). Il sensore ad effetto di Hall quando rileva un campo magnetico cortocircuita verso massa l’uscita, per cui la colleghiamo al piedino P3 del microcontroller. Il piedino P3 sarà configurato internamente al microcontroller per avere una resistenza collegata al positivo di alimentazione, quindi sarà tenuto a livello logico “1”, e commuterà a “0” quando rileverà un campo magnetico.

Il piedino P1 del microcontroller (il 3 nell’Arduino) è collegato ad un LED infrarosso, che sarà utilizzato per impartire i comandi al ricevitore Power Functions. Il valore della resistenza R2 è di 390Ω, piuttosto alto, perché non serve grande potenza: il LED sarà praticamente attaccato alla cupoletta del ricevitore Power Functions. Anzi, se fosse troppo potente l’emissione del LED potrebbe interferire con altri treni nel diorama.

Una coppia di LED NeoPixel™ di tipo SMD

Il LED WS2812B è un NeoPixel™, programmabile usando un solo filo. Può definire un qualsiasi colore usando 24 bit, 8 per ogni colore. Lo useremo come indicatore visivo, un colore per ogni stato del microcontroller. E’ opzionale, e può essere omesso senza alcun impatto sulla funzionalità del circuito nel suo complesso. Se lo omettiamo possiamo anche togliere R4 e C4, necessari per evitare l’arrivo di disturbi sull’ingresso di comando del LED e dall’alimentazione a 5V.

Questo a grandi linee il funzionamento del circuito. Quello con l’Arduino Nano è assolutamente identico, a parte la dimensione fisica e la presenza di altri piedini, che però non utilizzeremo.

Il protocollo del telecomando

Spendiamo qualche parola per il protocollo del ricevitore ad infrarossi Power Functions, servirà a capire alcune parti del programma. Il ricevitore è pensato per funzionare con sostanzialmente due modalità:

  • quella del telecomando #58122 tipico dei set Technic, con le due levette a tre posizioni: centro (posizione di riposo), avanti e indietro. In questo caso il trasmettitore deve inviare continuamente impulsi al ricevitore, che tiene attivo il motore corrispondente fino a quando non lasciamo la levetta, che ritorna in posizione di riposo. Questa modalità ha in tutto tre velocità dei motori collegati al ricevitore: tutto avanti, fermo, tutto indietro.
  • quella del telecomando #64277 tipico dei treni, con i due commutatori rotativi e i due pulsanti di arresto. Il trasmettitore invia soltanto il comando in caso di variazione dei controlli, ed il ricevitore mantiene lo stato fino a quando non arriva un differente comando. Questa modalità ha un controllo più esteso dei motori, permettendo sette differenti velocità in avanti, sette all’indietro e lo stop, oltre alla “frenata”, una modalità in cui il motore viene alimentato in modo da esercitare una azione frenante, a differenza di quando semplicemente si toglie la corrente ed il treno si ferma per inerzia. In realtà le velocità utilizzabili sono meno, dalla 2 alla 7, con la 1 il motore pare riceva troppa poca energia per mettersi in moto.

Utilizzeremo quindi la seconda modalità, specifica per i treni.

Il funzionamento del treno

Per poter funzionare, il treno richiede che il circuito ferroviario sia configurato in un certo modo:

  • Circuito chiuso, non importa quanto complesso o lungo, basta che sia chiuso
  • In un punto dove il circuito è rettilineo va posizionata la bobina di ricarica, ad esempio di fronte ad una stazione, utilizzando uno dei metodi proposti in precedenza.
  • Poco prima della posizione della bobina, tipicamente a due segmenti di binario dritto di distanza secondo il senso di marcia del treno, va piazzato un magnetino ad indicare la prossimità della bobina stessa

Il comportamento del treno è ciclico:

  • Supponendo di avere la batteria carica all’avvio, il treno marcia normalmente per un tempo prefissato alla velocità di crociera.
  • Trascorso quel tempo, il treno si mette alla ricerca della posizione del magnetino, riducendo leggermente la velocità per non mancarlo.
  • Trovato il magnetino, riduce ulteriormente la velocità fin quasi a fermarsi e cerca la bobina di ricarica, che dovrebbe essere poco distante
  • Trovata la bobina di ricarica, si ferma per un tempo prefissato, se la batteria non è scarica.
  • Se invece la batteria è scarica, si ferma sulla bobina di ricarica fino alla carica completa
  • Terminato il tempo di ricarica, il treno si riavvia gradualmente e ritorna alla velocità di crociera.

I tempi e le velocità sono definiti con delle costanti nella parte iniziale del programma, e possono essere modificati a piacere.

Il software

Il programma è, semplificando al massimo, una macchina a stati molto semplice.

In testa al programma c’è una sezione di configurazione che deve essere modificata per adattarla alle nostre esigenze. I valori che ho inserito sono tali da andare perfettamente in molte situazioni, per esempio utilizzando i treni originali LEGO. Se però vogliamo motorizzare un nostro treno, o il circuito è particolare, è necessario metterci le mani e adattare i valori alle nostre esigenze. Vediamo ora il funzionamento del programma, e sicuramente dopo il significato delle costanti sarà meno oscuro.

All’accensione il sistema rimane per quindici secondi nello stato STARTUP, in cui rimane fermo (ci consente di aggiustare le cose prima di partire a razzo). In questa fase se il sensore magnetico rileva il magnete il LED di segnalazione si accende con luce bianca. Questo è utile per capire se il magnete è posizionato correttamente e viene rilevato dal treno.

Allo scadere del tempo, viene controllato se si trova ancora sopra il magnete, ed in questo caso passa allo stato MANUAL, ossia il microcontroller si disattiva ed il treno è utilizzabile come un normale treno Power Functions. Se non rileva il magnete, fa un controllo sulla presenza della tensione di carica, ossia se il treno si trovi allineato con la bobina Qi-Charger, in quel caso procede alla carica completa della batteria (vedi sotto lo stato FULL_CHARGE). Questo è utile quando il treno dovesse trovarsi con la batteria scarica e lo vogliamo forzare a caricarla del tutto prima di partire.

Se invece non rileva la presenza della tensione di carica, controlla il livello di carica della batteria, e nel caso sia sufficiente, passa allo stato di marcia normale (RUN) e si avvia accelerando gradualmente. Se invece la carica della batteria è troppo bassa, rimane fermo e passa allo stato di ALARM.

Passiamo ad elencare gli stati di funzionamento:

  • STARTUP – è il tempo di attesa iniziale definito con la costante TR_STARTUP in secondi, in cui il treno rimane immobile in attesa. Se al termine di questo tempo rileva di essere sopra il magnete, passa allo stato MANUAL, se invece rileva di essere sopra la bobina di ricarica passa allo stato CHARGE_FULL, altrimenti passa allo stato RUN se la batteria non è scarica. Se la batteria è scarica passa allo stato ALARM.
  • RUN – è la marcia normale del treno alla velocità TR_FULLSP, ossia la velocità di crociera massima. Consiglio di usare i valori 6 o 7 (7 è il massimo). Non viene letto alcun sensore, la durata della marcia dipende solo dal valore impostato nella costante TR_RUNTIME in secondi. In questo stato il LED di stato è verde brillante.
  • SEARCH – Trascorso il tempo TR_RUNTIME, il treno passa alla ricerca del magnetino, leggendo il sensore ad effetto Hall. La velocità passa a TR_SRCSP (consiglio 4 o 5) ed il LED diventa blu. Se non trova il magnetino, dopo un intervallo di tempo pari al doppio della marcia normale (TR_RUNTIME) passa allo stato di ALARM e si ferma.
  • LOCATE – Trovato il magnetino, il treno passa alla ricerca della bobina di carica. Avanza a piccoli scatti alla velocità TR_SLOWSP (consiglio 2 o 3) controllando la presenza della tensione di carica. Il LED è celeste. Se trascorre il tempo TR_PADSRC senza trovare la bobina torna allo stato SEARCH. Se per tre volte esegue il ciclo SEARCH/LOCATE senza trovare la bobina di carica, torna allo stato RUN se la batteria non è scarica, altrimenti passa ad ALARM e si ferma.
  • CHARGE – Trovata la bobina di carica, il treno rimane fermo per il tempo minimo definito da TR_CHARGE, con il LED di colore viola. Il tempo viene aumentato o diminuito in funzione della tensione della batteria a vuoto: se tende a scendere, il tempo di ricarica viene aumentato, se invece supera una certa soglia viene diminuito, proprio per mantenere la batteria entro i limiti di capacità di cui parlavamo sopra. Terminata la carica, torna allo stato RUN ed alla velocità di crociera. Se invece la batteria è scarica passa allo stato CHARGE_FULL
  • CHARGE_FULL – quando la batteria è scarica, il treno si ferma per la ricarica completa, il LED passa al colore arancio. Rimane in questo stato fino a che la tensione della batteria non supera i 4,1V circa. Poi passa allo stato CHARGE_FULL2
  • CHARGE_FULL2 – Per assecondare il profilo di carica delle celle al litio, terminata la prima parte della carica, in cui la tensione cresce fino ad un certo valore, si passa alla seconda fase, in cui la tensione è pressoché costante. Il LED è giallo. Non avendo modo di misurare lo stato della carica direttamente, il treno rimane in questo stato per un tempo fisso e predeterminato definito da TIME_FULLCHARGE. Se dovesse succedere di esagerare con il tempo, non succede niente, semplicemente perché il circuito TP4056 ferma la carica quando la batteria è piena, quindi non c’è pericolo di rovinare nulla.
  • MANUAL – In questo stato il treno diventa a tutti gli effetti un treno Power Functions: il microcontroller rimane inerte e non cambia più il proprio stato, e possiamo manovrare il treno con il telecomando. Per riportarlo in modalità automatica occorre resettare il microcontroller: nel caso dell’Arduino Nano, c’è il pulsantino di Reset per questo, mentre nel Digispark occorre togliere alimentazione. In questo stato il LED è verde, meno luminoso dello stato RUN.
  • ALARM – Se per qualche motivo il treno rileva che la batteria ha bisogno di essere caricata e non riesce a trovare il magnetino o la bobina di ricarica, per non rovinare la batteria scaricandola troppo passa a questa modalità, fermandosi e segnalando con il LED rosso la situazione di blocco. Il treno è manovrabile con il telecomando Power Functions, e possiamo portarlo sopra la bobina di ricarica: in questo caso il microcontroller passa allo stato CHARGE_FULL.

La configurazione

Vediamo i parametri di funzionamento del software e il loro significato.

  • MOTOR – Può essere RED o BLUE, tutto maiuscolo. Definisce il canale usato nel ricevitore infrarosso Power Functions per il controllo del motore del treno. Predefinito è BLUE.
  • IRCHANNEL – Definisce il canale del ricevitore Power Functions. Può essere 0, 1, 2 o 3, e corrispondono rispettivamente ai canali 1, 2, 3 e 4. Insieme al valore MOTOR sopra permette di differenziare il treno controllato, specialmente per evitare interferenze con i treni vicini. Se abbiamo più di un treno controllato automaticamente è consigliabile usare un canale differente per ogni treno. Predefinito è 0
  • TR_RUNTIME – E’ il tempo in secondi per cui il treno rimane nello stato RUN. Se ad esempio abbiamo un circuito molto corto e vogliamo che il treno si fermi ad ogni giro alla stazione abbasseremo questo valore al di sotto del tempo in cui il treno compie un giro. Predefinito è 50 secondi.
  • TR_CHARGE – E’ il tempo minimo di sosta per ricarica sulla bobina Qi-Charger. Il valore corretto è dipendente da quante energia viene consumata dal treno durante il TR_RUNTIME. Se il treno è molto pesante, servirà un tempo di permanenza più lungo. Il software ha un sistema di autoregolazione per cui aumenta o diminuisce il tempo di ricarica in funzione del consumo, portandolo fino al triplo. Se vediamo che il treno aumenta il tempo di fermata, vuol dire che il consumo è elevato, quindi il treno pesa troppo, o che la batteria al Litio si sta invecchiando. Predefinito è 30 secondi. I valori scelti qui sono tali che il treno merci #60052 con una batteria Li-po da 1200mAh gira per ore senza cambiare il tempo di ricarica.
  • TR_FULLSP – E’ la velocità di crociera del treno. Può valere da 2 (minimo) a 7 (piena velocità). Predefinita è 6.
  • TR_SRCSP – E’ la velocità assunta dal treno quando è in ricerca del magnete che indica la prossimità della bobina di ricarica. I valori vanno sempre da 2 a 7. Consigliati 4 o 5, predefinito è 5. Nei test da me fatti, il treno rileva il magnete anche alla massima velocità, per precauzione ho preferito abbassare leggermente la velocità del treno. Anche qui molto dipende dal treno e dal suo peso.
  • TR_SLOWSP – E’ la velocità assunta dal treno quando fa i piccoli aggiustamenti per allinearsi con la bobina di ricarica. Dato che procede a “impulsi”, se il treno ha un certo peso, potrebbe essere necessario aumentare questo valore. Predefinita è 2 (la minima). Anche qui è calibrata per il treno merci, ed a ogni “impulso” il treno avanza di poco meno di un centimetro.
  • TR_STARTUP – E’ il tempo che passa da quando il treno è alimentato a quando inizia il ciclo marcia/ricarica, in secondi. In questo tempo iniziale è possibile effettuare una ricarica completa o didattivare del tutto l’automatismo, come spiegato sopra nella descrizione del funzionamento. Predefinito a 15 secondi.
  • TIME_FULLCHARGE – Come spiegato sopra, questo è il tempo in cui viene effettuata la ricarica completa a tensione costante. Il tempo predefinito equivale a 30 minuti. Considerando che la corrente di ricarica è di 1A massimo, possiamo fare un calcolo approssimato dicendo che ogni ora equivalgono a 1000mAh di capacità, se l’accumulatore è da 2000mAh in 60 minuti la carichiamo a circa metà capacità. Usando un accumulatore da 1200mAh in 30′ arriviamo anche qui a circa metà capacità. Più semplicemente basta aggiungere 30′ ogni 1000mAh di capacità della batteria, per mantenere l’accumulatore nella fascia 50-80% al fine di massimizzare la vita utile.
  • TR_PADSRC – E’ il tempo in secondi per cui il treno cerca l’allineamento con la bobina di carica. Se entro questo tempo non la trova, come spiegato sopra,, torna allo stato di SEARCH. Predefinito è 15 secondi.

Questi sono i parametri configurabili ed il loro significato.

Ci sono anche altri parametri, ma sono calibrati per il circuito così com’è ora e per le librerie software impiegate. Se si intende cambiarli occorre sapere dove e come mettere le mani, pena il non funzionamento, o peggio il guasto.

Nella prossima parte vedremo i prototipi e le soluzioni costruttive adottate.
(Fine della prima parte)