PROGETTI ARDUINO

  • HOME
  • 200 Progetti
  • Progetti e Tutorial
  • Reti
    • Impara le reti
    • internet fibra
    • wifi mesh
    • modem router
    • diagnostica reti
    • ethernet lan
    • sicurezza configurazione
  • Elettronica
  • Recensioni
  • Manuale
  • Contatti
  • HOME
  • 200 Progetti
  • Progetti e Tutorial
  • Reti
    • Impara le reti
    • internet fibra
    • wifi mesh
    • modem router
    • diagnostica reti
    • ethernet lan
    • sicurezza configurazione
  • Elettronica
  • Recensioni
  • Manuale
  • Contatti

Progetto 136
Monitor consumi
elettrici base

🚀 Introduzione
​

Vuoi misurare quanta corrente assorbe un dispositivo e calcolare la potenza consumata? ⚡📊

In questo progetto realizzerai un monitor di consumi elettrici in corrente continua utilizzando Arduino, un sensore di corrente ACS712 e un display OLED.
​
Il sistema misurerà:
  • tensione del circuito;
  • corrente assorbita;
  • potenza istantanea;
  • energia consumata nel tempo.
​
👉 Per le prove utilizzeremo esclusivamente un circuito a bassa tensione, come un carico da 5V o 12V.

🧰 Materiale necessario
  • 1x Arduino UNO;
  • 1x display OLED 0,96 pollici I2C SSD1306;
  • 1x sensore di corrente ACS712 da 5A;
  • 2x resistenze per il partitore di tensione;
  • 1x resistenza da 30 kΩ;
  • 1x resistenza da 7,5 kΩ;
  • 1x pulsante;
  • 1x carico a bassa tensione, come una lampadina o una striscia LED da 12V;
  • 1x alimentatore a bassa tensione;
  • cavetti jumper;
  • breadboard;
  • cavo USB.
​
Le resistenze da 30 kΩ e 7,5 kΩ permettono di misurare tensioni fino a circa 25V senza superare il limite di 5V sull’ingresso analogico di Arduino.

🛒 Non hai ancora i componenti?

Molti dei progetti presenti su progettiarduino.com utilizzano componenti elettronici di base come LED, resistenze, sensori e breadboard.
Se stai iniziando con Arduino, il modo più semplice è utilizzare un kit completo per principianti, che include quasi tutti i componenti necessari per realizzare molti dei progetti presenti sul sito.

👉 Kit Arduino consigliato:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4b3dxjW

📘 Vuoi imparare Arduino passo dopo passo?
Se vuoi approfondire e realizzare progetti più completi, puoi dare un'occhiata anche ai miei libri dedicati ad Arduino.
All'interno troverai spiegazioni semplici, schemi chiari e molti progetti pratici pensati per chi parte da zero.

👉 Scopri i miei libri su Arduino:
ℹ️ Link di affiliazione Amazon: in qualità di Affiliato Amazon ricevo un guadagno dagli acquisti idonei, senza alcun costo aggiuntivo per te.
https://amzn.to/4rfzjXE
​

📚 Librerie necessarie
​

Per utilizzare il display OLED devi installare:
  • Adafruit SSD1306;
  • Adafruit GFX Library.
La libreria Wire è già inclusa nell’Arduino IDE.
​
Il sensore ACS712 viene letto direttamente tramite analogRead() e non richiede librerie esterne.

🔌 Schema di collegamento

Display OLED SSD1306
  • VCC → 5V;
  • GND → GND;
  • SDA → A4;
  • SCL → A5.
L’indirizzo I2C utilizzato nel codice è 0x3C.

Sensore ACS712
Sul lato dei pin di segnale:
  • VCC → 5V;
  • GND → GND;
  • OUT → A0.
Sul lato dei morsetti di potenza:
  • alimentazione positiva → ingresso IP+;
  • uscita IP− → positivo del carico;
  • negativo del carico → negativo dell’alimentatore.
Il sensore deve essere collegato in serie al carico.

