officinasottocasa › Elettronica
Allarme GSM Batteria Scarica e Mancanza Corrente via SMS
Ci è bastato dimenticarci di collegare la batteria della moto al mantenitore per ritrovarcela scarica e da buttare. Da lì l’idea di questo allarme GSM con Arduino Nano e SIM800L, che avvisa via SMS non appena la tensione scende sotto soglia: utile per la batteria di un mezzo fermo, ma con lo stesso principio anche per segnalare una mancanza di corrente su un impianto a 12V. Schema elettrico, codice completo e collaudo reale, tutto in questo articolo.
di Alessandro Grassi · · aggiornato il · 12 minuti di lettura
L’esigenza
Nella stagione invernale, tra feste e smart working, la moto è destinata a restare in garage più a lungo del solito, e questo può causare una scarica anomala della batteria — specialmente se ci si dimentica, come è successo anche a noi, di collegarla al mantenitore di carica.
A nulla è servito chiudere il recinto dopo la fuga dei buoi: la tensione era scesa a 6,8V e il caricabatteria/mantenitore non è riuscito a individuare né a ricaricare la batteria. La morale è che abbiamo dovuto comprarne una nuova.
Ma come capita spesso, abbiamo colto l’occasione di un guasto per sviluppare un progetto e un nuovo contenuto per il blog: ecco come nasce il nostro dispositivo di monitoraggio e allarme batteria via GSM, che invia un SMS di avviso non appena la tensione scende sotto soglia — utile tanto per la batteria di un veicolo fermo quanto, con gli stessi principi, per segnalare una mancanza di corrente su un impianto alimentato a 12V (ne parliamo più avanti, nelle FAQ).
(Se il vostro interesse è specificamente monitorare un blackout della rete elettrica di casa, l’approccio è molto simile ma il caso d’uso è diverso: lo trattiamo nell’articolo dedicato Come monitorare blackout della rete elettrica da remoto con Arduino e un SIM800L)
Come funziona il dispositivo, in breve
Prima di entrare nel dettaglio elettronico e nel codice, riassumiamo cosa fa concretamente il sistema:
- misura in continuo la tensione della batteria tramite un partitore resistivo collegato a un ingresso analogico di Arduino;
- mostra il valore su un piccolo display OLED, accendendolo a intervalli per risparmiare energia;
- quando la tensione scende sotto una soglia impostata (12,0V nel nostro caso, tarata su una batteria da moto), sveglia il modulo GSM SIM800L, altrimenti tenuto in sleep-mode per non consumare;
- invia un SMS di allarme e si mette in stand-by fino al riavvio manuale della scheda, per evitare di intasare il telefono di SMS ripetuti.
L’hardware
Strumento di progettazione
Per progettare il circuito usiamo EasyEDA.com: lo troviamo estremamente funzionale, con una libreria di componenti completa per gli usi che ne facciamo, la possibilità di passare dallo schema alla PCB con sbroglio automatico e, con un click, di ordinare la produzione fisica della scheda.
Schema elettrico generale

Il sistema è composto da sei gruppi funzionali distinti:
- 1. una CPU, un Arduino Nano;
- 2. un ingresso collegato direttamente alla batteria del veicolo (o dell’impianto) da monitorare;
- 3. uno stepdown (LM7805) che abbassa la tensione dai 12V della batteria ai 5V di esercizio dei componenti;
- 4. un partitore di tensione per leggere il livello della batteria con le porte analogiche della CPU;
- 5. il modulo GSM, con uno stepdown dedicato (LM2596) per le sue specifiche di alimentazione;
- 6. un piccolo monitor OLED per leggere i valori.
Ingresso 12V dalla batteria

Tutto il modulo è alimentato dalla stessa batteria che è oggetto del monitoraggio: il consumo del circuito è trascurabile rispetto alla capacità della batteria, anche grazie agli accorgimenti che vedremo per la gestione del modulo GSM. Due fori permettono di saldare il connettore verso la batteria; sul positivo è previsto in serie un portafusibili con fusibile da 500mA a protezione della CPU.
Stepdown 5V

