Componenti · 18 min di lettura

Sensore di corrente ACS712: misurare corrente DC e AC con Arduino

Come usare il sensore di corrente ACS712: sensibilità 5A/20A/30A, punto zero a 2,5 V, codice Arduino DC e AC (RMS), calcolo della potenza, ESP32 e INA219.

Il sensore di corrente ACS712 è un modulo piccolo ed economico che rileva la corrente che attraversa un circuito tramite l'effetto Hall e la converte in una tensione che il tuo Arduino può leggere. Senza corrente la sua uscita è a circa 2,5 V; sale quando la corrente scorre in un verso e scende quando scorre nell'altro. Così puoi misurare sia la corrente continua (DC) sia quella alternata (AC) con un solo pin analogico. Si usa per vedere quanta corrente assorbe un motore, seguire la scarica di una batteria, capire se un apparecchio è in funzione o calcolare la potenza di un elettrodomestico. In più, la linea misurata è isolata elettricamente dal lato Arduino.

In questa guida imparerai passo dopo passo cosa c'è dentro l'ACS712, in cosa differiscono i modelli da 5A, 20A e 30A e quale scegliere, come collegare il modulo in serie al circuito, il primo sketch Arduino che misura la corrente continua, come calmare le letture instabili con la media, come calcolare il valore RMS della corrente alternata e come ricavare potenza (W) ed energia (Wh). Poi vedrai come collegarlo a ESP32 e Raspberry Pi Pico a 3,3 V con un partitore di tensione, perché bisogna essere molto prudenti con la rete a 230 V e perché l'INA219 è una scelta migliore per le correnti piccole.

Modulo sensore di corrente ACS712 (versione 20A)
Modulo ACS712: la sigla ELC-20A sul chip indica la versione da 20 ampere. Il morsetto a vite verde va in serie al circuito da misurare; i pin VCC, OUT e GND vanno ad Arduino.

Cos'è il sensore di corrente ACS712 e come funziona?

L'ACS712 è un chip a 8 pin prodotto da Allegro. La corrente da misurare attraversa un grosso percorso in rame all'interno del chip, dai pin 1 e 2 ai pin 3 e 4. Questo percorso ha una resistenza di appena 1,2 mΩ; anche a 10 A la caduta è di soli 12 mV con 0,12 W di calore, quindi il circuito misurato quasi non se ne accorge. Passando nel conduttore, la corrente genera un campo magnetico proporzionale. Un sensore Hall posto proprio sopra il rame rileva questo campo e un amplificatore interno lo trasforma in tensione. Trovi le basi in dettaglio nella nostra guida ai sensori a effetto Hall.

Non c'è alcun collegamento elettrico tra il percorso in rame in cui scorre la corrente e il lato che alimenta il chip; l'unico legame è il campo magnetico. Per questo la linea misurata e Arduino sono isolati tra loro (isolamento galvanico). La tensione di uscita segue questa formula: Vout = VCC / 2 + Sensibilità × I. Se la corrente va da IP+ a IP−, l'uscita sale sopra 2,5 V; nel verso opposto scende sotto. L'ACS712 è anche raziometrico: punto zero e sensibilità cambiano insieme alla tensione di alimentazione. Se questa scende a 4,8 V, il punto zero diventa 2,4 V e la sensibilità del modello da 5A passa da 185 a circa 178 mV/A.

CaratteristicaValore
Tensione di alimentazione4,5–5,5 V (tipica 5 V)
AssorbimentoTipico 10 mA, massimo 13 mA
Uscita a corrente zeroVCC × 0,5 (2,5 V a 5 V)
Resistenza del conduttore1,2 mΩ
Banda passante80 kHz (ridotta dal condensatore sul pin FILTER)
Errore totale di uscita±1,5% a 25 °C
Tenuta di isolamento2,4 kV RMS (60 secondi)
Carico in uscitaAlmeno 4,7 kΩ, al massimo 10 nF
Sovracorrente breve100 A (un impulso, 100 ms)
Temperatura di esercizioDa −40 a 85 °C
Collegamenti del moduloVCC, OUT, GND e morsetto a vite a 2 poli

Modelli da 5A, 20A e 30A: sensibilità e risoluzione

L'ACS712 esiste in tre versioni che dall'esterno sono identiche. Per sapere quale hai, leggi la sigla sul chip: ELC-05B misura ±5 A, ELC-20A ±20 A ed ELC-30A ±30 A. La sensibilità indica di quanti millivolt cambia l'uscita per ogni ampere. Più ampio è l'intervallo, più bassa è la sensibilità, così nei modelli da 20A e 30A l'uscita resta tra 0,5 e 4,5 V anche alla corrente massima. La tabella mostra anche a quanti milliampere corrisponde un passo dell'ADC a 10 bit di Arduino Uno (4,88 mV) per ciascun modello.

Modello (sigla del chip)IntervalloSensibilitàUscita a fondo scala1 passo ADC su UnoRumore (filtro 47 nF)
ACS712ELCTR-05B±5 A185 mV/A (180–190)1,58–3,43 V≈ 26 mA21 mV ≈ 0,11 A picco-picco
ACS712ELCTR-20A±20 A100 mV/A (96–104)0,50–4,50 V≈ 49 mA11 mV ≈ 0,11 A picco-picco
ACS712ELCTR-30A±30 A66 mV/A (63–69)0,52–4,48 V≈ 74 mA7 mV ≈ 0,11 A picco-picco

Dalla tabella emergono due conclusioni importanti. Primo, il rumore espresso in ampere è di circa 0,1 A in tutti e tre i modelli; se usi il 30A per un carico da 2 A, sprechi due terzi della risoluzione. La regola è semplice: scegli il modello più piccolo che copre con margine la corrente massima da misurare (in alternata il valore di picco). Per esempio, il 5A va bene per un motore a 12 V che assorbe al massimo 2–3 A, il 20A per una stufetta da 1500 W. Secondo, l'ACS712 non è pensato per le correnti piccole: con lui non puoi misurare un LED da pochi milliampere né un ESP32 in deep sleep. Per questo lavoro l'INA219, descritto alla fine della guida, è molto meglio.

