MiniUPS: continuità per il lampone

Sappiamo quanto importante sia assicurare il funzionamento continuativo di schede elettroniche Single Board Computer come Raspberry Pi, soprattutto per evitare perdite di dati o danni alle unità di storage; per questo esistono dispositivi chiamati UPS, realizzati anche in versione “hat” per le nostre Raspberry Pi. Un esempio lo trovate in queste pagine, dove proponiamo una scheda che funge da gruppo di continuità, garantendo l’alimentazione grazie a una batteria di backup LiPo che mantiene in carica, nonché a chiudere i processi in esecuzione per spegnere la Raspberry Pi laddove l’autonomia fornita dalla batteria sia in esaurimento.
Il nostro MiniUPS si presta alla realizzazione di sistemi di alimentazione per sistemi elettronici che richiedano un backup energetico per prevenire la perdita di dati come, la Raspberry Pi (in tutti i suoi allestimenti e versioni) oppure Arduino o più in generale per qualsiasi sistema elettronico per il quale sia richiesto un funzionamento affidabile h24.
La tensione di alimentazione principale è compresa tra 3,9 e 14 Vcc; come tensione nominale sono consigliati 5V±5% mentre la corrente che l’alimentatore deve fornire dev’essere almeno 3A, fornibile su un apposito morsetto a vite presente sulla scheda. Nel caso in cui l’alimentatore non fosse in grado di erogare tutta la corrente necessaria, la scheda, entro certi limiti, è comunque in grado di compensare la riduzione di tensione diminuendo l’assorbimento di corrente in ingresso.
Il processo di carica della batteria può portare a notevole generazione di calore, il sistema si autoregola gestendo la corrente di carica in modo da mantenere la temperatura all’interno del campo operativo dello stadio di carica. La tensione di batteria è poi innalzata al livello della tensione di alimentazione del Raspberry Pi mediante uno stadio switching DC-DC in topologia boost che garantisce in uscita una tensione stabilizzata nominale di 5V circa.
Il MiniUps è quindi una scheda di ricarica rapida intelligente per batterie LiPo a singola cella (1s) da 3,7V con corrente di ricarica massima da 3 A. Realizzata con un circuito stampato multistrato (4 strati) è dotata di un ingresso di accensione/spegnimento attivo basso ed è in grado di notificare al mondo esterno l’imminente spegnimento del carico. In aggiunta la scheda può essere interrogata attraverso bus I²C per conoscere i parametri di funzionamento del sistema (presenza o assenza della tensione principale, tensione della batteria, tensione di ingresso, allarmi, eccetera), inoltre permette anche di salvare dati utente su una memoria EEPROM integrata nella scheda stessa ed attraverso alcuni diodi led fornisce una rappresentazione visuale dello stato di funzionamento del sistema.
Oltre alle dotazioni legate alle funzionalità come UPS la scheda integra un modulo RTC (DS3231S) e relativa batteria (CR1025) connesso al bus I²C della Raspberry Pi ed un driver RS232 (MAX3232) connesso direttamente alle linee RX-TX della Raspberry Pi. Lo schema a blocchi di Fig. 1 dettaglia la configurazione hardware della scheda UPS.

Fig. 1

Nelle Raspberry Pi, a livello di risorse GPIO la scheda occupa una sola linea dedicata (pin 11, relativo al GPIO17) identificata con RPIOFF, in serie alla quale è stato posto un resistore di limitazione della corrente da 1kW, utilizzata per avvisare la Raspberry Pi o un generico carico che il sistema a breve verrà spento (entro 60s). Tale linea consente di salvare i dati delle applicazioni e permette uno spegnimento pulito del sistema, senza perdita di dati, eliminando il rischio di corrompere il contenuto della SD-Card conseguente ad un’interruzione improvvisa della tensione di alimentazione. Per intercettare lo stato di questa linea è possibile installare un servizio che avverta il sistema di questo evento oppure controllarla in polling direttamente all’interno dell’applicazione utente, a corredo, per questo scopo, è fornito uno script Python pronto per essere utilizzato. Oltre a questo si hanno numerosi esempi di utilizzo del bus I²C e della porta seriale attraverso altrettanti script sempre in Python direttamente scaricabili dal repository GitHub accessibile da https://github.com/Italsensor/RPI-MINI-UPS-R0.
Tutti gli ingressi e le uscite della scheda possono essere utilizzati saldando direttamente sulle piazzole oppure montando dei connettori passo 2,54 mm.
Nella Tabella 1 sono riportate le caratteristiche della scheda e nella Tabella 2 quelle della batteria LiPo in dotazione (quella di serie).

 Tabella 1

