The following project was designed for a need: with my friend Davide I’m working on a model railway (Il Plastico di Davide e Luca): we needed to know how much current it uses to size our power supplies (booster)…
The sensor
For current measurement, I used ACS712 sensor from Allegro MicroSystems (here’s its datasheet). You can find 3 models of this integrated circuit, depending on the maximum measured current (5-20-30A); for our requirements I chose the 5A model.
ACS712 is very easy to use: voltage across VIOUT and ground PIN is proportional to current flowing between IP+ e IP-. It requires a power supply of 5V (VCC) and two capacitors to filter power supply and output; on its datasheet you can find the typical application:

The chip is sold in a SOIC package; SparkFun sells a convenient breakout board with ACS712 presoldered. I connected that board to a perfboard where I soldered the two capacitors and three PINs for Arduino connection:
Measurement
As I wrote, output voltage is proportional to input current. The value that links the two measurements is sensitivity (you can find it on the datasheet) which – for 5A model – has a typical value of 185mV/A. The sensor can measure positive and negative currents (range -5A…5A), so if input current is 0, output value is 2.5V.
We’re going to read output value with one of the analog inputs of Arduino and its analogRead() function. That function outputs a value between 0 (0V in input) and 1023 (5V in input) that is 0,0049V for each increment.
The formula you need to convert units from analogRead() to Ampere is:

Arduino
Arduino sketch is very simple: it reads the value on AN0 PIN, converts it with the formula above and sends the result to a Personal Computer via serial connection. My PC is running AnalogDemo software which plots data to a chart and updates a feed on Pachube.
ACS712 measures an instant value; my first tests showed that the measure was too floating, that’s the reason why the sketch below reads 1000 values, computes an average and sends it to my PC. analogRead() needs about 0.1ms for each reading, if you want a value for each second, you need a delay of 1ms in the loop:
void setup() { Serial.begin(9600); } void loop() { float average = 0; for(int i = 0; i < 1000; i++) { average = average + (.0264 * analogRead(A0) -13.51) / 1000; delay(1); } Serial.println(average); } |
Test
To test the accuracy of my sensor, I used a microcontrolled battery charger, with the ACS712 between its outputs and the battery pack in charging:
I was able to found a very close match between the output current shown by the charger and the values read by the current sensor.
Get on the train!
Last Saturday we used the circuit with our model railway, here you can read about the test and watch a short video with the circuit running during a small short-circuit.
Notes
If you read the sensor’s output with Arduino, you have a resolution of about 0,026A (the value you get from analogRead() increases by a unit every 0.026A). To improve the resolution, you can add an opAmp which extends the output range; SparkFun again sells a breakout board with that improvement.