Collegamento dell'ACS712: Arduino Uno, ESP32 e Pico

Il modulo ACS712 ha due lati. Il lato del morsetto a vite appartiene al circuito da misurare: la corrente deve entrare da un morsetto e uscire dall'altro, quindi il modulo va collegato in serie al carico, proprio come un amperometro. Di solito tagli il filo positivo dell'alimentatore, colleghi il capo che arriva dall'alimentatore a un lato del morsetto e il capo che va al carico all'altro. Il lato a tre pin va ad Arduino. L'ACS712 funziona solo a 5 V; anche su ESP32 e Pico lo alimenti da un pin a 5 V e leggi l'uscita attraverso un partitore di tensione.

Pin ACS712Arduino UnoESP32Raspberry Pi Pico
VCC5V5V (VIN su alcune schede)VBUS (pin 40)
OUTA0GPIO 34 (con partitore 10k/20k)GP26 (con partitore 10k/20k)
GNDGNDGNDGND
Morsetto a viteIn serie al caricoIn serie al caricoIn serie al carico
Non collegare mai i due morsetti tra il positivo e il negativo di un alimentatore, cioè in parallelo come un voltmetro. Il conduttore interno ha solo 1,2 mΩ: è un cortocircuito netto. L'alimentatore eroga tutta la corrente che può, la batteria o l'alimentatore si danneggiano e cavi e modulo possono bruciare. La corrente misurata deve sempre passare attraverso un carico (motore, lampada o resistenza).

Oltre al chip, sul modulo ci sono pochissimi componenti: un condensatore di disaccoppiamento sull'alimentazione, un piccolo condensatore sul pin FILTER che fissa la banda passante, il LED di accensione (D1) e la sua resistenza (R1). Il 102 stampato su R1 significa 1 kΩ; puoi decifrare questi codici facilmente con il calcolatore di codici SMD. Poiché l'ACS712 è isolato, se misuri solo la corrente non serve collegare il negativo del circuito misurato al GND di Arduino.

Passo dopo passo: misurare la corrente continua con Arduino

  1. Collega VCC del modulo al pin 5V di Arduino, GND a GND e OUT ad A0. Il LED di accensione sulla scheda deve illuminarsi.
  2. Taglia il filo positivo del circuito da misurare: il capo che arriva dall'alimentatore va su un lato del morsetto, quello che va al carico (per esempio un motore a 12 V o una striscia LED) sull'altro.
  3. Lascia spento l'alimentatore del carico e carica lo sketch qui sotto. All'avvio misura il punto zero mentre non scorre corrente.
  4. Apri il Monitor seriale a 9600 baud; senza corrente il valore deve restare intorno a 0,00 A e oscillare al massimo di qualche centesimo di ampere.
  5. Accendi l'alimentatore del carico. Se la corrente risulta negativa, scambia i due fili nel morsetto oppure moltiplica il risultato per −1.
  6. Imposta SENSITIVITY nel codice in base al tuo modello: 0.185 per il 5A, 0.100 per il 20A e 0.066 per il 30A.
C++ (Arduino IDE)
1// ACS712 ile DC akım ölçme / DC current measurement with ACS712
2const int SENSOR_PIN = A0;            // ACS712 OUT pini / ACS712 OUT pin
3const float SENSITIVITY = 0.185;      // V/A: 5A=0.185, 20A=0.100, 30A=0.066
4const float ADC_STEP = 5.0 / 1024.0;  // bir ADC basamağı (V) / one ADC step (V)
5const int SAMPLES = 200;              // ortalama için örnek sayısı / samples to average
6
7float zeroRaw = 512.0;                // akım yokken ham değer / raw value at zero current
8
9// SAMPLES kez okuyup ortalamayı döndürür / reads SAMPLES times and returns the average
10float readAverageRaw() {
11  long sum = 0;
12  for (int i = 0; i < SAMPLES; i++) {
13    sum += analogRead(SENSOR_PIN);
14  }
15  return sum / (float)SAMPLES;
16}
17
18void setup() {
19  Serial.begin(9600);
20  delay(500);                         // sensörün oturmasını bekle / let the sensor settle
21  zeroRaw = readAverageRaw();         // yük KAPALIYKEN sıfır noktası / zero point with the load OFF
22  Serial.print(F("Sifir noktasi / Zero point: "));
23  Serial.print(zeroRaw * ADC_STEP, 3);
24  Serial.println(F(" V"));
25}
26
27void loop() {
28  float raw = readAverageRaw();
29  float current = (raw - zeroRaw) * ADC_STEP / SENSITIVITY;  // amper / amps
30
31  Serial.print(F("Akim / Current: "));
32  Serial.print(current, 2);
33  Serial.println(F(" A"));
34  delay(500);
35}

A ogni misura lo sketch fa la media di 200 letture analogRead; poiché una analogRead richiede circa 0,11 ms su Arduino Uno, servono circa 22 ms. La corrente si ricava con I = (grezzo − zero) × (5 / 1024) / sensibilità. Per esempio, nel modello da 5A con punto zero a 512, una media di 550 è una differenza di 38 passi; cioè 38 × 4,88 mV = 185,5 mV, e la corrente è 185,5 / 185 ≈ 1,00 A. Misurare il punto zero all'avvio invece di supporre 2,5 V è importante, perché l'offset del chip e piccole differenze sulla linea di massa della scheda lo spostano di qualche passo, e quell'errore si somma a ogni lettura.

