This Arduino project shows how to measure AC voltages up to about 600 Volts using Arduino UNO board and AMC1301 differential input, differential output isolated amplifier.
With this circuit we can easily measure home phase-to-natural (230V) and phase-to-phase (400V) voltages.
A 16×2 LCD connected to the Arduino board is used to display voltage values.
Hints:
No warranty is provided with this project, so do it at your own risk!
A part of the project circuit may be subjected to high voltage which is very harmful to human body, so be-careful!
Abbreviations:
AC: Alternating Current.
DC: Direct Current.
TRMS: True Root Mean Square.
ADC: Analog-to-Digital Converter
Isolated voltage measurement with Arduino and AMC1301 circuit:
Project circuit diagram is shown below.
All the grounded terminals should be externally connected together!
Hardware required:
This is a summary of circuit required parts (circuit schematic diagram may contain some component parameters not shown below).
- Arduino Uno or equivalent board such as Arduino Nano
- AMC1301 isolated amplifier —> details
- MCP6022 op amp —> details
- MCP1501-20 2.048 voltage reference —> details
- B0505S isolated DC/DC converter (1 or 2-Watt)
- 1602 LCD screen
- 6 x 1M Ohm resistor (R3, R4, R5, R12, R13, R14)
- 3 x 10k Ohm resistor (R17, R19, R22)
- 6 x 4.7k Ohm resistor (R6, R8, R9, R15, R16, R18)
- 2k Ohm resistor (R7)
- 330 Ohm resistor (R11)
- 100 Ohm resistor (R2, R20)
- 68 Ohm resistor (R1)
- 10 Ohm resistor (R21)
- 10k Ohm variable resistor
- 10µF capacitor (C2)
- 2 x 4.7µF capacitor (C1, C5)
- 2 x 2.2µF capacitor (C13, C14)
- 4 x 0.1 capacitor (C3, C6, C7, C8)
- 2 x 1nF capacitor (C11, C12)
- 3 x 220pF capacitor (C4, C9, C10)
Circuit description:
Before connecting high voltage signal to the Arduino board ADC input pin, it must be scaled down, isolated and filtered.
The AC voltage under measurement is connected in the circuit to VIN1 and VIN2 terminals. This voltage is then scaled down using a voltage divider circuit which consists of six 1 Mega-Ohm (R3, R4, R5, R12, R13, R14) and one 2 kilo-Ohm (R7) resistors.
The voltage divider circuit is designed so that it can reduce the input voltage to maximum of ±250mV in order to match the range of the AMC1301 isolation amplifier. For example, an input of 400V RMS will be reduced to 120mV RMS (±170mV peak).This means we can safely connect the circuit to a potential difference (voltage) of approximately 600V RMS (actually it’s about 589 Volts).
The AMC1301 from Texas Instruments is an isolated amplifier where its differential input is separated from its differential output by an isolation barrier.
Due to its low input impedance, the AMC1301 amplifier is well suited for current sensing applications where its differential input is connected in parallel with a resistor that has a very low resistance, for example shunt resistor. However, the AMC1301 can be used also in voltage sensing applications where the internal input impedance of the amplifier has to be taken into consideration.
The AMC1301 amplifier requires two power supplies, one is connected to high side (input) and the other to low side (output). The high and low side power supplies must be galvanically isolated, otherwise the isolation amplifier will have no meaning in the circuit.
The AMC1301 has a fixed gain of 8.2V/V and it is designed to measure differential signals of ±250mV with an isolated differential output of ±2.05V, it has a common mode output voltage (common mode offset) of 1.44V and a bandwidth of 200kHz.
In this project and as shown in the circuit schematic diagram above, the low side of the AMC1301 is powered with 5V which comes from the Arduino Uno board and the high-side is supplied from the isolated DC/DC converter B0505S.
The B0505S allows to get a galvanically isolated 5V source from the Arduino Uno board 5V output. I used this type of DC/DC converter because it is very available in the market with many brands, low cost, small, easy to use and requires few external components.
The B0505S has only 4 pins: 2 as inputs and the other 2 as outputs. In this project we may use B0505S-1W or B0505S-2W.
The voltage divider which converts input high voltage to low voltage is constituted of the resistors: R3, R4, R5, R7, R12, R13, R14 and the AMC1301 input impedance (VINP to VINN). The input impedance is approximately 18k Ohm and it is in parallel with R7 (2k Ohm).
So, the gain of the voltage divider can be calculated using the following equation:
Voltage-divider gain = (R7 // 18kΩ) / (R7 // 18kΩ + R3 + R4 + R5 + R12 + R13 + R14)
Voltage-divider gain = 1.8/6001.8
The differential output of the AMC1301 is connected to a differential amplifier circuit which filters the signal, applies a gain of 0.5V/V, removes the 1.44 DC offset and adds another offset of 1.024V.
The main component of this circuit is the Microchip MCP6022 dual op amp IC. It supplied with 5V from the Arduino board.
Since R9 = R18, R8 = R15 and R6 = R16 , the gain of the differential amplifier circuit (MCP6022) is:
Gain = R18/(R16 + R15) = 4.7/(2 x 4.7) = 0.5
So, the overall gain of the circuit is equal to: voltage divider gain x AMC1301 gain x MCP6022 differential amplifier gain circuit,
overall circuit gain = (1.8/6001.8) x 8.2 x 0.5 = 7.38/6001.8
This means a 230V RMS input will seen by the Arduino analog input as:
230 x 7.38/6001.8 = 282.8mV AC
So, the AC signal at analog channel input swings between about ±400mV (±√2 x 282.2) and by adding the 1.024V DC offset the signal will swing between 1.424V and 0.624V.
Before the attenuated AC signal goes to Arduino analog channel 0 (A0) it passes through an RC low pass filter which comprised of R1 and C3. The frequency of this filter can be simply calculated with this equation:
f = 1/(2 x π x R x C) = 23.4kHz
The 1.024V offset DC is just 2.048V divided by 2 using resistors R17 and R19, second op amp of the MCP6022 is used as voltage follower to get a low impedance voltage source (voltage buffer) which should not be affected by other circuit components such as R18.
I used the MCP1501-20 to get a precise voltage of 2.048V which is then used as positive voltage reference for the Arduino microcontroller ADC module. The MCP1501-20 is also supplied from the Arduino board with 5V. Its output is filtered and connected to the Arduino AREF pin.
The 1602 LCD screen (2 rows and 16 columns) is used to display the value of the input voltage, it is connected to the Arduino board as follows:
RS —> Arduino digital pin 2
E —> Arduino digital pin 3
D4 —> Arduino digital pin 4
D5 —> Arduino digital pin 5
D6 —> Arduino digital pin 6
D7 —> Arduino digital pin 7
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.
Isolated voltage measurement with Arduino and AMC1301 code:
Project code is the one below, it was tested with Arduino Uno and Nano boards.
The code tries to calculate AC signal RMS values applied to analog channel 0. It can measure AC voltages only, when a DC voltage is applied to the input terminals it will display 0 Volts because at all times the DC (or average) voltage is deducted from the whole input voltage signal.
Simply the average (mean or DC offset) value in discrete-time is the sum of all sample values divided by number of samples:
And the RMS value in discrete-time can be calculated using the following equation:
The Arduino uno board microcontroller (ATmega328P) has a 10-bit ADC module, the positive voltage reference is 2.048V means that a 2.048V is digitally represented by 1023 and 0V is represented by 0 (1 digit for every 2mV).
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | / /************************************************************************ * * AC Voltage measurement with Arduino. * Voltage values are printed on 1602 LCD screen. * This is a free software with NO WARRANTY - Use it at your own risk! * http://simple-circuit.com/ * ************************************************************************/ #include <LiquidCrystal.h> // include Arduino LCD library // LCD module connections (RS, E, D4, D5, D6, D7) LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // define analog channel input #define INPUT_CHANNEL A0 void setup(void) { delay(1000); lcd.begin(16, 2); // set up the LCD's number of columns and rows lcd.setCursor(0, 0); // move cursor to column 0, row 0 [position (0, 0)] lcd.print("RMS Voltage ="); analogReference(EXTERNAL); // set positive reference voltage to external } const uint16_t n = 512; // total number of samples (readings) int16_t r_array[n]; // readings array float average, rms; void loop() { average = 0; rms = 0; // read voltage at INPUT_CHANNEL 'n' times and save data to 'r_array' for (uint16_t i = 0; i < n; i++) { r_array[i] = analogRead(INPUT_CHANNEL); delayMicroseconds(200); } // calculate signal average (DC offset) for (uint16_t i = 0; i < n; i++) average += r_array[i]; average = average / n; // calculate AC signal RMS value for (uint16_t i = 0; i < n; i++) { if( abs(r_array[i] - average) > 3) rms += sq( r_array[i] - average ); } // calculate Arduino analog channel input RMS voltage in millivolts rms = 2 * sqrt(rms/n); // 2 = 2048/1024 // now calculate actual RMS input voltage (6001.8/7.83 is inverse of whole circuit gain) rms = rms * 6001.8 / 7.38; char _buffer[8]; lcd.setCursor(0, 1); if(rms >= 100000.0) // if voltage >= 100000.0 mV = 100.0 V sprintf( _buffer, "%3u.%1u V", (uint16_t)(rms/1000), (uint16_t)(rms/100) % 10 ); else if (rms >= 10000.0) // if voltage >= 10000.0 mV = 10.0 V sprintf( _buffer, " %2u.%1u V", (uint8_t)rms/1000, (uint16_t)(rms/100) % 10 ); else // if voltage < 10 V sprintf( _buffer, " %1u.%1u V", (uint8_t)(rms/1000), (uint8_t)(rms/100) % 10 ); lcd.print(_buffer); delay(1000); } // end of code. |
Finally, the following short video shows a test of hardware circuit under 230V AC (phase-to-natural):
Hello, firstly thank you for your work. Please can you provide us the simulation of this assembly please ? Which software have you used please ?
Thank you in advance !
You are a master in embedded programming, thank you for providing a very large scale tutorial platform
dear please make a USB mic using Arduino or pic16f887.
Welcome back after more than a year (last post March 10 2020). Hope you and yours are doing well. Thank you for your hard works on continuing to post tutorials, they are very educational.
Thanks for your support!
very nice tutorial can you do a project on ac current measurement using current readily available sensor in the market thanks