Invece di circuiti stepdown regolabili più complessi, per limitare spazio e complessità usiamo un semplice integrato a tre piedini, l’LM7805: restituisce in uscita una tensione costante a 5V con una corrente nominale fino a 1500mA. Noi utilizziamo una corrente molto più bassa, a parte qualche picco che comunque non grava su questo integrato.
Partitore di tensione per il sensore analogico

Questo è il primo elemento di controllo del circuito: un partitore di tensione (R1 = 100 kΩ, R2 = 10 kΩ) che porta la tensione dai 12V in ingresso dalla batteria (Vin) a circa 1,09V (Vout) ai capi di R2 — un valore compatibile con l’ingresso analogico A0 di Arduino, che accetta al massimo 5V.
Per chi volesse approfondire la teoria dei partitori di tensione consigliamo questo articolo di Raffaele Ilardo: raffaeleilardo.it/parti.htm (il sito non ha una versione sicura in https, per questo non c’è il link), da cui abbiamo preso spunto per il calcolo di tutte le resistenze usate nel progetto.
Con la formula inversa del partitore (la vediamo nel dettaglio più avanti, nel software) possiamo ricalcolare la tensione reale della batteria a partire dal valore letto sul pin A0, per visualizzarla sul display OLED e capire quando scende sotto soglia per attivare l’allarme GSM.
Schermo OLED

Un display OLED 128×64 su cui visualizziamo il valore di carica della batteria e l’eventuale attivazione dell’allarme. Per minimizzare i consumi lo accendiamo a intervalli regolari per un breve lasso di tempo; è alimentato direttamente dall’uscita 5V di Arduino Nano.
Alimentazione del modulo GSM SIM800L

Il modulo SIM800L per l’invio di un SMS è facile da usare ma richiede qualche accorgimento sull’alimentazione:
- tensione: il range operativo è tra 3,4V e 4,4V, quindi non è alimentabile direttamente dai pin 3V3 o 5V di Arduino;
- corrente: nei picchi di assorbimento può arrivare a 2A, ben oltre quanto un Nano può erogare direttamente.
- Abbiamo risolto entrambi i problemi con due accorgimenti:
- tensione e corrente: partendo di nuovo dai 12V della batteria, abbiamo inserito uno stepdown DC-DC con LM2596 e regolatore a vite, impostato a 4,2V, in grado di erogare la corrente necessaria anche nei momenti di massimo assorbimento;
- consumo: mandiamo il modulo in sleep-mode e lo svegliamo con la funzione wake-up solo quando la tensione scende sotto soglia, per inviare l’SMS di allarme. Il dettaglio del meccanismo di sleep/wake-up del SIM800L è nella nostra guida completa al modulo.
Il modulo GSM SIM800L
Il modulo dialoga con il Nano tramite comandi seriali AT (li vediamo nel dettaglio nella sezione software, qui sotto). Al suo interno usiamo una SIM per progetti IoT senza abbonamento di Thingsmobile. Se non conoscete ancora questo modulo, la nostra guida completa al SIM800L copre alimentazione, comandi AT principali, sleep/wake-up e invio SMS con molto più dettaglio di quanto rientri in questo articolo.
CPU: Arduino Nano
La CPU è un Arduino Nano (nel nostro caso la versione clone, del tutto equivalente a livello funzionale). Gestisce tutti gli I/O collegati tramite il software che vediamo più avanti.
La PCB