Quando leggi l'ACS712 con Arduino Uno non cambiare il riferimento con qualcosa come analogReference(INTERNAL): usa il riferimento predefinito a 5 V. Dato che l'ACS712 è raziometrico, anche se la tensione USB scende a 4,8 V, l'uscita del sensore e il riferimento dell'ADC si riducono nella stessa proporzione; i valori grezzi non cambiano e il 5.0 nel codice resta corretto da solo. ESP32 e Pico non hanno questo vantaggio perché il loro riferimento ADC non dipende dall'alimentazione; lì faremo una piccola correzione partendo dal punto zero.

Rumore e media delle letture

L'uscita dell'ACS712 trema di continuo anche con corrente costante. La prima causa è il rumore del sensore Hall: il produttore dichiara i valori di rumore visti sopra con un condensatore da 47 nF sul pin FILTER, cioè con circa 2 kHz di banda. La maggior parte dei moduli però monta lì solo 1 nF, come il circuito di esempio del produttore; la banda sale a 80 kHz e il rumore è parecchie volte più alto. La seconda causa è l'ADC: anche con il modello da 5A, Arduino Uno misura a passi di 26 mA e l'ultimo passo oscilla sempre su e giù. Il rumore casuale diminuisce con la radice quadrata del numero di campioni mediati: 16 campioni lo riducono a un quarto, 256 a un sedicesimo. Per altri metodi di filtraggio consulta la nostra guida per filtrare i dati dei sensori.

  • Media di molti campioni: in continua fai la media di 100–500 campioni. Se li distribuisci su 20 ms, anche il disturbo a 50 Hz della rete si annulla nella media.
  • Media mobile esponenziale: mescola ogni nuova lettura con la precedente con filtro = filtro + 0,1 × (nuovo − filtro); usa pochissima memoria e dà un valore stabile sul display.
  • Zona morta: se non vuoi vedere valori come 0,03 A senza nulla collegato, considera 0 i risultati con valore assoluto inferiore a 0,05 A.
  • Filtro hardware: se sai saldare, aggiungi 47 nF in parallelo al condensatore del pin FILTER per ridurre la banda a circa 2 kHz; per la continua e per la corrente di rete a 50 Hz basta e avanza.
  • Tienilo lontano dai campi magnetici: l'ACS712 è un sensore Hall; un magnete, un altoparlante o un altro cavo percorso da forte corrente nelle vicinanze falsano la lettura.
  • Aggiorna il punto zero: il punto zero deriva di qualche millivolt con la temperatura; nei progetti che restano accesi a lungo, rimisura lo zero a carico spento.
Multimetro digitale con puntali
Per tarare l'ACS712 collega un multimetro sulla portata di corrente in serie sulla stessa linea e confronta le due letture.

La media elimina il rumore ma non corregge l'errore sistematico. La sensibilità può variare di qualche punto percentuale da chip a chip; nel modello da 5A è compresa tra 180 e 190 mV/A. Per la massima precisione collega un multimetro sulla portata di corrente in serie sulla stessa linea dell'ACS712, fai passare una corrente nota di 1–2 A e confronta i due valori. Se il multimetro segna 2,00 A e Arduino 1,94 A, il tuo fattore di correzione è 2,00 / 1,94 = 1,031; dividi SENSITIVITY nel codice per questo numero (0,185 / 1,031 ≈ 0,179) e la tua misura coinciderà con quella del multimetro.

Misurare la corrente alternata: il calcolo RMS

La corrente di rete cambia continuamente verso: in Italia e in Europa a 50 Hz, negli Stati Uniti a 60 Hz. Per questo l'uscita dell'ACS712 disegna una sinusoide intorno a 2,5 V la cui media corrisponde a corrente zero; se usi lo sketch DC su un carico in alternata, ottieni valori senza senso vicini a 0 A. In alternata conta il valore RMS (efficace): equivale alla corrente continua che produrrebbe lo stesso calore ed è il valore usato da multimetri, fusibili e targhette degli apparecchi. Il calcolo segue il suo nome inglese: togli il punto zero da ogni campione, elevalo al quadrato (Square), fai la media dei quadrati (Mean) ed estrai la radice quadrata (Root).

La durata della finestra di misura conta: se non contiene un numero intero di periodi, il risultato cambia un po' ogni volta. Un periodo dura 20 ms a 50 Hz e 16,7 ms a 60 Hz. Una finestra di 100 ms contiene esattamente 5 periodi a 50 Hz e 6 a 60 Hz, quindi funziona su entrambe le reti, e Arduino Uno raccoglie circa 900 campioni in quel tempo. In una sinusoide pura il picco vale 1,414 volte il valore RMS, perciò potresti anche dividere il picco per √2. Però carichi come caricabatterie per smartphone, lampadine LED o dimmer assorbono correnti impulsive, non sinusoidali, e questa scorciatoia sbaglia; lo sketch qui sotto calcola il vero RMS ed è molto più preciso con questi carichi. Il valore di picco deve restare entro l'intervallo del modello:

ModelloLimite di corrente di piccoCorrente AC massima (RMS, sinusoide)Potenza indicativa a 230 V
5A±5 A3,5 A≈ 800 W
20A±20 A14,1 A≈ 3250 W
30A±30 A21,2 A≈ 4900 W
C++ (Arduino IDE)
1// ACS712 ile AC akım (RMS) ve görünür güç / AC current (RMS) and apparent power with ACS712
2const int SENSOR_PIN = A0;
3const float SENSITIVITY = 0.100;      // 20A modül: 100 mV/A / 20A module: 100 mV/A
4const float ADC_STEP = 5.0 / 1024.0;
5const unsigned long WINDOW_MS = 100;  // 50 Hz'te 5, 60 Hz'te 6 tam periyot / 5 cycles at 50 Hz, 6 at 60 Hz
6const float MAINS_VOLTAGE = 230.0;    // şebeke gerilimi (V) / mains voltage (V)
7
8float noiseRms = 0.0;                 // yük yokken ölçülen gürültü (A) / noise measured with no load (A)
9
10// Pencere boyunca örnek alır, ortalamayı çıkarıp RMS hesaplar / samples over the window, removes the mean, returns RMS
11float readRmsAmps() {
12  long sum = 0;
13  unsigned long sumSq = 0;
14  unsigned int n = 0;
15  unsigned long start = millis();
16  while (millis() - start < WINDOW_MS) {
17    int d = analogRead(SENSOR_PIN) - 512;  // 2,5 V'u sıfıra yaklaştır / shift 2.5 V to about zero
18    sum += d;
19    sumSq += (long)d * d;
20    n++;
21  }
22  float mean = sum / (float)n;                       // sıfır noktası kayması / zero point offset
23  float variance = sumSq / (float)n - mean * mean;   // yalnız AC kısım / AC part only
24  if (variance < 0) variance = 0;
25  return sqrt(variance) * ADC_STEP / SENSITIVITY;
26}
27
28void setup() {
29  Serial.begin(9600);
30  delay(500);
31  noiseRms = readRmsAmps();           // ilk ölçüm yük KAPALIYKEN / first reading with the load OFF
32  Serial.print(F("Gurultu / Noise: "));
33  Serial.print(noiseRms, 3);
34  Serial.println(F(" A"));
35}
36
37void loop() {
38  float irms = readRmsAmps();
39  float sq = irms * irms - noiseRms * noiseRms;  // gürültüyü karesel çıkar / subtract noise in quadrature
40  irms = (sq > 0) ? sqrt(sq) : 0.0;
41  float apparentPower = MAINS_VOLTAGE * irms;     // VA; dirençli yükte ≈ W / VA; ≈ W for resistive loads
42
43  Serial.print(F("Irms: "));
44  Serial.print(irms, 3);
45  Serial.print(F(" A   Guc / Power: "));
46  Serial.print(apparentPower, 1);
47  Serial.println(F(" VA"));
48  delay(1000);
49}

Questo sketch non memorizza il punto zero come numero fisso; in ogni finestra calcola la media dei campioni e la sottrae. Matematicamente è la radice quadrata della varianza: RMS² = media dei quadrati − quadrato della media. Poiché la corrente alternata ha media nulla su un numero intero di periodi, la media trovata è proprio l'errore del punto zero, che così si corregge da solo anche se varia con la temperatura. Il rumore misurato all'avvio a carico spento viene sottratto in quadratura, perché rumore e corrente reale sono indipendenti e i valori RMS si sommano attraverso i loro quadrati. Senza questo passaggio vedresti valori fantasma come 0,1 A e 23 VA con niente collegato. Un esempio: un ferro da stiro da 1000 W assorbe circa 4,35 A a 230 V; il suo picco di 6,1 A supera l'intervallo del modello da 5A, quindi misuralo con il 20A.

La tensione di rete può uccidere. L'isolamento all'interno del chip ACS712 è robusto (tenuta di 2,4 kV RMS), ma nei moduli economici le viti del morsetto e le saldature sul lato inferiore della scheda sono a tensione di rete e restano scoperte. Fai i collegamenti solo con la spina staccata, chiudi il modulo in una scatola di plastica, aggiungi un fusibile sulla linea e non toccare nulla quando il circuito è in tensione. Misurare la rete con Arduino collegato al computer via USB mette a rischio anche il computer in caso di guasto; è più sicuro mostrare i risultati su un display o inviarli senza fili con un ESP32. Se non hai esperienza di impianti elettrici, non fare questo esperimento da solo; se sei uno studente, lavora sempre con un adulto esperto di elettricità.

Un modo molto più sicuro per misurare la corrente di un elettrodomestico è un trasformatore di corrente a nucleo apribile come lo SCT-013, che si usa senza tagliare alcun filo. Si chiude attorno al cavo come una pinza amperometrica e non ha alcun contatto metallico con la rete. L'unica attenzione è che la pinza abbracci solo la fase o solo il neutro; se abbracci entrambi i conduttori, i campi delle correnti opposte si annullano e il risultato è zero. I trasformatori di corrente misurano solo l'alternata; per la continua serve l'ACS712 o l'INA219.

Calcolo di potenza (W) ed energia (Wh)

Una volta nota la corrente, la potenza è una semplice moltiplicazione: P = V × I. Se una batteria da 12 V alimenta un motore che assorbe 1,5 A, la potenza è 12 × 1,5 = 18 W; puoi verificarlo con il calcolatore della legge di Ohm. L'energia è la potenza moltiplicata per il tempo: se il motore da 18 W gira per 2 ore, consuma 36 Wh. Lo sketch lo fa moltiplicando a ogni lettura la potenza per il tempo trascorso e sommando. Per misurare la tensione puoi usare il modulo venduto come sensore di tensione 0–25 V; contiene un partitore di tensione da 30 kΩ e 7,5 kΩ che divide per 5 la tensione d'ingresso. Se vuoi progettare un partitore con i tuoi valori, usa il calcolatore del partitore di tensione.

