Tuesday, October 2, 2018

Safe and easy DIY Home Energy Monitor Using Current Transformer with Arduino, Raspberry Pi, or Beaglebone Black

To measure and monitor the energy usage of home appliances, let us build a simple and basic energy monitor. Although there are several methods to build energy monitors, I have chosen YHDC Current Transformer SCT-013-000 [YHD18] for it. Because it is non-invasive, safe, and suitable for learning. It is a split-core current transformer so that it can be fastened and used easily without the requirement to touch the high voltage power lines. Note that only one power cable is to be put in the core as shown in Figure 1.

Figure 1. (Left) SCT-013 is split core so that it can be easily clipped on a wire. (Center) If all the wires are put inside the core, input and output currents are cancelled. Therefore the net current will be zero. (Right) It is required to put only one wire in the core.

  1. Measuring Current
  2. Burden Resistor
  3. Bias
  4. Measuring Power
  5. Signal Processing
  6. Calibration
  7. Schematic Circuit
  8. Arduino
  9. BeagleBone Black / Odroid
  10. Raspberry Pi
  11. Web Interface
  12. References

Measuring Current

Current transformers induce a current in the secondary winding depending on the AC current in the primary winding and the turn ratio. According to its datasheet, the effective turn ratio is 2000:1. Therefore, an input current of 100 A (rms) will produce an output current of 50 mA (rms). The rated current for this current transformer is 120 A. It has a transient voltage supressor (TVS) which limits the peak output voltage not to exceed 17.8 V.

For this design, the maximum value of primary rms current \(I_{i_{rms}}\) is assumed as 30 A and the desired voltage for the interfacing signal processor is around 3.3 V. To obtain the secondary current \(I_s\) for the CT (current transformer), the input current is divided by the turn ratio. It is intended for passive loads, and the currents are assumed to be sinusoidal. Therefore, the peak to peak value for \(I_s\) is \(2\sqrt{2}\) times its rms value. The relationship between the input rms current and the output peak to peak current can be expressed as in the following equations.

\[ I_{s_{p-p}} = \frac{I_{i_{rms}}}{2000} \times 2\sqrt{2} \]

\[ \label{eq:ispp} I_{s_{p-p}} = \frac{\sqrt{2}I_{i_{rms}}}{1000} \]

Burden Resistor

For example, input rms current of 30 A will produce output peak to peak current of 42.43 mA for this current transformer. If the desired peak to peak output voltage is 3.3 V, using Ohm's law \( R = \frac{V}{I} \) will give the burden resistance as \( 78 \Omega \). The nearest commonly available resistor value \( 75 \Omega \) can be used for it. The output peak to peak voltage \( V_{s_{p-p}} \) for the burden resistance \( 75 \Omega \) is shown in the following equations. \[ V_{s_{p-p}} = \frac{\sqrt{2}I_{i_{rms}}}{1000}\times R_{burden} \] \[ V_{s_{p-p}} =0.106 \times I_{i_{rms}} \]


The resulting voltage is an alternating (AC) signal. To get a voltage which is always positive, a bias voltage is added to the signal. [LH18]။ The voltage at the burden resister is varying between -1.6 V to 1.6 V in this example. After adding the bias voltage \(V_b \) which is 1.6 V, the resulting output voltage \(V_c\) is obtained to be varying between 0 V and 3.2 V as shown in Figure 2. To get the bias voltage, a simple voltage divider can be constructed using 180 \(\Omega\) resistors. 360 \(\Omega\) resistance can be obtained by adding two 180 \(\Omega\) resistors in series. The resulting voltage \(V_c\) can be used by a controller like Arduino to calculate current, power, etc.

Figure 2. Adding bias.

Measuring Power

By measuring \(V_c\), the current flowing in the wire can be calculated. The power can then be derived by multiplying with the voltage. The following assumptions are made when designing this energy monitor.
  • 1. The power line voltage is assumed to be constant, 230 V in our case. If you want to get the accurate value, you can use a simple voltage divider or a voltage transformer and then measuring its output voltage.
  • 2. The difference between the apparent power \(P=VI\) and the real power is negligible. For example, in Singapore, the power factor must be greater than 0.95. If you want to measure the power even more accurately, you can use a microcontroller like Arduino Uno and sampling the voltage and the current at 1 kHz, for example, and calculate it. Alternatively, you can use an energy metering IC like ADE9153A [Ana18].
  • 3. The load are passive and the relation between the voltage and the current is linear. In this example, the calculations like getting rms values assumed that they are sinusoidal waveforms. If not, RMS to DC converters like AD8346 [Ana17] can be used also.