Tabella 2

A titolo puramente indicativo, in riferimento a delle prove effettuate con una Raspberry Pi3B+ Rev 1.3, sistema operativo Raspbian 10 (buster), desktop grafico, browser aperto su due pagine di YouTube con filmati in esecuzione, LibreOffice con applicazione Writer aperta, gioco precaricato Soccer in esecuzione, mouse e tastiera USB connesse, monitor HDMI connesso e partendo da una condizione di batteria LiPo carica, l’autonomia complessiva risulta mediamente di 10 minuti (la tensione della batteria è pari a circa 3,6 V).
Con la modalità UPS, al ripristino della tensione di alimentazione, il sistema riparte già dopo circa 1 minuto e 15”; la batteria, però, non è completamente carica, ma la tensione ai suoi capi, in presenza della tensione di alimentazione principale, è tale da permettere il superamento della soglia di accensione pari a circa 3,9 V.
Il connettore X1 della batteria (JST modello S3B-XH-A) si trova sul lato saldature della scheda, come proposto nella Fig. 2.

Fig. 2                          

Fig. 3

La relativa piedinatura è la seguente:
1 = +VBAT (positivo batteria);
2 = NTC (termistore NTC);
3 = 0V (negativo batteria).

La batteria proposta adatta al progetto è quella visibile nella Fig. 3: come vedete, dispone di un cavetto terminante con un connettore adatto a quello JST della scheda.
La piedinatura del connettore è corrispondente a quella del JST della scheda e i colori del cavetto sono: rosso per il positivo, nero per il negativo e bianco per il termistore che consente di monitorare la temperatura della cella LiPo.
Per quanto riguarda l’ingresso di alimentazione, il relativo connettore è una morsettiera a passo 5 mm (Fig. 4) della quale il contatto 1 è la massa (negativo) e il 2 il polo positivo.

Fig. 4

 

Fig. 5

La Fig. 5 propone una panoramica delle linee di I/O e delle segnalazioni della nostra scheda UPS.

Modalità di funzionamento

Il sistema può operare con due modalità distinte:

  • automatica (UPS mode);
  • manuale (desktop mode); quest’ultima è l’impostazione predefinita.

La scelta relativa alla modalità di funzionamento, da effettuarsi sempre a carico spento o non collegato, è definita dall’impostazione del livello di tensione presente sul pin 6 (MODE) del connettore utente J2; se lasciato aperto il sistema utilizza la modalità automatica, invece cortocircuitando il pin 6 con il pin 5 (0V) il sistema utilizza la modalità manuale. J2 è un header maschio da due file con 6 vie ciascuna passo 2,54 mm, la cui piedinatura è proposta nella Tabella 3; è quindi possibile utilizzare un jumper passo 2,54 mm per cortocircuitare tra loro i due pin di configurazione come in Fig. 6.

     

                         Tabella 3                                                                                              Fig. 6