C++ (Arduino IDE)
1// ACS712 + gerilim sensörü ile güç (W) ve enerji (Wh) / power (W) and energy (Wh) with ACS712 + voltage sensor
2const int CURRENT_PIN = A0;           // ACS712 OUT
3const int VOLTAGE_PIN = A1;           // 0-25 V gerilim sensörü S pini / 0-25 V voltage sensor S pin
4const float SENSITIVITY = 0.185;      // 5A modül / 5A module (V/A)
5const float DIVIDER_RATIO = 5.0;      // (30k + 7,5k) / 7,5k = 5 / divider ratio
6const float ADC_STEP = 5.0 / 1024.0;
7const int SAMPLES = 200;
8
9float zeroRaw = 512.0;
10float energyWh = 0.0;                 // biriken enerji / accumulated energy
11unsigned long lastMs = 0;
12
13float averageRaw(int pin) {
14  long sum = 0;
15  for (int i = 0; i < SAMPLES; i++) sum += analogRead(pin);
16  return sum / (float)SAMPLES;
17}
18
19void setup() {
20  Serial.begin(9600);
21  delay(500);
22  zeroRaw = averageRaw(CURRENT_PIN);  // yük kapalıyken sıfır noktası / zero point with the load off
23  lastMs = millis();
24}
25
26void loop() {
27  float current = (averageRaw(CURRENT_PIN) - zeroRaw) * ADC_STEP / SENSITIVITY;
28  float voltage = averageRaw(VOLTAGE_PIN) * ADC_STEP * DIVIDER_RATIO;
29  float power = voltage * current;    // P = V x I (W)
30
31  unsigned long now = millis();
32  energyWh += power * (now - lastMs) / 3600000.0;  // W x saat = Wh / W x hours = Wh
33  lastMs = now;
34
35  Serial.print(voltage, 2);  Serial.print(F(" V   "));
36  Serial.print(current, 2);  Serial.print(F(" A   "));
37  Serial.print(power, 1);    Serial.print(F(" W   "));
38  Serial.print(energyWh, 3); Serial.println(F(" Wh"));
39  delay(1000);
40}

Poiché il modulo di tensione va collegato tra il positivo e il negativo del circuito misurato, questa volta il negativo del circuito e il GND di Arduino devono essere uniti; il perché lo trovi nella guida sulla massa comune. Per stimare quante ore durerà una batteria, combina la corrente media misurata con i calcoli in mAh e Wh oppure con il calcolatore della durata della batteria. In alternata le cose cambiano un po': Vrms × Irms è la potenza apparente, in VA; la potenza attiva (W) è questo valore moltiplicato per il fattore di potenza. Nei carichi resistivi come bollitori, ferri da stiro e lampadine a incandescenza il fattore di potenza è vicinissimo a 1, quindi VA ≈ W. In motori, alimentatori e lampadine LED può stare tra 0,5 e 0,9; per misurare la potenza attiva reale bisogna campionare contemporaneamente anche la forma d'onda della tensione, con moduli sensori di tensione isolati come lo ZMPT101B.

ACS712 con ESP32: lettura tramite partitore di tensione

L'ESP32 funziona a 3,3 V e i suoi ingressi analogici misurano fino a circa 3,1 V; applicare più di 3,6 V a un pin può danneggiare la scheda. L'ACS712 invece funziona solo a 5 V e la sua uscita può arrivare a 4,5 V nei modelli da 20A e 30A e quasi a 5 V in sovracorrente. Per questo alimenti il sensore dal pin 5V della scheda ESP32 (VIN su alcune schede) e fai passare OUT attraverso un partitore di tensione. 10 kΩ + 20 kΩ è una buona scelta: da OUT al pin dell'ESP32 attraverso 10 kΩ, e dallo stesso punto verso GND attraverso 20 kΩ. Il rapporto è 20 / 30 = 0,667, e i 30 kΩ totali rispettano senza problemi il carico minimo di 4,7 kΩ richiesto dall'ACS712.

Uscita ACS712SignificatoTensione sul pin dell'ESP32
0,50 V−20 A nel modello da 20A0,33 V
2,50 VCorrente zero1,67 V
4,50 V+20 A nel modello da 20A3,00 V
5,00 VSaturazione in sovracorrente3,33 V

Nel codice ci sono due dettagli. Primo, l'ADC dell'ESP32 non è lineare agli estremi; invece dei valori grezzi usiamo quindi analogReadMilliVolts(), che applica i dati di calibrazione scritti nel chip in fabbrica. Il GPIO 34 appartiene all'ADC1 e funziona anche con il Wi-Fi attivo; i pin dell'ADC2 non si possono usare insieme al Wi-Fi. Secondo, qui manca il vantaggio raziometrico di Arduino Uno: il riferimento ADC dell'ESP32 è fisso, ma la sensibilità dell'ACS712 cambia con i 5 V che arrivano dall'USB. La soluzione è un trucco semplice: dato che senza corrente l'uscita è metà di VCC, moltiplichi per 2 il punto zero misurato all'avvio, ottieni la vera tensione di alimentazione del sensore e correggi la sensibilità di conseguenza. Siccome lo stesso errore è presente sia nel punto zero sia nel segnale misurato, questo metodo compensa anche la tolleranza delle resistenze del partitore. Lo sketch campiona per 100 ms e restituisce due risultati insieme: guarda il primo con un carico in continua e il secondo con un apparecchio di rete.

C++ (Arduino IDE)
1// ESP32 + ACS712 (10k/20k gerilim bölücüyle) / ESP32 + ACS712 (with a 10k/20k voltage divider)
2const int SENSOR_PIN = 34;            // ADC1_CH6, Wi-Fi açıkken de çalışır / works while Wi-Fi is on
3const float DIVIDER = 20.0 / 30.0;    // R2 / (R1 + R2) = 20k / 30k
4const float SENS_AT_5V = 185.0;       // mV/A: 5A=185, 20A=100, 30A=66
5const unsigned long WINDOW_MS = 100;  // 50 Hz'te 5 tam periyot / 5 full cycles at 50 Hz
6
7float zeroMv = 2500.0;                // akım yokken sensör çıkışı (mV) / sensor output at zero current (mV)
8float sensMv = SENS_AT_5V;            // düzeltilmiş hassasiyet (mV/A) / corrected sensitivity (mV/A)
9
10// Bölücüden önceki gerilimin ortalaması (mV) / average voltage before the divider (mV)
11float averageMv(int samples) {
12  uint32_t sum = 0;
13  for (int i = 0; i < samples; i++) sum += analogReadMilliVolts(SENSOR_PIN);
14  return sum / (float)samples / DIVIDER;
15}
16
17// Pencere boyunca okur: DC (ortalama) ve AC (RMS) akım / reads over the window: DC (mean) and AC (RMS) current
18void measure(float &dcAmps, float &acAmps) {
19  double sum = 0, sumSq = 0;
20  uint32_t n = 0;
21  uint32_t start = millis();
22  while (millis() - start < WINDOW_MS) {
23    double d = analogReadMilliVolts(SENSOR_PIN) / DIVIDER - zeroMv;
24    sum += d;
25    sumSq += d * d;
26    n++;
27  }
28  double mean = sum / n;
29  double variance = sumSq / n - mean * mean;
30  if (variance < 0) variance = 0;
31  dcAmps = mean / sensMv;
32  acAmps = sqrt(variance) / sensMv;
33}
34
35void setup() {
36  Serial.begin(115200);
37  analogReadResolution(12);
38  delay(500);
39  zeroMv = averageMv(1000);                    // yük KAPALIYKEN / with the load OFF
40  sensMv = SENS_AT_5V * (2.0 * zeroMv) / 5000.0;  // oransal düzeltme: VCC = 2 x sıfır / ratiometric fix: VCC = 2 x zero
41  Serial.printf("Sifir / Zero: %.0f mV  Hassasiyet / Sensitivity: %.1f mV/A\n", zeroMv, sensMv);
42}
43
44void loop() {
45  float dc, ac;
46  measure(dc, ac);
47  Serial.printf("DC: %.2f A   AC (RMS): %.2f A\n", dc, ac);
48  delay(1000);
49}

