Electric Current Measurement Using Arduino and ACS758 Sensor

In the previous project I built a circuit that can be used to measure AC and DC currents with a good accuracy over a wide range from 0 to 200A DC, this circuit is based on Arduino UNO board and Allegro ACS758 hall-effect current sensor.
In this project I’m going to use the same Arduino board and current sensor to measure AC and DC currents with minimum required components. A 1602 LCD connected to the Arduino board is used to display current values, the Arduino also sends the same values to the Laptop which can be viewed using serial monitor.
A pushbutton connected to the Arduino board is used to choose between AC and DC currents.

No warranty is provided with this project, so do it at your own risk!
A part of project circuit may be subjected to high voltage which is very harmful to human body, so be-careful!

AC: Alternating Current
DC: Direct Current
TRMS: True Root Mean Square
ADC: Analog-to-Digital Converter
PCB: Printed Circuit Board
DIY: Do It Yourself

About ACS758 current sensor:
The ACS758 family from Allegro™ is an integrated circuit (IC) which is specifically designed for current measurement with frequency upto 120kHz. It’s a hall-effect-based current sensor with 100µΩ current conductor. This device generates a voltage that is proportional to the current passing through it where the generated voltage is galvanically isolated from the passing current. This means at all times, high power circuit is isolated from low power circuit.

The ACS758 family consists of many versions with different current ratings: 50A, 100A, 150A and 200A. Some versions are bidirectional sensors and the others are unidirectional. Bidirectional means that the sensor can be used to measure current flow in both directions, they are most used with AC loads (it may be used also with DC loads). Unidirectional means the sensor can sense current flow in one direction only, this type is suitable for DC loads.

In this project I’m going to use bidirectional sensor with rated DC current of 200A, its full name is: ACS758ECB-200B. Since this device is bidirectional, it allows us to measure AC and DC currents with typical sensitivity of 10mV/A.
However, other ACS758 versions may also be used in this project, such as ACS758ECB-50B which has a typical sensitivity of 40mV/A.
ACS770 is a newer version of hall-effect based current sensors, it’s recommended by the manufacturer to use it instead of the ACS758!

When the ACS758ECB-200B is powered by single supply source with 5V and when the primary current is zero, then the output of the device is 2.5V (it’s just VCC/2), this voltage called: quiescent output voltage ( VIOUT(Q) ).

With a supply of 5V, the typical device sensitivity is 10mV/A. The sensitivity as defined in device datasheet is the change in device output in response to a 1 A change through the primary conductor. For example when a single supply is used and with primary current of 5 Amps then the device output is: VIOUT(Q) + 5 x 10mV = 2.5 + 0.05 = 2.550V.

Hardware circuit of Arduino and ACS758 current sensor

Electric current measurement using Arduino and ACS758 sensor:
Project circuit diagram is shown below (click on the image for better view).

Interfacing Arduino ACS770 ACS758 AC DC current sensor circuit with LCD

Note that in the circuit there is 1 ground only which is the same as Arduino board ground (GND).
The Arduino uno board is represented by U2.

As shown in circuit schematic, the ACS758 current sensor is connected between the AC/DC source and the load. Instead of the ACS758 other similar devices may also be used, for example ACS770.
The voltage source may be AC or DC according to the connected load.

Hardware required:
This is a summary of circuit required parts (circuit schematic diagram may contain some component parameters not mentioned below).

  • Arduino Uno or equivalent board such as Arduino Nano (U2)
  • ACS758 Hall-effect current sensor (U1)   —> details
  • 1602 LCD screen
  • 10k variable resistor (R2)
  • 100 Ohm resistor (R1)
  • 330 Ohm resistor (R3)
  • 10 nF capacitor (C1)
  • Pushbutton (S1)
  • Breadboard
  • Jumper wires

Circuit description:
The ACS758 current sensor is noted in the circuit schematic above as U1. It is supplied with voltage of 5V which comes from the Arduino board.
At rated current of +200A the voltage output of the ACS758 sensor is 4.5V ( VIOUT(Q) + 200 x 10mV = 4.5V ) and at current of -200A the output voltage is 0.5V ( VIOUT(Q) – 200 x 10mV = 0.5V ).
The output of the ACS758 is connected to a RC filter (R1 and C1) that removes any high frequency noise and then directly to Arduino analog channel 2.