La modifica della modalità di funzionamento deve essere effettuata sempre a carico non alimentato (led DL3 spento), si procede quindi con l’impostazione della modalità desiderata e si effettua il reset della scheda rimuovendo il ponticello tra i pin 1 e 2 e reinserendolo dopo alcuni secondi.
In alternativa la modalità si può modificare “on the fly” anche con sistema attivo, ma solo durante la fase di shutdown (durata 60 s), al termine dello shutdown il carico viene spento ed il sistema entra automaticamente nella modalità scelta.
La modalità UPS (accensione e spegnimento automatico in base alla tensione di alimentazione) si imposta lasciando aperto il pin 6 del connettore J2.
Permette di gestire in modo automatico la linea di alimentazione del carico proprio come accade con un UPS tradizionale: in presenza della tensione di alimentazione principale, la scheda attiva automaticamente il processo di ricarica della batteria e quando la tensione di quest’ultima raggiunge i 3,9V provvede ad alimentare il carico. Qualora la tensione principale venga a mancare il sistema entra nella modalità di backup, se la tensione di batteria diventa minore o uguale a 3,6V si ha l’attivazione della linea di shutdown RPIOFF (attiva alta), trascorsi ulteriori 60 s il sistema procede con la disconnessione del carico. Il carico verrà nuovamente alimentato solo al ritorno dell’alimentazione principale e con una tensione della batteria di backup maggiore o uguale a 3,9V.È possibile interrompere questa modalità di funzionamento cortocircuitando il pin 4 con il pin 3 (0V) del jumper J2; in questo modo si avvia la sequenza di spegnimento ed è possibile -nel relativo intervallo di tempo- mantenere aperto il pin 6 del connettore J2 (si ritorna automaticamente alla modalità automatica) oppure cortocircuitarlo con il pin 7 (0V) per attivare, trascorsi i 60 s dello shutdown, la modalità di funzionamento manuale.

Modalità manuale

Accensione e spegnimento attraverso pulsante esterno si impostano inserendo un jumper passo 2,54 mm nella terza posizione del connettore J2 (il pad 5 ed il pad 6 sono cortocircuitati) secondo quanto mostrato nella Fig. 7.

Fig. 7

Questa modalità permette di accendere e spegnere la Raspberry Pi, oppure una generica scheda embedded o più in generale un carico generico, in modo controllato dall’utente, attraverso un pulsante esterno normalmente aperto oppure un contatto pulito tra il pin 4 ed il pin 3 (0V) del connettore J2.
Il microcontrollore presente sulla scheda sovraintende le operazioni di accensione e spegnimento e controlla costantemente il valore della tensione di batteria. Il diodo LED DL3 di colore rosso si accende segnalando la presenza della tensione di alimentazione sui pin 2 e pin 4 del connettore CN2. Nel caso in cui il carico sia costituito da una Raspberry Pi dovrà accendersi anche il diodo LED DL2 indicando la presenza della tensione 3,3V generata dalla Raspberry Pi stessa.
L’accensione del carico si effettua connettendo tra loro il pin 4 ed il pin 3 del connettore J2 per un intervallo di tempo di almeno 3 s (la tensione di batteria deve comunque essere maggiore o uguale a 3,9V).
Lo spegnimento si effettua in modo analogo connettendo tra loro il pin 4 ed il pin 3 del connettore J2 per un intervallo di tempo di almeno 5 s. Non appena la scheda entra nella fase di spegnimento viene attivata la linea RPIOFF che può essere utilizzata, ad esempio nel caso in cui il sistema alimenti una scheda Raspberry Pi, per avviare il processo di shutdown evitando così una possibile perdita di dati legata ad una interruzione improvvisa dell’alimentazione, trascorsi 60s la scheda interrompe l’alimentazione al carico rimanendo in stand-by.
Se la tensione di batteria dovesse diventare inferiore a 3,6V, indipendentemente dallo stato del pulsante di accensione/spegnimento, la scheda avvia automaticamente la procedura di shutdown attivando la linea RPIOFF; in seguito attende 60s ed al termine provvede a sezionare l’alimentazione del carico, infine il segnale RPIOFF è riportato al livello basso ed il sistema ritorna nello stato di attesa fino a quando la tensione di batteria non risulta maggiore di 3,9V, da questo momento in poi è possibile riaccendere il carico utilizzando il pulsante.
In entrambe le modalità di funzionamento la batteria LiPo è sempre al sicuro, il sistema disattiva automaticamente il carico quando la tensione risulta inferiore a 3,6 V avviando la procedura di spegnimento proprio come se questa fosse stata richiesta manualmente dalla linea di ingresso di accensione/spegnimento, in questo modo il carico, se necessario, può effettuare uno shutdown in sicurezza, senza perdita di dati.
Il modulo è dotato di RTC integrato e relativa batteria tampone (CR1025), la batteria si installa sul lato saldature del circuito stampato nell’apposito alloggiamento, come visibile in Fig. 8.