ACS712 con Raspberry Pi Pico e MicroPython

Anche il Raspberry Pi Pico funziona a 3,3 V, quindi il collegamento è uguale a quello dell'ESP32: collega VCC dell'ACS712 a VBUS (pin 40), che fornisce 5 V quando il Pico è alimentato via USB, e OUT a GP26 (ADC0, pin 31) tramite lo stesso partitore 10k/20k. In MicroPython read_u16() restituisce un valore da 0 a 65535 e la tensione = grezzo × 3,3 / 65535. L'ADC del Pico è a 12 bit; con il partitore, sulla carta misura a passi di circa 6,5 mA con il modello da 5A, cioè circa quattro volte più fine di Arduino Uno. Il codice qui sotto misura il punto zero all'avvio, applica la correzione raziometrica e poi stampa ogni secondo la corrente continua e il valore RMS della corrente alternata.

MicroPython
1from machine import ADC
2import time
3import math
4
5adc = ADC(26)            # GP26 = ADC0, fiziksel pin 31 / physical pin 31
6VREF = 3.3               # ADC referansı (V) / ADC reference (V)
7DIVIDER = 20 / 30        # 10k/20k bölücü oranı / 10k/20k divider ratio
8SENS_AT_5V = 0.185       # V/A: 5A=0.185, 20A=0.100, 30A=0.066
9
10
11def read_volts(samples=200):
12    # bölücüden önceki ortalama gerilim / average voltage before the divider
13    total = 0
14    for _ in range(samples):
15        total += adc.read_u16()          # 0-65535
16    return total / samples * VREF / 65535 / DIVIDER
17
18
19zero = read_volts(1000)                  # yük KAPALIYKEN / with the load OFF
20sens = SENS_AT_5V * (2 * zero) / 5.0     # oransal düzeltme / ratiometric correction
21print("Sifir / Zero: {:.3f} V".format(zero))
22
23
24def read_rms(window_ms=100):
25    # 100 ms = 50 Hz'te 5 periyot / 5 cycles at 50 Hz
26    n = 0
27    s = 0.0
28    s2 = 0.0
29    start = time.ticks_ms()
30    while time.ticks_diff(time.ticks_ms(), start) < window_ms:
31        v = adc.read_u16() * VREF / 65535 / DIVIDER - zero
32        s += v
33        s2 += v * v
34        n += 1
35    mean = s / n
36    return math.sqrt(max(s2 / n - mean * mean, 0)) / sens
37
38
39while True:
40    dc = (read_volts() - zero) / sens
41    print("DC: {:.2f} A   AC (RMS): {:.2f} A".format(dc, read_rms()))
42    time.sleep(1)

ACS712 o INA219?

L'INA219 è un chip di misura di corrente e tensione di Texas Instruments che comunica via I2C. Invece dell'effetto Hall, misura la caduta di tensione su una piccola resistenza di shunt (di solito 0,1 Ω sui moduli) attraversata dalla corrente. I moduli più diffusi misurano fino a ±3,2 A con una risoluzione di circa 0,8 mA, leggono da soli la tensione del bus fino a 26 V e calcolano la potenza all'interno del chip. Con un solo collegamento I2C ottieni quindi tensione, corrente e potenza insieme, senza preoccuparti di ADC, medie o taratura dello zero. In compenso non c'è isolamento tra il circuito misurato e Arduino, non misura la corrente alternata e non va oltre i 26 V.

CaratteristicaACS712Modulo INA219
Metodo di misuraEffetto Hall (magnetico)Resistenza di shunt (0,1 Ω)
Intervallo di corrente±5 / ±20 / ±30 A±3,2 A (dipende dallo shunt)
Risoluzione26–74 mA con Arduino Uno≈ 0,8 mA
Corrente alternataSìNo
Misura di tensione e potenzaNo (serve un partitore separato)Sì (fino a 26 V)
IsolamentoSìNo
InterfacciaUscita analogicaI2C (indirizzo 0x40–0x4F)
AlimentazioneSolo 5 V3–5,5 V
Uso idealeMotori, stufe, apparecchi di rete, correnti elevateBatterie, pannelli solari, consumo di sensori e schede
C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_INA219.h>
3
4Adafruit_INA219 ina219;               // varsayılan adres 0x40 / default address 0x40
5
6void setup() {
7  Serial.begin(9600);
8  if (!ina219.begin()) {
9    Serial.println(F("INA219 bulunamadi / INA219 not found"));
10    while (true) delay(10);
11  }
12  // ina219.setCalibration_16V_400mA();  // küçük akımda daha ince çözünürlük / finer resolution for small currents
13}
14
15void loop() {
16  float busV = ina219.getBusVoltage_V();        // yük tarafındaki gerilim / voltage on the load side
17  float current_mA = ina219.getCurrent_mA();    // akım (mA) / current (mA)
18  float power_mW = ina219.getPower_mW();        // güç (mW) / power (mW)
19
20  Serial.print(busV, 2);       Serial.print(F(" V   "));
21  Serial.print(current_mA, 1); Serial.print(F(" mA   "));
22  Serial.print(power_mW, 0);   Serial.println(F(" mW"));
23  delay(1000);
24}

