Energy Metering with the Portenta C33

This application note describes how to implement a simple energy meter with the Portenta C33.

Introduction

This application note explores the implementation of a simple yet useful energy meter using the Arduino® Portenta C33 and a non-invasive current transformer. The proposed energy meter enables real-time measurement and monitoring of electrical current consumption, providing valuable and useful insights into energy usage patterns to the user.

Non-invasive current transformers offer several advantages, including electrical safety, easy installation, and the ability to measure current in existing electrical circuits without interrupting the flow of current. These characteristics make them well-suited for applications such as energy metering, power monitoring, and load management.

The Portenta C33 features a powerful microcontroller and onboard wireless connectivity, making it an ideal choice for energy monitoring applications. The Portenta C33's onboard Wi-Fi® module enables seamless integration with wireless networks and facilitates communication with the Arduino Cloud platform.

Portenta C33 with a non-invasive current transformer
Portenta C33 with a non-invasive current transformer

By combining the Portenta C33 and the SCT013-000 current transformer, you can quickly build an energy meter that can measure Root Means Square (RMS) current, power consumption, and communicates the data to the Arduino Cloud platform for further analysis and visualization.

Goals

The main goals of this application note are as follows:

  • Develop a functional energy meter that can provide real-time insights into energy usage patterns, allowing users to track and analyze their energy consumption.
  • Showcase the integration of the Portenta C33 board with a non-invasive current transformer to measure AC current.
  • Calculate the RMS (Root Mean Square) value of a current waveform, providing an accurate representation of the actual current flowing through the circuit.
  • Use the measured RMS current and a known AC voltage to calculate power consumption in Watts.
  • Establish a connection between the Portenta C33 and the Arduino Cloud to send the measured RMS current data for further analysis, visualization, and remote monitoring.

Hardware and Software Requirements

Hardware Requirements

Software Requirements

Hardware Setup Overview

The electrical connections of the intended application design are shown in the diagram below:

Application's electrical connection overview
Application's electrical connection overview

The overview illustrates the connection from the sensor passing through a conditioner circuit and interfacing with the Portenta C33.

Take into account that only one AC wire must pass in between the current transformer, as shown below:

Correct usage of a non-invasive current transformer
Correct usage of a non-invasive current transformer

Measuring Current Using Non-Invasive Current Transformers

Non-invasive current transformers, such as the SCT013-000 current transformer used in this application note, provide a safe and convenient method for measuring electrical current, without the need for direct electrical connections. These transformers work on the principle of electromagnetic induction and consist of a primary winding and a secondary winding.

As shown in the animation below, the primary winding typically consists of a single turn or a few turns of a conductor, while the secondary winding consists of a large number of turns wound around a magnetic core. When an alternating current flows through the primary winding, it induces a proportional current in the secondary winding. This induced current can be measured and used to determine the magnitude of the primary current.

As shown in the animation below, the primary winding is typically a single turn or a few turns of a conductor, while the secondary winding is a large number of turns wound around a magnetic core. When an alternating current flows through the primary winding, it induces a proportional current in the secondary winding. This induced current can be measured and used to determine the magnitude of the primary current.

Working principle of a non-invasive current transformer

To accurately measure the induced current, a burden resistor is connected in parallel with the secondary winding of the current transformer. The burden resistor creates a voltage drop proportional to the secondary current, which can be measured using an analog or digital sensor, for example, the analog input pins of the Portenta C33. In this application note, the measured secondary current is converted into an RMS current value using appropriate calibration ratios and calculations.

The value of the burden resistor must be carefully chosen to match the physical characteristics of your current transformer and measurement sensor.

To calculate the ideal burden resistor some math is required. Below you can find the calculations done for the SCT013-000 current transformer used this the application note:

  • Primary winding peak current (IP):

Primary winding peak current calculation
Primary winding peak current calculation

  • Secondary winding peak current (IS):

Secondary winding peak current calculation
Secondary winding peak current calculation

  • Ideal burden resistor (RBurden):

Ideal burden resistor calculation
Ideal burden resistor calculation

For this application note and the used non-invasive current transformer, the ideal burden resistor RBurden is 21.9 Ω; you can use a commercially available resistor value, for example, 22 Ω.

Non-invasive current transformers offer several advantages, including electrical safety, easy installation, and the ability to measure current in existing electrical circuits without interrupting the current flow. These characteristics make them well-suited for applications such as:

  • Energy metering
  • Power monitoring
  • Load management

Non-Invasive Current Transformer Example Sketch

The non-invasive current transformer sketch has a simple structure which is explained below.