Partitore di tensione
Per misurare la tensione del carico:
  • resistenza da 30 kΩ tra positivo dell’alimentatore e A1;
  • resistenza da 7,5 kΩ tra A1 e GND;
  • negativo dell’alimentatore collegato al GND di Arduino.
Il punto centrale del partitore viene collegato al pin A1.

Pulsante di azzeramento
  • un terminale → pin digitale 2;
  • terminale opposto → GND.
Il pulsante utilizza INPUT_PULLUP.
Foto

⚠️ Sicurezza elettrica

Questo progetto è pensato esclusivamente per circuiti in corrente continua a bassa tensione.

👉 Non collegare il circuito direttamente alla rete elettrica domestica da 230V.

La tensione di rete può provocare:
  • folgorazioni;
  • incendi;
  • danni ad Arduino;
  • danni al computer collegato tramite USB.
​
Per misurare la rete elettrica servono sensori isolati, contenitori adeguati e competenze specifiche.

​💻 Codice Arduino
​

Il programma legge:
  • uscita analogica del sensore ACS712;
  • tensione del partitore;
  • stato del pulsante.
Dalle misurazioni calcola:
potenza = tensione * corrente;

L’energia viene invece calcolata sommando la potenza nel tempo:
energiaWh += potenza * oreTrascorse;
​/*
  ============================================================
  Progetto 136 - Monitor consumi elettrici base
  Misura tensione, corrente, potenza ed energia in corrente DC
  ============================================================
*/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Dimensioni e indirizzo del display OLED
#define LARGHEZZA_DISPLAY 128
#define ALTEZZA_DISPLAY 64
#define RESET_OLED -1
#define INDIRIZZO_OLED 0x3C

// Pin analogici utilizzati per le misurazioni
#define PIN_CORRENTE A0
#define PIN_TENSIONE A1

// Pulsante per azzerare il contatore energetico
#define PIN_RESET 2

// Tensione di riferimento dell'ADC di Arduino UNO
const float TENSIONE_RIFERIMENTO = 5.0;

// Numero massimo restituito dall'ADC a 10 bit
const float VALORE_MASSIMO_ADC = 1023.0;

// Sensibilità del sensore ACS712 da 5A.
// Per il modello da 20A utilizzare circa 0.100.
// Per il modello da 30A utilizzare circa 0.066.
const float SENSIBILITA_ACS712 = 0.185;

// Valori delle resistenze del partitore
const float RESISTENZA_SUPERIORE = 30000.0;
const float RESISTENZA_INFERIORE = 7500.0;

// Rapporto utilizzato per ricostruire
// la tensione reale del circuito
const float RAPPORTO_PARTITORE =
  (RESISTENZA_SUPERIORE + RESISTENZA_INFERIORE) /
  RESISTENZA_INFERIORE;

// Numero di campioni utilizzati per mediare le letture
const int NUMERO_CAMPIONI = 100;

// Valori molto piccoli vengono considerati rumore
const float SOGLIA_RUMORE_CORRENTE = 0.03;
const float SOGLIA_RUMORE_TENSIONE = 0.05;

// Soglia indicativa per l'avviso di corrente alta
const float SOGLIA_CORRENTE = 4.0;

// Tempi di aggiornamento
const unsigned long INTERVALLO_MISURA = 250;
const unsigned long TEMPO_DEBOUNCE = 180;

// Oggetto utilizzato per controllare il display
Adafruit_SSD1306 display(
  LARGHEZZA_DISPLAY,
  ALTEZZA_DISPLAY,
  &Wire,
  RESET_OLED
);

// Tensione di uscita del sensore ACS712
// quando non passa corrente
float tensioneZeroSensore = 2.5;

// Valori elettrici calcolati
float tensione = 0.0;
float corrente = 0.0;
float potenza = 0.0;
float energiaWh = 0.0;

// Variabili temporali
unsigned long ultimaMisura = 0;
unsigned long ultimoCalcoloEnergia = 0;
unsigned long ultimaPressione = 0;