Per il codice installa la libreria Adafruit INA219 dal Gestore librerie. Collega SDA e SCL del modulo ad A4 e A5 su Arduino Uno; la corrente da misurare deve entrare da VIN+ e uscire da VIN− verso il carico, e il GND dell'INA219 deve essere in comune con il circuito misurato. In breve: per misurare corrente continua da pochi milliampere fino a 3 A insieme alla tensione scegli l'INA219; se ti servono correnti più alte, corrente alternata o isolamento, l'ACS712 è la scelta giusta.

Idee di progetto con l'ACS712

  • Protezione del motore da sovracorrente: quando un motore DC pilotato con un L298N si blocca, la corrente schizza in alto; ferma il motore e fai suonare un allarme appena superi la tua soglia.
  • Monitor per batteria e pannello solare: misura la corrente di carica e scarica con il suo verso, moltiplicala per la tensione, accumula i Wh e mostra i risultati su un display OLED.
  • Presa intelligente: comanda la presa con un modulo relè, verifica con l'ACS712 se l'apparecchio funziona davvero e invia i dati a Home Assistant via MQTT.
  • Avviso fine lavatrice: quando la corrente resta per qualche minuto sotto un certo valore, l'ESP32 ti manda un messaggio su Telegram.
  • Allarme pompa a secco: quando l'acqua finisce, la corrente assorbita dalla pompa cala; rilevalo e spegni la pompa.
  • Registratore di energia: salva corrente e potenza una volta al minuto su una scheda SD o su Fogli Google e traccia il grafico dei consumi giornalieri.
  • Wattmetro da banco: aggiungi un ACS712 al progetto del voltmetro con Arduino per costruire uno strumento che mostra tensione, corrente e potenza sullo stesso display.

Errori comuni e soluzioni

SintomoCausa probabileSoluzione
Segna 0,1–0,3 A senza correnteIl codice suppone il punto zero a 2,5 V o 512Misura il punto zero all'avvio a carico spento e aggiungi una piccola zona morta
Il valore salta di continuoLetture singole, banda ampia del filtro da 1 nFFai la media di 100–500 campioni; se serve aggiungi 47 nF su FILTER
La corrente risulta negativaLa corrente attraversa il morsetto nel verso oppostoScambia i fili o moltiplica il risultato per −1
Valori vicini a 0 A con carico ACUsato il codice DC; una sinusoide ha media nullaUsa lo sketch che calcola l'RMS
Valori sempre più alti o più bassi di qualche punto percentualeValore del modello sbagliato o tolleranza della sensibilitàScegli 0.185, 0.100 o 0.066 in base alla sigla del chip e tara con un multimetro
Il valore grezzo resta fisso a 0 o 1023OUT sul pin sbagliato o collegato a VCC, corrente oltre l'intervalloControlla i collegamenti e, se serve, scegli un modello più grande
L'alimentatore si spegne, il cavo scaldaMorsetto collegato in parallelo alla sorgente (cortocircuito)Collega il modulo in serie al carico
Valori incoerenti sull'ESP32Niente partitore, pin ADC2 o analogRead grezzaUsa partitore 10k/20k, GPIO 34 e analogReadMilliVolts
La lettura cambia vicino a un magneteIl sensore Hall rileva il campo magnetico esternoTieni il modulo lontano da magneti, altoparlanti e cavi con forte corrente
Il modo più semplice per verificare se il tuo sensore di corrente funziona è usare un carico noto. Per esempio, una resistenza da 10 Ω collegata a 12 V assorbe 1,2 A secondo la legge di Ohm e trasforma 14,4 W in calore; scegli quindi una resistenza di potenza da almeno 20–25 W. Se misuri circa 1,2 A, collegamenti e codice sono corretti.

L'ACS712 è un ottimo punto di partenza per imparare a misurare la corrente: con un solo pin analogico misuri corrente continua e alternata, e con poche righe di codice anche potenza ed energia. Se scegli il modello giusto, misuri il punto zero, fai la media e tari con un multimetro, otterrai risultati affidabili entro pochi punti percentuali. Puoi consolidare le basi della lettura analogica nella nostra guida all'ADC. Nell'app BlueGrays trovi progetti come la lettura di sensori analogici, un voltmetro digitale con LCD, il comando di una lampadina a 230 V con relè e un datalogger con ESP32, ciascuno con schema elettrico e codice passo dopo passo.

Domande frequenti

Quanti ampere misura l'ACS712 e quale modello scegliere?

L'ACS712 esiste in tre modelli da ±5 A, ±20 A e ±30 A, con sensibilità di 185, 100 e 66 mV/A. Scegli il modello più piccolo che copre la corrente massima da misurare (in alternata il valore di picco); un modello più piccolo dà una variazione d'uscita maggiore e una risoluzione migliore a parità di corrente. Riconosci il modello dalla sigla ELC-05B, ELC-20A o ELC-30A sul chip.

Perché l'ACS712 dà 2,5 V senza corrente?

L'uscita parte da metà della tensione di alimentazione perché l'ACS712 possa misurare la corrente in entrambi i versi. Quando la corrente scorre in un verso l'uscita sale sopra 2,5 V, nel verso opposto scende sotto. Se l'alimentazione non è esattamente 5 V, il punto zero si sposta a VCC / 2; per questo conviene misurarlo all'avvio.