1/**
2 Energy metering application note
3 Name: current_cloud.ino
4 Purpose: This sketch interfaces the Portenta C33 with the SCT013-000 current transformer
5 to measure RMS current and power.
6
7 @author Arduino Team
8 @version 1.0 20/06/23
9*/
10
11// Import the properties and definitions for the Arduino Cloud integration
12#include "thingProperties.h"
13
14// Define a floating-point conversion factor for the SCT013-000 current transformer configuration
15float Sensor_Factor = 51.8;
16
17// Define floating-point variables for the Root Mean Square (RMS) current and apparent Power
18float Irms, AP;
19
20// Define an integer for the specific voltage of the geographical region
21int Region_Voltage = 110;
22
23// Define a boolean variable to control whether or not the sampling process is active
24bool Sample_Switch = true;
25
26// Define the pin where the current transformer is connected
27#define TRANSFORMER_PIN A0
28
29void setup() {
30 // Initialize the serial communication with a baud rate of 115200
31 Serial.begin(115200);
32
33 // Set the current transformer pin as input
34 // Set the resolution of the analog read to 12 bits
35 // Pause the execution of the program for one second
36 pinMode(TRANSFORMER_PIN, INPUT);
37 analogReadResolution(12);
38 delay(1000);
39
40 // Call the function to setup the Arduino Cloud
41 iot_cloud_setup();
42}
43
44void loop() {
45 // Update the status of the Arduino Cloud
46 ArduinoCloud.update();
47
48 // If the sampling switch is active, calculate the RMS current
49 if (Sample_Switch == true) {
50 Irms = getCurrent();
51
52 // Calculate apparent power
53 AP = Irms * Region_Voltage;
54
55 // Print RMS current and apparent power to the IDE's Serial Monitor
56 Serial.print(F("- I_rms [A]: "));
57 Serial.print(Irms);
58 Serial.print(F("- Apparent Power [VA]: "));
59 Serial.print(AP);
60 } else {
61 // If the sampling switch is not active, print a message saying the energy measurement has been paused
62 Serial.println(F("- Energy measurement has been paused!"));
63 }
64
65 // Update the RMS current and apparent power in the Arduino Cloud
66 cloud_Current = Irms;
67 cloud_ApparentPower = AP;
68
69 // Pause the execution of the program for one second
70 delay(1000);
71}
72
73/**
74 This function is executed every time a new value is received from the Arduino Cloud
75
76 @param none
77 @return none
78*/
79void onCloudCurrentChange() {
80 // Print a debug message
81 Serial.print(F("- Updated I_RMS value for IoT Cloud"));
82}
83
84/**
85 Reads the designated analog pin, connected to a SCT013-000 current transformer and calculates RMS Current
86
87 @param none
88 @return RMS current (amperes)
89*/
90float getCurrent() {
91 float Current = 0;
92 float I_Sum = 0;
93 int N = 0;
94 long time = millis();
95
96 // Collect samples for 0.5 seconds (approx. 30 cycles at 60 Hz)
97 while(millis() - time < 500) {
98
99 // Read the analog pin
100 int sensorValue = analogRead(TRANSFORMER_PIN);
101
102 // Convert the analog reading to voltage
103 float sensorVoltage = sensorValue * (3.1 / 4096.0);
104
105 // Convert the sensor voltage to current
106 Current = sensorVoltage * Sensor_Factor;
107
108 // Calculate the sum of the squares of the current
109 I_Sum += sq(Current);
110 N++;
111 delay(1);
112 }
113
114 // Compensate for the negative semi-cycle quadratics
115 I_Sum = I_Sum * 2;
116
117 // Calculate RMS current (average)
118 Current = sqrt((I_Sum)/N);
119 return(Current);
120}
121
122/**
123 Sets up the connection to the Arduino Cloud
124
125 @param none
126 @return none
127*/
128void iot_cloud_setup() {
129 // Defined in thingProperties.h
130 initProperties();
131
132 // Connect to Arduino Cloud
133 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
134
135 /*
136 The following function allows you to obtain more information
137 related to the state of network and IoT Cloud connection and errors
138 the higher number the more granular information you’ll get.
139 The default is 0 (only errors).
140 Maximum is 4
141 */
142 setDebugMessageLevel(2);
143 ArduinoCloud.printDebugInfo();
144
145 sct_ratio = Sensor_Factor;
146 system_Voltage = Region_Voltage;
147 sample_Control = Sample_Switch;
148}
149
150/**
151 This function is executed every time a new value from sct_ratio is received from the Arduino Cloud
152
153 @param none
154 @return none
155*/
156void onSctRatioChange() {
157 Sensor_Factor = sct_ratio;
158}
159
160/*
161 This function is executed every time a new value from system_Voltage is received from the Arduino Cloud
162*/
163void onSystemVoltageChange() {
164 Region_Voltage = system_Voltage;
165}
166
167*
168 This function is executed every time a new value from sample_Control is received from the Arduino Cloud
169*/
170void onSampleControlChange() {
171 Sample_Switch = sample_Control;
172
173 if (Sample_Switch == true){
174 Serial.println(F("Energy measurement started - Arduino Cloud triggered"));
175 }
176 if (Sample_Switch == false){
177 Serial.println(F("Eenrgy measurement paused - Arduino Cloud triggered"));
178 }
179}