void setup() {
  // Il pulsante è collegato tra il pin e GND
  pinMode(PIN_RESET, INPUT_PULLUP);

  // Inizializza il display OLED
  if (!display.begin(
        SSD1306_SWITCHCAPVCC,
        INDIRIZZO_OLED
      )) {
    // Se il display non viene rilevato,
    // il programma rimane bloccato
    while (true) {
    }
  }

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextWrap(false);

  // Mostra la schermata iniziale
  mostraAvvio();

  // Calibra il sensore ACS712.
  // Durante questa fase il carico deve essere spento.
  calibraSensoreCorrente();

  // Memorizza il momento iniziale
  ultimaMisura = millis();
  ultimoCalcoloEnergia = millis();

  // Esegue e mostra subito una prima misurazione
  aggiornaMisure();
  mostraDati();
}

void loop() {
  // Controlla il pulsante di azzeramento
  gestisciPulsante();

  // Aggiorna periodicamente tutte le misure
  // senza bloccare Arduino con delay()
  if (millis() - ultimaMisura >= INTERVALLO_MISURA) {
    ultimaMisura = millis();

    aggiornaMisure();
    mostraDati();
  }
}

void aggiornaMisure() {
  // Memorizza il momento corrente per calcolare
  // quanto tempo è trascorso dall'ultimo aggiornamento
  unsigned long momentoAttuale = millis();

  unsigned long tempoTrascorso =
    momentoAttuale - ultimoCalcoloEnergia;

  ultimoCalcoloEnergia = momentoAttuale;

  // Legge tensione e corrente
  tensione = leggiTensione();
  corrente = leggiCorrente();

  // Elimina piccoli valori causati dal rumore
  if (tensione < SOGLIA_RUMORE_TENSIONE) {
    tensione = 0.0;
  }

  if (abs(corrente) < SOGLIA_RUMORE_CORRENTE) {
    corrente = 0.0;
  }

  // Il progetto considera soltanto il valore
  // assoluto della corrente assorbita
  corrente = abs(corrente);

  // Calcola la potenza istantanea in watt
  potenza = tensione * corrente;

  // Converte il tempo trascorso da millisecondi a ore
  float oreTrascorse =
    tempoTrascorso / 3600000.0;

  // Integra la potenza nel tempo
  // per ottenere l'energia consumata in Wh
  energiaWh += potenza * oreTrascorse;
}

float leggiTensione() {
  unsigned long somma = 0;

  // Esegue più letture per ridurre il rumore
  for (int i = 0; i < NUMERO_CAMPIONI; i++) {
    somma += analogRead(PIN_TENSIONE);
  }

  float mediaAdc =
    somma / (float)NUMERO_CAMPIONI;

  // Converte il valore ADC nella tensione
  // realmente presente sul pin A1
  float tensionePin =
    mediaAdc *
    (TENSIONE_RIFERIMENTO / VALORE_MASSIMO_ADC);

  // Ricostruisce la tensione prima del partitore
  float tensioneReale =
    tensionePin * RAPPORTO_PARTITORE;

  return tensioneReale;
}

float leggiCorrente() {
  unsigned long somma = 0;

  // Esegue più letture dell'uscita ACS712
  for (int i = 0; i < NUMERO_CAMPIONI; i++) {
    somma += analogRead(PIN_CORRENTE);
  }

  float mediaAdc =
    somma / (float)NUMERO_CAMPIONI;

  // Converte il valore ADC in volt
  float tensioneSensore =
    mediaAdc *
    (TENSIONE_RIFERIMENTO / VALORE_MASSIMO_ADC);

  // Calcola la differenza rispetto
  // al punto di zero del sensore
  float differenza =
    tensioneSensore - tensioneZeroSensore;

  // Converte la differenza di tensione in ampere
  float correnteCalcolata =
    differenza / SENSIBILITA_ACS712;

  return correnteCalcolata;
}