Furthermore, the tolerance of the components used in the circuit are contributing the error in measurement of the power also. For example, the tolerance of 75 \(\Omega\) burden resistor can be 1 % or 5 %, as a result, its output voltage \(V_c\) can contribute an error up to 5 %. A good news is that energy monitors are usually fixed at a particular load, and it can be calibrated to remove almost all the errors. The measurement after calibration can be very accurate.

Signal Processing

Since the Linux on our SBC cannot perform hard real-time tasks, we will build and use a simple signal processor using op-amps to produce a proportional dc voltage depending on rms current input. The LM324 op-amp can produce output voltages from 0.8 V to \(Vcc - 1.5\) V [Tex15; Tex17]. Therefore, when using 5 V power supply, we can have a output voltage range of more than 2 V. As an example, if we use 75 \(\Omega\) burden resistor again, the resulting energy monitor can measure up to 20 A. Its current range can be changed easily by changing the burden resistor.

Figure 3. A voltage reference circuit.

For this op-amp with 5 V power supply, the output voltage can vary between 0.8 V to 3.5 V with its center point around 2.2 V. Therefore, to get a bias voltage \(V_b\) of 2.2 V, a voltage reference is built using a zener diode and an op-amp voltage follower as shown in Figure 3. Thereafter, a precision rectifier is constructed as illustrated in Figure 4 [Ye13]. For the diodes, small signal Schottky diode BAT46 is chosen because it has lower forward voltage \(V_F\) and faster speed. Capacitor \(C_1\) improves the frequency response of the circuit.

Figure 4. A fullwave precision rectifier using op-amps.

When \(V_c\) is in positive half (i.e. \(V_c > V_b\) ), D1 is forward and D2 is reverse as shown in Figure 5. If we think \(V_b\) as a reference ground, the first op-amp acts as a voltage follower and the voltage at its inverting input is \(\approx V_c\). The second op-amp becomes inverting amplifier and the rectified voltage \(V_r\) can be expressed as follow. \[ V_r =-\frac{R_2}{R_1} \times V_c \]

Figure 5. When the input is positive, the precision rectifer acts like an inverting amplifier and produces negative output voltage.

Since \(R_1\) and \(R_2\) are the same, the output voltage is negative value of input voltage with the same amplitude. \[ V_r =-V_c \]

Figure 6. When the input is negative, the precision rectifier acts like a voltage follower and produces negative output voltage.

When input voltage \(V_c\) is in negative half (i.e. \(V_c < V_b\) ), D1 is reverse and D2 is forward as shown in Figure 6. At that situation, there is no current in \(R_1\) and \(R_2\) which are connected to high impedance inputs. Therefore, the voltage drop is zero for them and both op-amps act as voltage follower where \(V_r\) is equal to \(V_c\) and also negative. For this circuit configuration, the peak to peak voltage of the first op-amp needs to be \(2V_F\) greater than that of the input voltage. Therefore, the maximum peak to peak voltage for the input voltage \(V_c\) can be obtained as follow. \[ V_{c_{p-p}}=V_{cc}-1.5-0.8-2 V_F \] When \(V_{cc}\) is 5 V and \(V_F\) of Schottky diode is 0.25 V, the maximum \(V_{c_{p-p}}\) is calculated as 2.2 V. When that value is substituted in the equation for \(I_{i_{rms}}\), the maximum current that can be measured is obtained as 20 A.


To achieve a more accurate measurement of the energy monitor, we can calibrate it. An easier and more practical approach for calibration is to use hardware trimmer although it is also possible to adjust the values in the program which is implemented in the SBC. To adjust the offset value and scale factor of the output voltage, an inverting op-amp adder is deployed is shown in Figure 7. To filter the ripples, a low pass filter is also implemented also. To clip the output voltage not to exceed 1.8 V, a zener diode can be added as illustrated in it.