The following sections will help you to understand the main parts of the code.

Variables and Constants

The key variables and constants used in the sketch are:

1// Conversion factor for the specific sensor configuration
2float Sensor_Factor = 51.8;
3
4// RMS Current and Apparent Power variable
5float Irms, AP;
6
7// Voltage specific to the geographical region in volts
8int Region_Voltage = 110;
9
10// Boolean variable to control measurement sampling
11bool Sample_Switch = true;
12
13// Analog pin to which the current transformer is connected
14#define TRANSFORMER_PIN A0
  • Sensor_Factor
    : A conversion factor used to convert the raw current transformer reading to an RMS current value.
  • Irms
    and
    AP
    : Variables used to store the RMS current and apparent power respectively.
  • Region_Voltage
    : The voltage of the power system you are monitoring. This varies depending on the country and the type of power system.
  • Sample_Switch
    : A boolean switch to control whether or not your Portenta C33 should be measuring power. If it is true, your Portenta C33 will measure power.
  • TRANSFORMER_PIN
    : The pin on your Portenta C33 board that the current transformer is connected to.

Initialization Function

The

setup()
function helps set up the communication with the Arduino Cloud, as well as the communication settings of the board itself:

1void setup() {
2 // Initialize the serial communication with a baud rate of 115200
3 Serial.begin(115200);
4
5 // Set the current transformer pin as input
6 // Set the resolution of the analog read to 12 bits
7 // Pause the execution of the program for one second
8 pinMode(TRANSFORMER_PIN, INPUT);
9 analogReadResolution(12);
10 delay(1000);
11
12 // Call the function to setup the Arduino Cloud
13 iot_cloud_setup();
14}

This function runs once when the Portenta C33 starts:

  • It initializes the serial communication.
  • Sets the pin mode of the current transformer input pin to input.
  • Sets the ADC resolution to 12 bits and waits for a second for the system to stabilize.
  • Finally calls the
    iot_cloud_setup()
    function to set up the Arduino Cloud connection.

The Main Loop

The main loop of the sketch is as follows:

1void loop() {
2 // Update the status of the Arduino Cloud
3 ArduinoCloud.update();
4
5 // If the sampling switch is active, calculate the RMS current
6 if (Sample_Switch == true) {
7 Irms = getCurrent();
8
9 // Calculate apparent power
10 AP = Irms * Region_Voltage;
11
12 // Print RMS current and apparent power to the IDE's Serial Monitor
13 Serial.print(F("- I_RMS [A]: "));
14 Serial.print(Irms);
15 Serial.print(F("- Apparent power [VA]: "));
16 Serial.print(AP);
17 } else {
18 // If the sampling switch is not active, print a message saying the energy measurement has been paused
19 Serial.println(F("- Energy measurement has been paused!"));
20 }
21
22 // Update the RMS current and apparent power in the Arduino Cloud
23 cloud_Current = Irms;
24 cloud_ApparentPower = AP;
25
26 // Pause the execution of the program for one second
27 delay(1000);
28}

The main

loop()
function executes continuously. At each iteration:

  • It first updates the Arduino Cloud connection.
  • If the
    Sample_Switch
    is true, it measures current, calculates apparent power, and prints them to the IDE's Serial Monitor.
  • If
    Sample_Switch
    is false, it simply prints that the energy measurement is paused.
  • It then updates the
    cloud_Current
    and
    cloud_ApparentPower
    variables with the local values of current and apparent power, then waits for a second before the next iteration.

User Functions

The

iot_cloud_setup()
function groups the initial configuration process of the Arduino Cloud as follows:

1void iot_cloud_setup() {
2 // Defined in thingProperties.h
3 initProperties();
4
5 // Connect to Arduino Cloud
6 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
7
8 /*
9 The following function allows you to obtain more information
10 related to the state of network and IoT Cloud connection and errors
11 the higher number the more granular information you’ll get.
12 The default is 0 (only errors).
13 Maximum is 4
14 */
15 setDebugMessageLevel(2);
16 ArduinoCloud.printDebugInfo();
17
18 sct_ratio = Sensor_Factor;
19 system_Voltage = Region_Voltage;
20 sample_Control = Sample_Switch;
21}