The 1602 LCD screen (2 rows and 16 columns) is used to display the value of the current that flows through the ACS758 sensor (load current), it is connected to the Arduino board as follows:
RS —> Arduino digital pin 3
E   —> Arduino digital pin 4
D4 —> Arduino digital pin 5
D5 —> Arduino digital pin 6
D6 —> Arduino digital pin 7
D7 —> Arduino digital pin 8
VSS, RW, D0, D1, D2, D3 and K are connected to GND,
VEE to the 10k Ohms variable resistor (or potentiometer) output,
VDD to Arduino 5V and A to Arduino 5V through 330 ohm resistor.

VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are the back light LED pins.

The pushbutton which is connected to Arduino digital pin 2 is used to choose between 3 current types: AC, DC or AC+DC.
With the Arduino code below and when AC type is selected, the Arduino calculates TRMS value of the AC current flows through the ACS758 sensor, any DC current will not be included in the results.
Alternatively, when DC type is selected, the Arduino calculates average (mean) value of the current applied to the ACS758 sensor.
However, when AC+DC type is selected, the Arduino calculates TRMS value of the current that passes through the ACS758 sensor where the DC component (offset) is included in calculations.

Electric current measurement using Arduino and ACS758 code:
Project code is the one below, it was tested with Arduino UNO board.
This Arduino code calculates RMS values for AC and AC+DC currents, and average (mean) values for DC current. The user can switch between the 3 current calculation modes using the pushbutton connected to Arduino digital pin 2, the default current type is AC (at startup).

Simply the average (mean or DC offset) value in discrete-time is the sum of all sample values divided by number of samples:

mean value equation

And the RMS value in discrete-time can be calculated using the following equation:

RMS value equation

The Arduino uno board microcontroller (ATmega328P) contains a 10-bit ADC module, in this project the positive voltage reference of the ADC module is the same as Arduino VCC (about 5 volts).
The ATmega328P MCU also contains a bandgap voltage reference of 1.1V. This internal voltage reference helps getting more accurate voltage values applied to any analog channel rather than the Arduino VCC (because we don’t know the exact value of VCC).

The philosophy is, first get the digital representation number of the internal voltage reference and then read the analog channel A2 voltage, for both readings VCC is used as positive reference of the ADC module. We can extract the analog voltage applied to A2 channel by multiplying the digital representation number of A2 voltage by the ratio of actual internal reference voltage (1.1V) and the digital representation number of the internal reference voltage.

To get more precise and higher resolution readings, I wrote a simple code to use what’s known as oversampling and decimation technique to add another 2 bits to the 10 bits of the ADC. This gives us a total of useful 12-bit words.

Firstly, I declared an array of 256 elements named r_array , it is used to store reading samples which are used later to calculate average (dc offset) and RMS values.
With oversampling of 2 bits, we’ve to do 16 analog readings for each element of the ‘r_array’ variable. These readings are summed and divided by 4, where 16 = 4² and 4 = 2² and this ² is number of oversampling bits.

Oversampling code is located in a void function named get_smaples() which is used to fill sample array r_array by doing a total of 4096 (16 x 256) successive ADC readings.

Programming hints:
At startup, the Arduino MCU executes an auto calibration code, so before powering the Arduino make sure that there’s no current flows through the ACS758 sensor, otherwise results of DC and AC+DC current calculations may not be accurate, auto calibration has no effect on AC calculations.

I added the auto calibration code to read and save circuit default offset voltage that is mainly caused by the ACS758 sensor. The auto-calibrated DC offset value is saved to a float variable named: dc_offset.

Functions used in the Arduino code:
void current_type_set(): selection of current type AC, DC or AC+DC is made by pressing the pushbutton connected to digital pin 2. When pressed, the Arduino immediately executes an interrupt routine and then in the loop() function a variable named current_type is incremented, it is later used to distinguish between the 3 current types.

void gain_set(uint8_t g): this function is used to change circuit gain according to g.

void get_smaples(): this function fills the sample array mentioned above with 256 12-bit of data.

bool debounce (): used to debounce the pushbutton connected to Arduino digital pin 2. Returns true if OK and false if error.

Full Arduino code:

The following video shows my DIY circuit for this project, I used a clamp meter from UNI-T company (UT219DS) in order to test the accuracy of my circuit.
Note that some wires connecting the Arduino uno and the DIY PCB are soldered on the back of the two boards, this removes small voltages & noise caused by poor connections between jumper wires and Arduino board female header pins.

Related Projects:
Measure AC & DC Currents with Arduino and ACS758 Sensor
Interfacing Arduino with Current Transformer – AC Current Measurement
AC Current Measurement using Arduino and Current Transformer
Isolated AC Voltage Measurement with Arduino and AMC1301 Amplifier

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.