Hi, thanks for the very useful post. I do have a question: how do I choose the value for the two capacitors?
Hello!
You can use the values (1nF for filtering and 100nF as bypass) suggested in the datasheet.
I tried your sketch, and have a .25A load (a lightbulb) and I am not seeing any current whatsoever.
I’m trying to measure current on 120V AC.
Hi Patrick,
are you using the same breakout board from SparkFun? Do you see anything on the serial terminal?
i have use this sketch for AC power supply, but the value that shown in serial monitor is very fluctuate.
is this sketch for DC only or i can use this sketch for AC?
thanks
Hi!
ACS712 is suitable for DC and AC… it gives you only the “actual” measure: as you can see my sketch calculate a mean of 1000 samples… try to increment that number and let me know!
Please, could you help me about the ACS712?
I want to know about the low value that we can measure with ACS712. For example I need to measure a mobilep phone current, near to 20mA.
Is it possible?
Thanks
Hi!
Of course you can… just add an OpAmp to increase ACS712 sensitivity, or buy this breakout from SparkFun:
http://www.sparkfun.com/products/8883
bye
Hello,
I think that this sketch can’t be used to sense AC. The ACS712 will output the measure, but as the incomming current is bipolar (sometimes +I and sometimes -I), the value will change up and down. If you make an average, the result will be always around 0A (or 2.5V). I’m lookiing for another solution…
hi luca, I’m from Brazil. Thansks for your help. The project works well!
I have just one more question, please!
Why we use (-13, 51)?
Thanks again I’m very happy!
Hi Vinicius!
On ACS712 datasheet you can find the “sensitivity” value, which is 185mV/A. Sensor’s output for 0A (= no current) is 2.5V, so if you need the current value, you have to substract 2.5/0,185 which is 13.51.
bye
Luca Hello!
Please check this software, maybe it’s good for you.
http://www.blueleafsoftware.com/Resources/EmbeddedSand/MegunoLink
Very easy to use and do not reset the Arduino every time you turn on or turn off the serial port.
Bye
Just to clarify, you’re working with a DC load not an AC load?
Doesn’t seem like this sketch would work for AC.
Yes: the sensor works also with AC load but you have to change the sketch…
Hi Luca,
This all makes sense except I can’t understand why it will give values below -5A and above +5A:
If you put the value 0 in your equation for units, you get -13.51 out. If the sensor can only sense between -5 and +5, how do we get all these values outside that range?
Thanks
Hi Steve,
Have a look to ACS712′s datasheet, page 7: you can find the chart “output voltage vs sensed current”. The output voltage never goes below 1.5V so Arduino’s read value will never be 0. That means you’re not using the complete range of Arduino’s ADC and that’s the reason why SparkFun added an opAmp.
bye
Hey there,
Great tutorial. I have one question though. I am using the breakout from sparkfun:
https://www.sparkfun.com/products/8883
and I am having a problem working with the gain and vref pots.
I dont quite have a good understanding of this. Could you please explain this to me.
This is for my design project at my universtity which is due in a few days time.
Would really appreciate your advice. Thanks
sheldonreddy@gmail.com
Hi Sheldon,
SparkFun added an opAmp to their board to let you choose the output range of ACS712.
They suggest you this calibration method:
- connect the board to Arduino and read output value without any current flowing in the sensor… move Vref pot to choose the “offset” value (for example move it until you read 512)
- now use a known current value, let’s say you need to measure a max of 1A: use this value and move gain pot until you read 1023 (which is the maximum value Arduino’s ADC can read)
Now your sensor can read -1A – 1A with the maximum available resolution (1024 steps), each step is 1/512 = 0,002A
bye
Ciao Luca
Ho realizzato il progetto ma mi sono reso conto che la risoluzione di lettura della corrente non è sufficiente, quindi vorrei acquistare la breakout board con operazionale incluso per rilevare valori dell’ordine di pochi mA. Dal sito ufficiale leggo che per diminuire il rumore dovuto all’alto guadagno la larghezza di banda viene ridotta da 80 KHz a 34 Hz. Questo influisce sulla frequenza di acquisizione del dato? attualmente utilizzo 1000 rilevazioni al secondo mediate, come da tuo sketch, e non vorrei diminuire. Ti ringrazio per l’attenzione e per quanto ho trovato utile il tuo lavoro. Federico
Ciao Federico,
sì, influisce: 34Hz significa che il chip non sarà in grado di “leggere” variazioni nell’intensità della corrente più rapide di 1/34 di secondo. Questo significa che campionare a 1KHz (= 1000 campioni al secondo) è inutile, puoi abbassarlo appunto a 30 circa, che comunque ritengo sufficienti visto che eseguirai una media tra tali campioni.
Fammi sapere come va!
Ciao,
Luca complimenti per il blog ricco di spunti interessanti. Ho da poco acquistato l’ACS714 perché avrei in mente di monitorare la corrente assorbita in casa. La domanda è la seguente il criterio per determinare il valore corretto di corrente è lo stesso anche a 230 Volt in corrente alternata?
Grazie Pixel! Sì, il sensore è pensato anche per corrente alternata e dal datasheet leggo che supporta tensioni > 230V.
Fammi sapere come va!
Ciao,
grazie per la risposta… ho un dubbio relativo alla mirura del valore medio. In giro ho letto che la lettura della corrente in alternata deve essere effettuata facendo la media un pò diversamente. Tu hai qualche informazione aggiuntiva da darmi? Grazie
Ciao! In effetti per la corrente alternata normalmente si utilizza il valore RMS, che devi calcolare prendendo il valore di picco e dividendolo per la radice di 2… preparerò un esempio di sketch!
Mitico….
terrò d’occhio il blog…
Grazie e Saluti
Hi when I use the sensor i get:
2.35v = 0A
2.36 = 0.06A
2.37 = 0.1A 511 512 514 517
2.39v = 0.2A 515 522
2.41v = 0.3A
2.42v = 0.4A
2.44v = 0.5A
2.46v = 0.6A
2.48v = 0.7A
The values in the 500′s being the raw analog pin readings that seem to jump around. This sensor is the 5A version and i thought it was supposed to be 2.5v to 5v ie 512 to 1023 0 – 5A. At present it seems really restricted and notchy due to its wavering inaccuracy. Is this broken? Kind Thanks
Hi!
your sensor has a sensitivity of 185mV/A, so at its maximum (5A) you should read an output voltage of 3,425V: take a look at its datasheet, you can find a chart that plots A/Vout. With 0A you should read 2.5V, your value (2.35) seems to low; did you use the correct capacitors?
ciao luca, i’m using acs712 30A with your sketch (11.54Vdc and 12Vdc 10W globe as a test) without editing your sketch I get a reading of 0.30 which seems to low, i’m calculating 0.83, but when i edit the sketch to change sensitivity to 66mV/A i get 10.03A
where am i going wrong?
Salve luca,
sarebbe possibile utilizzare secondo te l’ACS 712 per rilevare la corrente in uscita al differenziale di casa tramite arduino? O è piu consigliato un dispositivo meno invasivo, quale ad esempio una pinza amperometrica, sempre pilotata con arduino? Ovviamente preferirei la scelta piu economica…e piu efficiente, dato che vorrei usare il sistema per monitorare l’uso di corrente in casa ed evitare che scatti il contatore, magari sfruttando un avviso acustico (sempre pilotato da arduino).
Grazie mille in anticipo
Ciao Gianfranco,
io sarei, viste anche le tensioni e correnti in gioco, per un sensore ad effetto Hall, tipo:
http://www.seeedstudio.com/depot/-p-519.html?cPath=144_154
fammi sapere come va!
What is the range of values displayed in the serial monitor of arduino?
Hi Paul,
it depends on the sensor you’re using… ACS712 is rated -5/+5A
My serial port value is not varying with the load current.It is remaining a constant value.I think it is not the problem of my circuit.I had checked the circuit several times.Can you suggest a solution for this ?
Paul: try reading the “raw” output value of the sensor with a multimeter: if it does change it could be a problem of the analog pin of your Arduino
i had tried that.But the multimter value is not changing.It remains constant.What may be the problem?
post a schematics of your sensor… how are you changing the current in it? which value do you read on your multimeter?
excellent work….keep it up friend…thankyou…:)
i have a 5a model of acs712 sensor. i had tried use the equation(above) to find current value. if the adc value is 1024, result is 13.49a. but result should be 5a for 1024. where do i make mistake can you suggest anything about this situation?
Hello! With 5A, the ACS712 sensor won’t output 5V (look at its datasheet, pag.7), but a value near 3.5V that analogRead() reads 711.
Hello luca,
Thank you for this very helpful post.
I’d like to measure AC current, but I can not find a sketch in internert and do not get it myself.
Can you or anyone else please give me such a sketch.
Hi Nikita,
the sensor measures the “actual” current, so for AC you need to decide which “value” do you want to measure.
You usually want the RMS value, that – assuming your wave is a true sine – is 0.707 times the peak value… so you need to write a sketch that measures several values, find the maximum (= peak) and calculates the RMS value.
Hello, very good design.
I did the same thing in my project that only the current sensor captures a peak current and then back to 0, I do not know what’s going on, I think he gets the current instant. Do you think my sensor may be the problem? he is not the SparkFun.
Hi Andre, is the current in your project alternate?
Hello Luca,
I am want to measure the current of a fan, I used the same example but its current returns is zero, to measure AC is different?
Hi Andre,
AC current rapidly changes, so you have to decide “which” value you want to measure. Usually, they choose the RMS value, which is the maximum value / sqrt(2). I’m going to write a tutorial about it, so stay tuned!
Ciao,
ti scrivo perchè c’è qualcosa che non mi torna molto.
Tu scrivi questa formula:
A = 0,026 * units – 13,51
Il sensore riesce a leggere tra -5A e 5A.
units varia tra 0 e 1023.
quindi in linea di principio quando esce 1023 dovrei avere 5A.
Per cui faccio questa prova sostituendo a units il valore 1023 nella tua formula è il risultato ottenuto è: 13,088A differente da quei 5A che mi aspettavo.
C’è qualcosa che non torna oppure è tutto giusto?
Se è tutto giusto avendo il sensore da 20A questa formula è corretta?
A= (0.0049 * units – 2,5)/0,1
Ciao Pier
l’errore nel tuo assunto è che l’uscita del sensore, per 5A, sia 1023 ovvero 5V. In realtà se guardi il grafico sul datasheet, vedrai che la sensibilità del sensore è 185mV/A, centrata a 2.5V. Quindi con 5A di corrente avrai una tensione in uscita di 3,425 e una lettura dell’ADC di Arduino di 712.
e quindi per il sensore da 20A sapendo che la sensibilità è 100mV/A è giusta?
A= (0.0049 * units – 2,5)/0,1
yes!
Hello Luca,
I bind AC load sensor and the connecting pin to pin Vout analog Arduino, the value read at the input A0 would be the current through the sensor. Am I right or wrong? When I put a load sensor my AC does not alter the value of output (it works as if current = 0).
For load DC the sensor works correctly.
Hi Andre
with AC loads, the output of the sensor should rapidly change following the voltage. Which value do you get from your A0 pin? Try reading it many times…
Ciao Luca
ho seguito il tuo consiglio e acquistato la breakout board di sparkfun con stadio amplificatore, però non riesco ad effettuare una misurazione stabile.
Il mio obiettivo è quello di misurare affidabilmente valori di corrente nell’ordine dei pochi mA, con una risoluzione massima di 1mA, meglio se 0.5mA. Credi che sia un traguardo raggiungibile? Ho seguito le istruzioni per la calibrazione del sensore utilizzando i tuoi valori di riferimento (0A e Vref a circa 512bit – 1A 1023bit). I problemi sorti sono due:
- Una volta terminata la calibrazione il valore calcolato con la tua formula, senza alcuna corrente nel sensore risultava di circa mezzo Ampere. Utilizzando il sensore amplificato devo utilizzare una formula diversa da quella espressa sopra?
- La lettura dei valori risulta sempre molto instabile, infatti i 512 bit di calibrazione non sono stati molto accurati. Questa fluttuazione è normale?
Ti ringrazio in anticipo, e complimenti per il tuo impegno in questo blog e nell’aiutare la comunità.
Ciao Federico,
purtroppo no, non è raggiungibile a causa delle caratteristiche fisiche del sensore (guarda le FAQ del produttore). Utilizzando cmq il modulo amplificato (a cui dedicherò un prossimo articolo) la formula va adattata in base ai settaggi del potenziometro.
Grazie Luca
purtroppo per le mie esigenze dovrò optare per uno strumento decisamente più costoso, ma apprezzo molto la tua dedizione.
Continuerò a seguire il tuo blog, in attesa del prossimo progetto
if my load is a resistor and i connect this sensor in parallel in as much its small internal resistance most of the current of the source will pass in this sensor and it will be maximum and that mean it won’t be the real load current when i remove the sensor
Hi!
This sensor must be connected in series with your load.