Fig. 8

È importante inserire la batteria in modo tale che il polo negativo sia a contatto con il circuito stampato ed il polo positivo a contatto con l’alloggiamento metallico, inserire la batteria a rovescio può danneggiare irrimediabilmente il modulo RTC.

Preparazione e configurazione della scheda

Il passo successivo prevede la configurazione di alcune caratteristiche della Raspberry Pi e l’installazione di tool specifici che potranno essere utilizzati per la lettura del modulo RTC; ecco la procedura.
1) A Raspberry Pi spenta, se non si dispone di una connessione di rete, collegare un monitor HDMI ed una tastiera su una porta USB libera. Se sulla Raspberry Pi è attivo il servizio SSH ed è disponibile una connessione di rete, ci si potrà connettere ad essa da un qualsiasi PC dotato di terminale PuTTY, mediante protocollo SSH; in questo caso non è quindi necessario collegare direttamente alla Raspberry Pi monitor e tastiera. Si inserisce quindi, nell’apposita sede, una microSDHC con il sistema operativo desiderato precaricato.
2) Verificare sulla scheda UPS che la modalità di funzionamento sia quella manuale (configurazione predefinita) in seguito inserire la scheda UPS nel connettore GPIO della Raspberry Pi.
3) Collegare la batteria LiPo alla scheda attraverso l’apposito connettore X1 presente sul lato saldature della scheda stessa.
4) Inserire la scheda nel connettore GPIO della Raspberry Pi.
5) Inserire il jumper di reset del microcontrollore nel connettore J2 come riportato nella Fig. 5: il diodo led DL4 potrebbe iniziare a lampeggiare.
6) Si applica al connettore J1 la tensione di alimentazione principale, si attende che la batteria abbia completato il ciclo di carica (il LED DL1 da verde fisso si spegne) e attraverso un pulsante normalmente aperto connesso su J2 tra il pin 4 ed il pin 3 (0V) da tenere premuto per almeno 3 secondi, si attiva la linea di accensione: la Raspberry Pi deve accendersi. I LED di stato DL2 e DL3 (entrambi di colore rosso) devono essere accesi e fissi, indicando la presenza della tensione a 5V e 3.3V sul connettore GPIO della Raspberry Pi.
7) Completato il boot, si effettua il login con credenziali root oppure come utente normale; in quest’ultimo caso si dovrà ricordare di premettere ai vari comandi riportati di seguito il comando sudo per permetterne l’esecuzione con privilegi di amministratore.
8) Si verifica se è stato attivato nel sistema in uso l’interfaccia I²C attraverso l’utility di configurazione del Raspberry raspi-config scrivendo nel terminale il seguente comando seguito dalla pressione del tasto Invio:

sudo raspi-config

Utilizzando i tasti freccia ci si posiziona sulla riga Interfacing Options (Fig. 9) e si preme il tasto invio; le immagini relative alla configurazione qui riportate si riferiscono ad una Raspberry Pi 4 model B rev 1.1. con sistema operativo buster e kernel Linux 4.19.75-v71+; per sistemi operativi differenti le opzioni potrebbero trovarsi in altri punti del menù di configurazione, ma saranno comunque sempre presenti e facilmente identificabili. Utilizzando i tasti freccia si ricerca l’opzione I²C e si preme Invio (Fig. 10).

Fig. 9

 

Fig. 10