Figure 7. Schematic diagram of op-amp adder, low pass filter, and voltage clipper.

The output voltage \(V_a\) of the op-amp can be expressed as follow. \[ V_a=V_b - \frac{R_1}{R_2}(V_r-V_b) - \frac{R_1}{R_2}(V_{cc}-V_b) \] The desired output offset voltage is 1 V when the current is zero. Therefore, when \(V_b\) is 2.2 V, \(V_{cc}\) is +5 V, and quiescent value of \(V_{r}\) is 2.2 V, the value of \(R_3\) can be obtained as 2.3 k\(\Omega\). A 5 k\(\Omega\) trimmer having that nearest mid point can be used. Since the maximum peak to peak value of \(V_{c_{p-p}}\) is 2.2 V, the peak value of \(V_{a}\) denoted by \(V_{p}\) can be up to 1.1 V. For current \(I_{i_{rms}}\) of 20 A, the average output \(V_{o}\) is desired to be 1.8 V which is analog input reference of SBCs like BeagleBone Black and Odroid-XU4. If we subtract offset voltage value of 1 V, the average output voltage caused by the input rms current \(V_{d}\) is 0.8 V. The relation between \(V_{d}\) and \(V_{p}\) is shown below. \[ V_d=\frac{V_p}{\pi}\int_{\omega t =0}^{\pi} \sin (\omega t) d\omega t \] \[ V_d=\frac{2V_p}{\pi} \] For \(V_{d}\) 0.8 V, \(V_{p}\) is 1.26 V. \(R_1\) and \(R_2\) ratio for the inverting op-amp is obtained from these voltages as follow. \[ \frac{R_1}{R_2}=\frac{1.26}{1.1} \] Therefore, \(R_2\) is obtained as 870 \(\Omega\), and we can use 2 k\(\Omega\) trimmer which has the mid point around there. The cutoff frequency \(f_c\) of the low pass filter can be calculated as follow. \[ f_c=\frac{1}{2\pi R C} \] where the values of R = 2 k\(\Omega\) and C = 68 \(\mu\)F give the cutoff frequency as \(\approx\)1 Hz. To limit the output voltage, 1.8 V Zener diode is used as the voltage clipper.


The first step in calibration is to adjust \(V_o\) to be 1 V by turning \(R_3\) trimmer when there is no load. Thereafter, adjust \(R_2\) trimmer to get corresponding \(V_o\) for a known load. For example, the rms current value of 230 V, 2000 W hair dryer is 8.7 A. Then the corresponding output voltage \(V_o\) can be calculated as 1.35 V as follow. \[ V_o=1 + 0.8 \times \frac{I_{i_{rms}}}{20} \]

Schematic circuit

The output voltage of the signal processor can be read by analog input of SBCs like BeagleBone Black and Odroid-XU4. Microcontrollers such as Arduino Uno can also be used to read the output voltage. Raspberry Pi does not have analog inputs, and ADC chip likes MCP3004 can be used for it. An example schematic circuit after combining all of the components we have discussed above is shown in Figure 8. In case, you need smoother waveforms, the capacitor C3 can be increased to 1 nF.

Figure 8. Schematic circuit diagram for the signal processor.

Figure 9. Fabricated PCB.


The signal processor can use 5 V for its power supply. Therefore, 5 V pin of Arduino can attach to its Vcc. As an example, the output voltage \(V_o\) of the signal processor can connect to analog input A0 of Arduino as shown in Figure 9.

Figure 10. Using the signal processor with Arduino.

Code example

To read analog input and to show the value on serial monitor, Arduino example AnalogReadSerial can be used. In Arduino IDE, click File menu -> Examples -> 01. Basics -> AnalogReadSerial to open it. The example can be found at the following link too.


When you run the program, you can see the values on the serial monitor which are read from the analog input. To get volt-ampere (VA) instead of analog voltage values, replace the code
int sensorValue = analogRead(A0);
with the following.
float a = 204.6; // offset = 1023.0 / 5 = 204.6 N/V;
float k = 2.53;  // scale factor = (20 * 230) / (0.8*204.6) => 28.1 VA/N
float val = analogRead(A0);
float w = k*(val - a);