Si può misurare la corrente di rete a 230 V con l'ACS712?

Sì, il chip ha una tenuta di isolamento di 2,4 kV RMS; a 230 V il modello da 5A va bene fino a circa 800 W e il 20A fino a circa 3250 W. Però il morsetto e le saldature del modulo sono a tensione di rete: collegalo solo con la spina staccata, chiudilo in una scatola e non lavorare da solo se non hai esperienza. Un'alternativa più sicura è un trasformatore di corrente a pinza come lo SCT-013, che non richiede di tagliare cavi.

L'ACS712 funziona con ESP32 o a 3,3 V?

L'ACS712 richiede 4,5–5,5 V e a 3,3 V non dà risultati corretti. Su ESP32 e Raspberry Pi Pico alimenta il modulo dal pin 5V, VIN o VBUS e porta l'uscita al pin analogico tramite un partitore da 10 kΩ + 20 kΩ. Così anche un'uscita vicina a 5 V resta sotto 3,33 V sul pin.

Perché l'ACS712 non segna zero senza corrente?

I motivi sono due: il codice suppone il punto zero esattamente a 2,5 V o 512, e il sensore ha un suo rumore. Misura il punto zero all'avvio a carico spento, fai la media di 100–500 campioni e aggiungi una piccola zona morta di circa 0,05 A. In alternata, sottraendo il rumore in quadratura elimini la corrente fantasma che compare a riposo.

Meglio ACS712 o INA219?

Dipende dall'uso. L'INA219 lavora in I2C e fornisce corrente, tensione e potenza insieme con circa 0,8 mA di risoluzione fino a ±3,2 A, quindi è molto più preciso per batterie e piccoli circuiti in continua. L'ACS712 misura fino a 30 A, legge anche la corrente alternata e isola il circuito misurato da Arduino.

Vedi tutti i progetti
Misurare l'intensità luminosa con LDR
#11Principiante

Misurare l'intensità luminosa con LDR

Vuoi vedere quanto è luminosa la tua stanza sotto forma di numero? L'LDR, un piccolo componente sensibile alla luce, misura la luce ambiente e l'Arduino scrive il valore sullo schermo del computer ogn

4.6(81)
139
Lettura dell'intensità luminosa con il modulo LDR ESP32
#113Principiante

Lettura dell'intensità luminosa con il modulo LDR ESP32

Monitoraggio in tempo reale sul Serial Monitor del valore grezzo dell'ADC del modulo LDR e della percentuale relativa di luce calcolata dai valori di riferimento al buio e alla luce. Questa percentuale non è una misurazione in lux. Spiega il principio di calibrazione del modulo. È consigliabile eseguirlo prima del Progetto 10, poiché serve a determinare il valore di soglia.

4.6(36)
55
Voltmetro digitale con display LCD
#56Intermedio
Premium

Voltmetro digitale con display LCD

Scopri quanta tensione dà una pila o un alimentatore con uno strumento costruito da te. Un partitore fatto di due resistenze abbassa la tensione alta a un livello che la scheda può leggere, e l'Arduin

4.5(27)
36
Lampadina 220V con pulsante (Push)
#19Avanzato
Premium

Lampadina 220V con pulsante (Push)

Finché tieni premuto il pulsante, una vera lampadina da 220 volt resta accesa, e si spegne appena lo lasci. Il piccolo segnale dell'Arduino non può accendere la lampadina direttamente, quindi in mezzo

4.4(30)
38
Luminosità di un LED con Potenziometro su ESP32 (Analogico → PWM)
#115Intermedio
Premium

Luminosità di un LED con Potenziometro su ESP32 (Analogico → PWM)

In questo progetto controlliamo in modo analogico la luminosità di un LED tramite un potenziometro. Il pin ADC dell'ESP32 legge la tensione tra 0 e 3,3 V dal potenziometro; il valore viene convertito in un segnale PWM (Pulse Width Modulation) e inviato al LED. Ruotando il potenziometro, il LED si accende e si spegne gradualmente. Con Arduino Core 3.0+ si usa direttamente analogWrite(); su ESP32-S2/S3 la risoluzione dell'ADC è fissata a 12 bit.

4.5(19)
32
Utilizzo dello schermo LCD con I2C
#32Principiante
Premium

Utilizzo dello schermo LCD con I2C

Regala al tuo Arduino uno schermo tutto suo e fagli scrivere il primo messaggio. Lo schermo LCD a due righe si collega con pochi fili; prima compare un saluto nella riga in alto, poi un secondo testo

4.8(53)
70
Schermo LCD I2C per ESP32 (16x2)
#119Intermedio
Premium

Schermo LCD I2C per ESP32 (16x2)

In questo progetto visualizziamo del testo collegando un display LCD a 16x2 caratteri all'ESP32 tramite il protocollo I2C. Grazie all'I2C possiamo controllare il display utilizzando solo 2 pin di dati (SDA e SCL); si elimina così lo spreco dei 6+ pin tipici del collegamento parallelo classico. Il codice stampa un messaggio fisso sulla prima riga e un contatore che aumenta ogni secondo sulla seconda riga. Inoltre, all'inizio, eseguendo lo scanner I2C, stampiamo l'indirizzo del display sul Serial

4.9(23)
40
Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avanzato
Premium

Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Costruisci un data logger di temperatura con timestamp usando ESP32! Leggi temperatura/umidità dal DHT22 ogni minuto, ottieni l'ora reale dal DS1307 RTC e registra su scheda microSD in formato CSV. L'OLED mostra dal vivo temperatura (font grande), percentuale di umidità, timestamp e contatore di log. Il file /temp_log.csv sulla scheda SD si apre in Excel, Google Sheets o Python pandas per l'analisi — perfetto per il monitoraggio di serre, tracciamento della temperatura domestica, raccolta

4.7(7)
12