Sensing Current Using Hall Effect Current Sensor ACS712 and Arduino

Browsing through Arduino projects on the internet recently I came across ACS712 current Hall sensor which can be used to measure current, it can measure both AC and DC current.I found it pretty cool so I ordered one, this post is about how we can measure AC/DC current consumed by the load connected to the power supply. So of the other applications of the sensor that comes to my mind are sensing if a device is on/off, measure instability in power supply, motor control, over current fault protection, etc.

#Features list includes:

  1. Low-noise analog signal path
  2. Device bandwidth is set via the new FILTER pin
  3. 5 µs output rise time in response to step input current
  4. 80 kHz bandwidth
  5. Total output error 1.5% at TA = 25°C
  6. Small footprint, low-profile SOIC8 package
  7. 1.2 mΩ internal conductor resistance
  8. 2.1 kVRMS minimum isolation voltage from pins 1-4 to pins 5-8
  9. 5.0 V, single supply operation
  10. 66 to 185 mV/A output sensitivity
  11. Output voltage proportional to AC or DC currents
  12. Factory-trimmed for accuracy
  13. Extremely stable output offset voltage
  14. Nearly zero magnetic hysteresis
  15. Ratiometric output from supply voltage

#Required Components:

  1. Arduino Uno
  2. Current Hall Sensor ACS712
  3. Breadboard
  4. Jumper wires

#About Hall Effect Current sensor ACS712

The picture below identifies the pin outs for the ACS172 modules.

The sensor consists of a linear Hall circuit with a copper conduction path located near the surface of the chip. When the device is turned on the applied current flowing through the copper conduction path which generates a magnetic field which the sensor converts into a linearly proportional voltage. This voltage is read through the Arduino analog pin which outputs 10-bit number (0-1023), from which the DC or AC current can be calculated.

Table below give specification on the different version of the chip

5A Module20A Module30A Module
Supply Voltage (VCC)5Vdc Nominal5Vdc Nominal5Vdc Nominal
Measurement Range-5 to +5 Amps-20 to +20 Amps-30 to +30 Amps
Voltage at 0AVCC/2 (nominally 2.5Vdc)VCC/2 (nominally 2.5Vdc)VCC/2 (nominally 2.5VDC)
Scale Factor185 mV per Amp100 mV per Amp66 mV per Amp
ChipACS712ELC-05AACS712ELC-10AACS712ELC-30A

Sensor IC is electrically isolated from the terminals conducting path. This feature allows, applications requiring electrical isolation without the use of opto-isolators or other costly isolation techniques.

The voltage reading on the Arduino analog pin by the sensor depends on the sensor’s rating. The ±5A sensor will output 185mV for each amp (mV/A), the ±20A 100mV/A and the ±30A 66mV/A. Accurately knowing the voltage is therefore pretty important. I bought 30A version so output will be 66mV/A.

#Schematics

The connection of ACS712 with Arduino and load is shown below.

#Sensing DC Current

Sensing DC current is simple as there is no change in direction of current with it is as simple as reading the value from the Arduino’s analog pin to which sensor is connected. The code for the Arduino is below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const int analog_IN = A0;
int mv_per_amp = 66; // use 100 for 20A Module and 66 for 30A Module
int raw_value= 0;
int acs_offset = 2500;
double voltage = 0;
double amps = 0;

void setup(){
Serial.begin(9600);
}

void loop(){
raw_value = analogRead(analog_IN);
voltage = (raw_value / 1024.0) * 5000; // Gets you mV
amps = ((voltage - acs_offset) / mv_per_amp);
Serial.print("Raw Value = " ); // shows pre-scaled value
Serial.print(raw_value);
Serial.print("\t mV = "); // shows the voltage measured
Serial.print(voltage, 3);
Serial.print("\t Amps = "); // shows the current
Serial.println(amps,3);
delay(2500);
}

If your load used the DC power supply then you should use the code above to measure the current.

#Sensing AC Current

Sensing AC current is a bit complex as the direction is constantly reversing in each sinusoidal cycle so we will get different current value each time we read the value. Instead, we are interested in Root mean square Voltage (Vrms).

With Arduino, we can continuously fetch readings from the analog pin for 1 second and get the highest reading in that interval. As the sin wave has a known frequency of 50/60 Hz sampling two waves will be good enough. This will give us peak voltage (Vp) in both(negative and positive) direction. RMS voltage can be calculated using peak voltage Vrms = Vp / √2. The code below reads samples for both minimum and maximum voltage for better accuracy, peak voltage Vp is the average of the absolute value of two voltages :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

const int sensor_IN = A0;
//use 185 for 5A, 100 for 20A Module and 66 for 30A Module
int mv_per_amp = 66
double voltage = 0;
double v_rms = 0;
double amps_rms = 0;

void setup(){
Serial.begin(9600);
}

void loop(){
voltage = getVPP();
v_rms = (voltage/2.0) * 0.707;
amps_rms = (v_rms * 1000)/mv_per_amp;
Serial.print(amps_rms);
Serial.println(" Amps RMS");
}

float getVPP(){
float result;
int read_value; //value read from the sensor
int max_value = 0; // store max value here
int min_value = 1024; // store min value here

uint32_t start_time = millis();
//sample for 1 Sec
while((millis()-start_time) < 1000) {
read_value = analogRead(sensor_IN);
// see if you have a new max_value
if (read_value > max_value){
/*record the maximum sensor value*/
max_value = read_value;
}
if (read_value < min_value){
/*record the maximum sensor value*/
min_value = read_value;
}

// Subtract min from max
result = ((max_value - min_value) * 0.5)/1024.0;
return result;
}

#Conclusion

As we saw the connecting the sensor was pretty simple but depending on the type of load connected to the sensor we have to process the output of the Arduino analog pin differently to get the correct output.

#Useful links

  1. Current Hall sensor ACS712-30Amp data sheet
  2. Must read
  3. More details on RMS voltage
Share