BeagleBone Black / Odroid

For BeagleBone Black and Odroid-XU4, when powered by barrel jack, their 5 V pin can be used to power the signal processor. Since they have analog inputs, the output voltage \(V_o\) of the signal processor can be directly connected to one of them, e.g. A5 as shown in Figure 10.

Figure 11. The signal processor connected to BeagleBone Black.

To read the analog input, CE_Ai class module can be used which can be found at the following link.


To read the data, a GUI C++ program can be created using wxWidgets as discussed in the following link.

Cross-platform C++ programming with wxWidgets

Then, a wxWidgets timer can take sample every second as shown in the example C++ program em.cpp at the following link.


Sampled data for last one minute is saved in eseconds.php to be used by web interface. Hourly and daily data can also be saved in the similar fashion. The program can be built and run using the commands as in Listing. em-bar.sh.
$ ./em-bar.sh

echo "Compiling..."
unamestr=`uname -m`
if [[ "$unamestr" == 'x86_64' ]]; then
   echo "on x86_64"
   g++ em.cpp `wx-config --cxxflags --libs std`-o em -std=c++11
   echo "CWD: $PWD"
   gnome-terminal -x sh -c './em'
elif [[ "$unamestr" == 'armv7l' ]]; then
   echo "on armv7l"
   g++ em.cpp `wx-config --cxxflags --libs std`-o em -std=c++11
   echo "CWD: $PWD"
   gksudo ./em
echo "Done."   

Listing. em-bar.sh

The GUI of the program is shown in Figure 11.

Figure 12. GUI of the program, em.cpp.

Raspberry Pi

For Raspberry Pi, we use an ADC chip MCP3004 to read the input voltage. Signal processor uses 5 V power supply, and its Vcc can be connected to 5 V pin of Raspberry Pi. The signal processor, ADC, and RPi are connected as shown in Figure 12.

Figure 13. Connecting the energy monitor to Raspberry Pi via SPI interface.

CE_SPI class module can be used to read the ADC.


Similar to BeagleBone Black, wxWidgets (See. Cross-platform C++ programming with wxWidgets) timer is used to sample the data every second as in C++ example program em.cpp which can be found at the following link.


The GUI of the program is shown in Figure 13.

Figure 14. GUI of em.cpp on Raspberry Pi.

Web Interface

An SBC can be setup as a web server to show the sampled data of the energy monitor as a PHP web page. The web interface can be accessed using a computer or a phone from any place where there is internet connection. Gchart from Google is used to draw the chart for energy usage in em.php.


Its web UI is shown in Figure 14.

Figure 15. UI of em.php.


[Ana17] Analog Devices. AD8346 Low Cost, Low Power, True RMS-to-DC Converter. 2017.
url: http://www.analog.com/en/products/analog-functions/rms-to-dc-converters/ad8436.html.

[Ana18] Analog Devices. ADE9153A Energy Metering IC with Autocalibration. 2018.
url: http://www.analog.com/en/products/analog-to-digital-converters/integrated-special-purpose-converters/energy-metering-ics/ADE9153A.html.

[LH18] Trystan Lea and Glyn Hudson. CT sensors - An Introduction. 2018.
url: https://learn.openenergymonitor.org/electricity-monitoring/ct-sensors/introduction.

[Tex15] Texas Instruments. LMx24, LMx24x, LMx24xx, LM2902, LM2902x, LM2902xx, LM2902xxx Quadruple Operational Amplifiers. 2015.
url: http://www.ti.com/lit/ds/symlink/lm324a.pdf.

[Tex17] Texas Instruments. LM358, LM258, LM158, LM2904 Dual Operational Amplifiers. 2017.
url: http://www.ti.com/lit/ds/symlink/lm258a.pdf.

[Ye13] Ting Ye. Precision Full-Wave Rectifier, Dual-Supply. 2013.
url: http://www.ti.com/lit/ug/tidu030/tidu030.pdf.

[YHD18] YHDC. SCT013-000-100A-50mA Split Core Current Transformer. 2018.
url: http://en.yhdc.com/product/SCT013-401.html.

No comments:

Post a Comment

Comments are moderated and don't be surprised if your comment does not appear promptly.