void calibraSensoreCorrente() {
  display.clearDisplay();
  display.setTextSize(1);

  display.setCursor(19, 14);
  display.print("Calibrazione ACS712");

  display.setCursor(8, 31);
  display.print("Mantieni carico spento");

  display.setCursor(26, 48);
  display.print("Attendere...");

  display.display();

  // Attende che il circuito si stabilizzi
  delay(1000);

  unsigned long somma = 0;
  const int CAMPIONI_CALIBRAZIONE = 500;

  // Calcola la media dell'uscita del sensore
  // quando non passa corrente
  for (int i = 0; i < CAMPIONI_CALIBRAZIONE; i++) {
    somma += analogRead(PIN_CORRENTE);
    delay(2);
  }

  float mediaAdc =
    somma / (float)CAMPIONI_CALIBRAZIONE;

  // Memorizza la tensione reale di zero
  tensioneZeroSensore =
    mediaAdc *
    (TENSIONE_RIFERIMENTO / VALORE_MASSIMO_ADC);
}

void gestisciPulsante() {
  // Con INPUT_PULLUP il pulsante premuto
  // viene letto come livello LOW
  if (digitalRead(PIN_RESET) == LOW &&
      millis() - ultimaPressione >= TEMPO_DEBOUNCE) {
    ultimaPressione = millis();

    // Azzera il contatore energetico
    energiaWh = 0.0;

    // Mostra subito il nuovo valore
    mostraDati();
  }
}

void mostraDati() {
  // Pulisce completamente il display
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);

  // Titolo e stato generale
  display.setCursor(0, 0);
  display.print("MONITOR CONSUMI");

  if (corrente >= SOGLIA_CORRENTE) {
    display.setCursor(103, 0);
    display.print("AL!");
  } else {
    display.setCursor(109, 0);
    display.print("OK");
  }

  display.drawLine(
    0,
    10,
    127,
    10,
    SSD1306_WHITE
  );

  // Mostra la tensione
  display.setCursor(0, 16);
  display.print("Tensione: ");
  display.print(tensione, 2);
  display.print(" V");

  // Mostra la corrente
  display.setCursor(0, 28);
  display.print("Corrente: ");
  display.print(corrente, 3);
  display.print(" A");

  // Mostra la potenza
  display.setCursor(0, 40);
  display.print("Potenza:  ");
  display.print(potenza, 2);
  display.print(" W");

  // Mostra l'energia accumulata
  display.setCursor(0, 52);
  display.print("Energia:  ");
  display.print(energiaWh, 3);
  display.print(" Wh");

  // Piccola indicazione del pulsante
  display.setCursor(98, 52);
  display.print("RST");

  // Invia al display tutti gli elementi disegnati
  display.display();
}

void mostraAvvio() {
  display.clearDisplay();
  display.setTextSize(1);

  display.setCursor(20, 14);
  display.print("Monitor consumi");

  display.setCursor(17, 30);
  display.print("Tensione e corrente");

  display.setCursor(28, 47);
  display.print("Progetto 136");

  display.display();

  delay(1800);
}
​Prima della calibrazione, il carico deve essere spento o scollegato, altrimenti Arduino considererà una corrente reale come punto di zero e tutte le letture successive saranno falsate.

⚙️ Come funziona
​

Arduino esegue numerose letture analogiche e ne calcola la media.

Questo riduce il rumore presente sull’uscita del sensore ACS712.

Il sensore ACS712 da 5A possiede una sensibilità indicativa di:
185 mV/A
Quando la corrente è zero, l’uscita si trova normalmente vicino a metà della tensione di alimentazione, quindi circa 2,5V.
​
Quando la corrente aumenta, la tensione di uscita si sposta rispetto a questo valore.

⚡ Misurazione della corrente
​

La corrente viene calcolata con la formula:
corrente = (tensioneSensore - tensioneZero) / sensibilita;
Dove:
  • tensioneSensore è il valore letto su A0;
  • tensioneZero è l’uscita del sensore senza carico;
  • sensibilita dipende dal modello ACS712.