Sempre mediante i tasti freccia si seleziona Yes e si preme il tasto Invio; si preme nuovamente il tasto Invio per confermare la selezione. Il sistema ripresenta la finestra iniziale, utilizzando il tasto Tab (tabulazione) ci si sposta sul pulsante Finish e si preme Invio per uscire dal programma di configurazione. Si procede con l’installazione del package “i2c-tools”:

sudo apt-get update
sudo apt-get install i2c-tools

questo pacchetto permette di utilizzare una serie di strumenti utili per la gestione e la diagnostica del bus I²C della Raspberry Pi.
10) Lo scopo del modulo RTC è di fornire data ed ora esatti anche in assenza di connessione verso un server NTP, è quindi importante operare in modo che la lettura della data e ora venga effettuata al boot del sistema, questo è possibile andando a modificare il file /boot/config.txt.
Nel caso delle versioni più recenti di sistema operativo basate su systemd (da Jessie in avanti – 25/04/2015), utilizzando l’editor vi, si scriverà il seguente comando:

sudo vi /boot/config.txt

Scorrendo fino alla fine del file si aggiunge la seguente riga:

dtoverlay=i2c-rtc,ds3231

A questo punto è possibile salvare le modifiche apportate al file ed uscire da vi premendo il tasto: e scrivendo wq seguito dalla pressione del tasto Invio. Al prossimo riavvio l’ora sarà aggiornata automaticamente leggendola direttamente dal modulo RTC.
11) Si disabilità il modulo fake hwclock (utilizzato dal kernel per simulare il comportamento di un RTC reale nel caso in cui il sistema non sia dotato di una connessione di rete che permetta di avere data ed ora sempre aggiornate) per evitare possibili interferenze con il modulo hwclock:

sudo apt-get -y remove fake-hwclock

Si disattiva anche l’avvio automatico del servizio al boot del sistema, nel caso di sistemi operativi più datati basati ancora su SysV si utilizza il seguente comando:

sudo update-rc.d -f fake-hwclock remove

Per i sistemi più recenti basati invece su systemd (disponibile a partire dalla versione Jessie) si utilizza invece il seguente comando:

sudo systemctl disable fake-hwclock

12) Utilizzando il proprio editor preferito (in questo esempio sarà utilizzato vi) aprire il file /lib/udev/hwclock-set quindi:

sudo vi /lib/udev/hwclock-set

scorrendo con i tasti freccia verso il basso si cercano nel file le seguenti righe:

if [ -e /run/systemd/system ] ; then
exit 0
fi

commentandole inserendo il carattere # ad ogni inizio riga, ottenendo quindi:

#if [ -e /run/systemd/system ] ; then
#exit 0
#fi

Scorrendo ancora verso la fine del file si commentano le righe come riportato nella Fig. 11 (per maggiori informazioni vedere il manuale relativo allo strumento hwclock).

Fig. 11

Si procede salvando in modo permanente le modifiche apportate al file ed uscendo da vi premendo il tasto: e scrivendo wq seguito dalla pressione del tasto Invio.
13) Si riavvia la Raspberry Pi con il seguente comando:

sudo reboot

seguito dalla pressione del tasto Invio.
14) Si effettua nuovamente il login e si verifica se il bus I²C risulta effettivamente abilitato dal kernel utilizzando il comando:

ls /dev/i2c*

Se si ottiene in risposta /dev/i2c-1 il bus I²C risulta correttamente configurato.
15) Per verificare la comunicazione con il modulo RTC si scrive nella finestra del terminale il seguente comando seguito dalla pressione del tasto Invio:

sudo i2cdetect -y 1

Se si ottiene la rappresentazione di Fig. 12 , la quale indica che la scheda (0x08) e il modulo RTC (UU sull’indirizzo 0x68) sono correttamente identificati sul bus I²C.

Fig. 12

16) Il modulo RTC è correttamente raggiungibile, con la Raspberry Pi connessa ad Internet si verificano le impostazioni di data ed ora utilizzando il comando:

sudo date

In assenza di connessione di rete, la data potrebbe non essere corretta; per impostarla manualmente si può utilizzare il comando:

sudo date -s “Wed Apr 28 10:27:00 CEST 2021”