EasyEDA genera automaticamente la PCB a partire dallo schema: ci siamo limitati a disporre i componenti in modo ordinato e ad avviare lo sbroglio automatico delle piste, su una piastra a doppia faccia. Il programma genera anche il file GERBER pronto per la produzione.
Distinta base (BOM)
Nota sui link Amazon: alcuni link della tabella sono link di affiliazione — se acquistate tramite questi link non pagate nulla in più, ma supportate il blog.
| # | Componente | Specifiche | Qtà | Note | Link Amazon |
|---|---|---|---|---|---|
| 1 | Arduino Nano | ATmega328, anche versione clone | 1 | CPU del sistema | Link |
| 2 | Modulo GSM SIM800L | Quad-band, alimentazione 3,4–4,4V | 1 | Invio SMS di allarme | Link |
| 3 | SIM IoT senza abbonamento | es. Thingsmobile | 1 | Necessaria per l’invio SMS | Link |
| 4 | Regolatore LM7805 (TO-220) | Uscita 5V, fino a 1500mA nominali | 1 | Alimenta Nano, OLED e logica | Link |
| 5 | Modulo stepdown LM2596 | DC-DC regolabile a vite | 1 | Alimenta il SIM800L a 4,2V | Link |
| 6 | Display OLED SSD1306 128×64 | Interfaccia I2C | 1 | Visualizzazione stato batteria | Link |
| 7 | Resistore R1 | 100 kΩ | 1 | Partitore di tensione | – |
| 8 | Resistore R2 | 10 kΩ | 1 | Partitore di tensione | – |
| 9 | Portafusibile + fusibile | 500 mA | 1 | Protezione della CPU | – |
| 10 | PCB custom | Doppia faccia, file Gerber da EasyEDA | 1 | – | — |
| 11 | Cavetteria, connettori, case | Secondo necessità di montaggio sul veicolo | — | Non fornita nel kit | – |
Prototipo su breadboard

Prima della versione definitiva su PCB abbiamo realizzato un prototipo su breadboard per testare collegamenti e software, usando una Elegoo Uno R3 al posto della Nano: il software non cambia, perché entrambe montano la stessa CPU ATmega328, solo in due configurazioni hardware diverse.
Il software
Diagramma di flusso