​
Per il modello da 5A viene utilizzato:
const float SENSIBILITA_ACS712 = 0.185;

Per altri modelli:
  • ACS712 20A → circa 0.100 V/A;
  • ACS712 30A → circa  0.066 V/A. 

🔌 Misurazione della tensione

Arduino può misurare direttamente soltanto tensioni comprese tra 0V e 5V.

Il partitore riduce la tensione del circuito prima che raggiunga il pin A1.

Con resistenze da 30 kΩ e 7,5 kΩ il rapporto è:
rapporto = (30000 + 7500) / 7500;

​Il valore letto da Arduino viene quindi moltiplicato per questo rapporto per ricostruire la tensione reale.

📊 Calcolo della potenza

La potenza elettrica viene calcolata moltiplicando tensione e corrente:
potenza = tensione * corrente;

​Il risultato viene espresso in watt.
Per esempio:
  • tensione: 12V;
  • corrente: 0,5A;
  • potenza: 6W.

🔋 Calcolo dell’energia

La potenza indica il consumo istantaneo.
L’energia indica invece quanto è stato consumato nel tempo.
​
Il programma calcola l’energia in wattora:
energiaWh += potenza * oreTrascorse;

Se un dispositivo assorbe 10W per un’ora, il consumo sarà:
10 Wh

Il valore aumenta finché Arduino rimane acceso oppure finché non viene premuto il pulsante di azzeramento.

⚠️ Avviso di sovracorrente

Nel codice è presente una soglia di sicurezza indicativa:
const float SOGLIA_CORRENTE = 4.0;

Quando la corrente supera questa soglia, il display mostra:
CORRENTE ALTA
​
La soglia deve essere scelta in base al sensore, ai cavi e al carico utilizzato.
​
👉 Il messaggio non sostituisce un fusibile o una protezione elettrica reale.

🎚️ Calibrazione del sensore

Ogni modulo ACS712 può presentare un piccolo errore sul punto di zero.

Per questo il programma esegue una calibrazione iniziale.

Durante l’avvio:
  • il carico deve essere spento;
  • Arduino esegue numerose letture;
  • viene calcolata la tensione di zero del sensore.
​
👉 Non accendere il carico durante la calibrazione iniziale.

📟 Informazioni visualizzate
​

Il display OLED mostra:
  • tensione in volt;
  • corrente in ampere;
  • potenza in watt;
  • energia in Wh;
  • stato normale o allarme.
​
I dati vengono aggiornati più volte al secondo.

🧠 Perché è un progetto importante
​

Con questo progetto impari a:
  • utilizzare il sensore ACS712;
  • misurare una tensione con un partitore;
  • calcolare corrente e potenza;
  • calcolare l’energia consumata;
  • filtrare letture analogiche;
  • calibrare un sensore;
  • utilizzare millis() per integrare un valore nel tempo;
  • creare un contatore energetico;
  • visualizzare misure elettriche su OLED;
  • gestire una soglia di sovracorrente.
​
👉 Questa base sarà utile per sistemi di monitoraggio energetico più completi e connessi.

🔄 Varianti possibili
​

Vuoi migliorare il progetto?
  • 💾 salva l’energia nella EEPROM;
  • 📊 aggiungi un grafico della potenza;
  • ⏰ registra data e ora tramite DS3231;
  • 🗃️ salva le misure su microSD;
  • 🔔 aggiungi un buzzer di allarme;
  • ⚡ scollega il carico tramite relè;
  • 📶 invia i consumi tramite Wi-Fi;
  • 📱 crea una dashboard web;
  • 🔋 monitora una batteria;
  • ☀️ misura la produzione di un piccolo pannello solare;
  • 📟 aggiungi schermate selezionabili;
  • 🧮 calcola il costo dell’energia.

Foto
Foto

© ProgettiArduino.com 2026 - Fancello Salvatore
​ Layout, immagini e testi sono di esclusiva proprietà di www.progettiarduino.com 
Privacy Policy