This function is responsible for setting up the connection with the Arduino Cloud:

  • It initiates the properties of the Cloud connection.
  • Begins the Cloud connection with the preferred connection method.
  • Sets the debug message level to 2 for detailed debugging, and prints the debug information.

The variables

sct_ratio
,
system_Voltage
, and
sample_Control
are used to synchronize the local values with the Arduino Cloud.

Now, let's talk about the

getCurrent()
function:

1float getCurrent() {
2 float Current = 0;
3 float I_Sum = 0;
4 int N = 0;
5 long time = millis();
6
7 // Collect samples for 0.5 seconds (approx. 30 cycles at 60 Hz)
8 while(millis() - time < 500) {
9
10 // Read the analog pin
11 int sensorValue = analogRead(TRANSFORMER_PIN);
12
13 // Convert the analog reading to voltage
14 float sensorVoltage = sensorValue * (3.1 / 4096.0);
15
16 // Convert the sensor voltage to current
17 Current = sensorVoltage * Sensor_Factor;
18
19 // Calculate the sum of the squares of the current
20 I_Sum += sq(Current);
21 N++;
22 delay(1);
23 }
24
25 // Compensate for the negative semi-cycle quadratics
26 I_Sum = I_Sum * 2;
27
28 // Calculate RMS current (average)
29 Current = sqrt((I_Sum)/N);
30 return(Current);
31}

The

getCurrent()
function calculates the RMS current from the sensor reading. It reads the sensor value, converts it to voltage, then calculates the current. The square of the current is summed over 0.5 seconds (approximately 30 cycles at 60 Hz). This sum is compensated for the negative semi-cycle quadratics and then used to calculate the RMS current. This value is returned to the user.

Finally,

onSctRatioChange()
,
onSystemVoltageChange()
, and
onSampleControlChange()
functions: These functions get executed every time the corresponding value is changed from the Arduino Cloud. For example, if
onSctRatioChange()
is executed, the
Sensor_Factor
will be updated with the new value received from the Cloud, and similarly for the others.

Full Example Code

The complete example code can be downloaded here. The

thingProperties.h
header is already included for your reference, and it is based on the variables of the example code. The header is generated automatically with Arduino Cloud. If you desire to modify the requirements of the application environment, it is recommended to make changes within the Arduino Cloud environment.

Arduino Cloud Dashboard

The Arduino Cloud allows to create a dashboard with professional real-time Human-Computer Interaction (HCI) as can be seen in the following animation, showing an active Portenta C33 board:

Arduino Cloud Dashboard Example

One of the standout features of the Arduino Cloud Dashboard is the ability to update the current transformer's ratio in real time. This feature becomes particularly useful when you need to switch to a different current transformer in a live deployment scenario. Different current transformers can possess different electrical characteristics more or less convenient for different scenarios, and the real-time update capability simplifies the swap between them.

Additionally, the dashboard lets you select the installation voltage to meet the requirements of your site. This adaptability underscores the flexibility and user-friendliness of the Arduino Cloud Dashboard, making it an invaluable tool for handling real-time sensor data.

Arduino Cloud Mobile Dashboard Example

On a mobile phone, the Arduino Cloud dashboard displays the information as the previous figure. It provides the complete interface you would use on a desktop platform, making it a very useful feature to access the dashboard wherever you are.

Conclusions

In this application note, we delved into the interaction between a Portenta C33 board and the SCT013-000 current transformer. We examined how the Arduino Cloud enables us to visualize and analyze real-time and historical sensor data intuitively.

By using the Portenta C33 board and the Arduino Cloud, you can transform raw sensor data into meaningful insights. Whether it is reading the RMS current and apparent power information, altering the current transformer configurations in real-time, or adapting to unique site requirements, this application note offers a robust and versatile system for handling these tasks.

One of the key takeaways from this application note is its potential for this application in various real-world scenarios. By integrating IoT and Cloud capabilities, we can effectively monitor and manage energy usage, leading to more efficient power consumption and contributing to a sustainable future.

Next Steps

Now that you have learned to deploy a Portenta C33 with SCT013-000 current transformer, using the on-demand remote actuation and real-time data visualization of the Arduino Cloud platform, you will be able to expand the application further by adding new measurement equipment with similar characteristics. You could also deploy multiple sensors connected to different boards, creating a cluster to gather energy measurements from every point of interest in an electrical installation.

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.