Librerie
#include <U8x8lib.h> // libreria per gestione schermo OLED
#include "SoftwareSerial.h" // libreria per seriale con modulo SIM800L
Entrambe sono disponibili nel Library Manager dell’IDE Arduino. La lettura del voltaggio non richiede una libreria: è il risultato di un calcolo fatto via software.
Attribuzione dei pin
Definiamo subito i pin con nomi parlanti, così un’eventuale modifica dei collegamenti si fa in un solo punto:
#define VoltTestPin A0 // pin analogico collegato al partitore per la misura del voltaggio
#define DTR_PIN 5 // pin DTR del SIM800L collegato al pin D5 di Arduino
#define SIM_TX_PIN 6 // pin TX del SIM800L collegato al pin D6 di Arduino
#define SIM_RX_PIN 7 // pin RX del SIM800L collegato al pin D7 di Arduino
Attenzione: ricordatevi il partitore sull’ingresso analogico, altrimenti rischiate di bruciare il pin prima ancora di iniziare. Non ci sono vincoli particolari nella scelta dei digitali (non usiamo funzioni PWM); tra gli analogici, A4 e A5 sono occupati dal collegamento I2C con il display OLED (SDA/SCL).
Inizializzazione degli oggetti
SoftwareSerial serialSIM800(SIM_TX_PIN, SIM_RX_PIN); // seriale software verso il SIM800L
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // oggetto per il display OLED
Qui gli oggetti vengono solo creati; verranno inizializzati (attivati) in setup().
Definizione delle variabili
int read_value = 0; // valore intero letto sul pin A0 (0-1023)
float ref_voltage = 5.0; // tensione di riferimento massima per il calcolo
float read_voltage = 0.0; // tensione letta sul pin A0
float batt_voltage = 0.0; // tensione reale della batteria, dopo la formula inversa del partitore
float R1 = 100000.0; // valore di R1 del partitore
float R2 = 10000.0; // valore di R2 del partitore
int v_dummy = 0; // flag per inviare l'SMS una sola volta, fino al reset
read_value è un intero perché il pin A0 può assumere solo 1024 valori discreti (0-1023): definirlo come float allocherebbe memoria inutile.
void setup()
void setup() {
serialSIM800.begin(57600); // inizializza la seriale con il modulo GSM
delay(50);
digitalWrite(DTR_PIN, HIGH);
delay(50);
Screeninit(); // avvia lo schermo OLED
delay(50);
sim800sleepmode(); // mette il modulo GSM in sleep-mode
}
void loop()
void loop() {
Readvoltage();
if (batt_voltage < 12.0 && v_dummy == 0) {
sim800wakeup();
sendsmsalarm();
v_dummy = 1; // impedisce l'invio di ulteriori SMS fino al reset della scheda
}
}
Testiamo anche la variabile v_dummy per evitare che il dispositivo invii SMS in loop continuo: una volta rilevato il superamento della soglia e inviato l’allarme, il sistema resta in stand-by finché non si interviene manualmente (nel nostro caso, si ricarica la batteria e si riavvia la scheda).
Screeninit()
void Screeninit() {
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clear();
u8x8.drawString(0, 0, "Initializing...");
delay(2000);
u8x8.clear();
}
Oltre a inizializzare il display, ci piace vedere la scritta “Initializing…” all’avvio della scheda.
Readvoltage()
void Readvoltage() {
read_value = analogRead(VoltTestPin);
read_voltage = (read_value * ref_voltage) / 1024.0; // converte la lettura in tensione
batt_voltage = read_voltage / (R2 / (R1 + R2)); // formula inversa del partitore
}
La batteria fornisce circa 12V; il partitore (R1 = 100 kΩ, R2 = 10 kΩ) li abbassa a circa 1,09V ai capi di R2, un valore che la porta analogica A0 legge come intero tra 0 e 1023 in proporzione al riferimento di 5V. Conoscendo il rapporto di partizione, possiamo invertire il calcolo e risalire alla tensione reale della batteria senza portarla direttamente sulla scheda.
sim800sleepmode() e sim800wakeup()
void sim800sleepmode() {
serialSIM800.println("AT+CSCLK=2");
}
void sim800wakeup() {
digitalWrite(DTR_PIN, LOW);
delay(200);
digitalWrite(DTR_PIN, HIGH);
serialSIM800.println("AT");
serialSIM800.println("AT+CSCLK=0");
}
AT+CSCLK=2 abilita lo sleep controllato dal pin DTR; il ciclo LOW→HIGH su DTR in sim800wakeup() risveglia il modulo prima di inviare l’SMS. Il dettaglio del comando e delle tempistiche è nella guida al SIM800L.
sendsmsalarm()
void sendsmsalarm() {
serialSIM800.println("AT+CMGF=1");
serialSIM800.println("AT+CMGS=\"+39xxxxxxxxxx\"");
serialSIM800.print("testo del messaggio");
serialSIM800.write(26); // Ctrl+Z, invia il messaggio
}
Nota pratica: nella nostra esperienza sul campo, tra AT+CMGS e l’invio del testo il modulo a volte ha bisogno di un breve margine (es. un delay(1000) o l’attesa del prompt >) prima di essere pronto a ricevere il corpo del messaggio. Se il vostro SMS non parte al primo colpo, è il primo punto da controllare.
Una piccola correzione di coerenza rispetto agli articoli originali
Unendo i due articoli abbiamo confrontato la definizione di ogni funzione con le relative chiamate, e abbiamo trovato alcune incoerenze di trascrizione tra i due post pubblicati separatamente: in setup() si chiamava sim800sleep() mentre la funzione era definita come sim800sleepmode(); nel loop() la condizione era scritta v_dummy = 0 invece di v_dummy == 0 (un’assegnazione al posto di un confronto, che avrebbe reso l’allarme sempre inattivo), mancava il punto e virgola dopo v_dummy = 1, e la chiamata Sendsmsalarm() non corrispondeva per maiuscole/minuscole alla funzione sendsmsalarm() realmente definita. Il codice qui sopra è già corretto e coerente; segnaliamo la correzione per trasparenza, come vuole la nostra linea editoriale.
File di progetto
monitor_batteria_moto (PDF, 5 KB)
Possibili applicazioni e sviluppi futuri
Abbiamo pensato a questo dispositivo per la nostra moto, ma può essere applicato a qualsiasi apparecchio a batteria, con gli opportuni accorgimenti su alimentazione e partitore di tensione al sensore — compreso, con soglie e collegamenti adattati, il monitoraggio di una mancanza di corrente su un impianto alimentato in continua a 12V (per un blackout sulla rete a 230V, l’approccio più diretto resta quello descritto nel nostro articolo dedicato al monitoraggio blackout).
Se qualcuno dei nostri lettori reinterpreta questo progetto, condividete con noi la vostra applicazione nei commenti.
Disclaimer
Questo progetto prevede il collegamento a una batteria di un veicolo e componenti che possono scaldare (regolatori di tensione, modulo GSM sotto carico): si tratta di un contenuto a scopo divulgativo e amatoriale, senza garanzie sul corretto funzionamento di schemi e codice riportati. La realizzazione è a rischio e responsabilità di chi la effettua; escludiamo qualsiasi responsabilità per danni diretti o indiretti a cose, veicoli o persone derivanti dalla costruzione o dall’uso del dispositivo. Il sistema non è uno strumento certificato o omologato. Per i dettagli consultate i nostri Termini e Condizioni di utilizzo.
Conclusioni
Speriamo che questo progetto, ora raccontato in un unico articolo con hardware e software insieme, vi sia utile — sia per proteggere la batteria della vostra moto sia per adattarlo ad altri usi. Se avete bisogno di informazioni specifiche o di un contributo su un vostro progetto e se costruite una vostra versione, raccontatecelo nei commenti.
Domande frequenti
Come funziona l’SMS di avviso mancanza corrente/batteria scarica?
Il sistema misura in continuo la tensione della batteria tramite un partitore resistivo; quando scende sotto la soglia impostata (12,0V nel nostro caso), sveglia il modulo GSM SIM800L, altrimenti in sleep-mode, e invia un SMS di allarme al numero configurato nel codice.
Il dispositivo può segnalare anche un blackout della rete elettrica, e non solo la batteria della moto?
Il principio (partitore + soglia + SMS via SIM800L) è lo stesso, ma per monitorare la rete a 230V servono accorgimenti diversi da quelli di un impianto a 12V in continua: per quel caso d’uso specifico abbiamo scritto un articolo dedicato.
Quanto consuma il modulo SIM800L in stand-by con questo sistema?
Tenendolo in sleep-mode (AT+CSCLK=2) tra un controllo e l’altro, il consumo resta trascurabile rispetto alla capacità della batteria monitorata; lo sveglia solo il superamento della soglia di allarme.
Posso usare una scheda diversa da Arduino Nano?
Sì: nel prototipo abbiamo usato una Elegoo Uno R3, che monta la stessa CPU ATmega328 del Nano in una configurazione hardware diversa. Il software non cambia; cambia solo la disposizione fisica dei pin.
Come cambio la soglia di tensione per adattarla ad altre batterie (es. 24V o batterie al litio)?
Si interviene su due punti del codice: il valore di confronto in if (batt_voltage < 12.0 ...) nel loop(), e — se la tensione massima da misurare cambia sensibilmente — i valori di R1/R2 del partitore, ricalcolati in modo che la tensione ai capi di R2 non superi mai i 5V accettati dal pin analogico.
È sicuro installare questo dispositivo su un veicolo?
È un progetto amatoriale a scopo divulgativo: va installato a proprio rischio, con attenzione a fusibile di protezione, isolamento dei collegamenti e alla tenuta meccanica sul veicolo. Non è uno strumento certificato. Dettagli nei Termini e Condizioni.
Link correlati
- – Guida completa al modulo GSM SIM800L – alimentazione, comandi AT, sleep/wake-up, invio SMS
- – Come monitorare blackout della rete elettrica da remoto con Arduino e un SIM800L
- – Teoria dei partitori di tensione — raffaeleilardo.it/parti.htm
- – Tutorial display OLED con Arduino — lastminuteengineers.com
- – SIM800/SIM900 sleep mode AT commands — raviyp.com