Controllata la data si procede con lo scrivere nel modulo RTC la data ed ora corrente utilizzando il comando:

sudo hwclok -w

in seguito si rilegge la data memorizzata nel modulo RTC con il comando:

sudo hwclok -r

La data e l’ora devono corrispondere alla data e ora restituita attraverso l’utilizzo del comando date, potrebbero esserci alcuni secondi di differenza associati alla tempistica di esecuzione dei comandi.

Qualora ci fossero dei messaggi di errore conseguenti all’esecuzione dei comandi sopra riportati, è probabile che ci siano dei problemi hardware con il modulo RTC, in questo caso si suggerisce di utilizzare una scheda differente e ripetere le operazioni sopra elencate.

Organizzazione registri per l’interfacciamento I²C-Bus

La scheda si interfaccia su bus I²C esponendo all’utente una serie di registri, il cui accesso può essere effettuato dal bus I²C della Raspberry Pi oppure da qualsiasi altro sistema che sia in grado di comunicare su bus I²C. I registri sono descritti nella Tabella 4. La scrittura in un’area non permessa oppure di sola lettura non eseguirà l’operazione richiesta ed il contenuto della cella indirizzata non sarà quindi alterato; per la lettura su aree riservate potrebbero essere restituiti dei valori che non riflettono il reale contenuto della cella indirizzata.

Tabella 4

Per una descrizione dettagliata dei singoli registri e del loro significato (per alcuni i singoli bit devono essere decodificati secondo determinati criteri) si rimanda al manuale d’uso del MiniUPS, scaricabile direttamente dal repository GitHub per la scheda, il cui link è riportato all’inizio dell’articolo.

Lettura registro da BUS I²C

Per la lettura di un registro attraverso la shell bash della Raspberry PI si può utilizzare il seguente comando (può essere eseguito anche senza privilegi di amministratore) seguito dalla pressione di Invio:

i2cget -y 1 0x08 <indirizzo_registro_hex> b

ottenendo in risposta il valore, espresso in esadecimale, del valore letto all’indirizzo specificato.
Se si dovesse ottenere in risposta Error: Read failed; questo può essere sintomo di un problema hardware nelle connessioni oppure nel caso in cui la lettura venga richiesta in corrispondenza di un reset del microcontrollore.

Scrittura registro da BUS I²C

Per la scrittura di un registro attraverso la shell bash del Raspberry PI si utilizza il seguente comando (può essere eseguito anche senza privilegi di amministratore) seguito dalla pressione del tasto Invio:

i2cset -y 1 0x08 <indirizzo_registro_hex> <valore_da_scrivere_hex> b

Lettura e scrittura su registro area utente della EEPROM

Si riporta un esempio di lettura, scrittura e successiva lettura per verifica della prima locazione di memoria dell’area utente sulla memoria EEPROM. Tutti i comandi sono seguiti dalla pressione del tasto Invio. Si inizia con la lettura del contenuto della memoria all’indirizzo 0x00:

pi@raspberrypi:~ $ i2cget -y 1 0x08 0x00 b
0x00

Si prova a scrivere, nella stessa locazione, il valore 128 ovvero 0x80 in esadecimale:

pi@raspberrypi:~ $ i2cset -y 1 0x08 0x00 0x80 b

si rilegge il contenuto della locazione appena scritta:

pi@raspberrypi:~ $ i2cget -y 1 0x08 0x00 b
0x80

Se si ottiene in risposta 0x80, questo conferma che il dato era stato effettivamente memorizzato nella locazione 0 all’interno dell’area EEPROM utente; se invece si ottiene un valore differente o un messaggio di errore è opportuno ricontrollare le connessioni e se i comandi sono stati inseriti con la sintassi corretta.

Conclusioni

Bene, per il momento ci fermiamo qui; nella prossima e conclusiva puntata spiegheremo come lavorare sul complesso Raspberry Pi – MiniUPS tramite degli script Python e in che modo possiamo gestire la porta seriale.

Download

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Menu