Skip to content

Commit e974d23

Browse files
committed
Initial commit
Merry X-Mas! This is the first commit.
1 parent ebedf7c commit e974d23

25 files changed

+3248
-2
lines changed

Diff for: .gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Gitignore settings for ESPHome
2+
# This is an example and may include too much for your use-case.
3+
# You can modify this file to suit your needs.
4+
.esphome/
5+
secrets.yaml
6+
.vscode/
7+

Diff for: README.md

+211-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,211 @@
1-
# ESP32EnergyMonitor
2-
Energy consumption monitor for ESP32 using ESPHome firmware
1+
# ESP32 Open Source Energy Monitor
2+
3+
## Introduction
4+
For months I've been looking for a non-intrusive energy monitoring solution for my home. The residence receives two phases from the utility company and because of that, the available solutions in the market based on open protocols are extremely expensive. Cheap alternatives always rely on cloud services and I don't believe any of them will remain online for too long.
5+
6+
The solution I present here was built on the top of [Open Energy Monitor](https://openenergymonitor.org/) experience and uses [ESPHome framework](https://esphome.io/). I selected the ESP32 controller because it has several analog ports to measure voltage and current.
7+
8+
## Features
9+
- 1 to 3 phase current measurement
10+
- 1 to 3 phase voltage measurement
11+
- ESPHome based firmware
12+
- Generic firmware source that can be used without ESPHome (*calibrate-vi.ino*)
13+
- Plug and Play integration with [Home Assistant](https://www.home-assistant.io/)
14+
- MQTT integration
15+
- No cloud services required
16+
- 100% open source
17+
- Extremely cheap to build
18+
- Outputs:
19+
- Apparent power (VA)
20+
- Real power (W)
21+
- Current (A, RMS)
22+
- Voltage (V, RMS)
23+
- Daily energy consumption (kWh)
24+
- Weekly energy consumption (kWh)
25+
- Monthly energy consumption (kWh)
26+
27+
## Hardware
28+
29+
### Parts list
30+
31+
N = number of phases to be measured (1, 2 or 3)
32+
33+
- 1 x ESP32 Dev Kit V1
34+
- 1 x 5V USB power supply with micro USB cable
35+
- 1 x ZMPT101B AC Transformer Module 250VAC, 5-30VDC
36+
- N x SCT013 Split Core Current Transformer 100A-50mA. Other models can be used, see below.
37+
- 2 x N x 10 kOhm resistor
38+
- N x 10uF electrolytic capacitor
39+
- N x 22 Ohm resistor. If using another range/model of current sensor, the resistance will change or the resistor will not be needed at all.
40+
- N x 2.5mm stereo audio connector
41+
- Wires and a prototype board for connecting everything
42+
43+
![Parts and final assembly](images/electronic_parts.png)
44+
*Parts and preliminary assembly of the prototype board*
45+
46+
47+
### Using a different model of the current sensor
48+
49+
There are currently two types of current sensors under the SCT013 family:
50+
- Sensors that output current, typically 50mA
51+
- Sensors that output voltage, typically 0-1V
52+
53+
The default circuit used for this project uses a 100A range transformer with a 50mA output. If you are going to use another range of sensor (10A, 15A, 30A, etc...) but still with mA output, you need to recalculate the burden (22Ω) resistor. Open Energy Monitor has a [nice tutorial](https://learn.openenergymonitor.org/electricity-monitoring/ct-sensors/interface-with-arduino) on how to do that.
54+
55+
If you decide to use a 0-1V output sensor, the burden resistor (22Ω) will not be required because it is already embedded in the probe. Later, in the software configuration, you need to adjust the ADC attenuation to improve the accuracy in this reading range of your probe.
56+
57+
### Multiple voltage measurements
58+
59+
If the energy monitor is going to be installed at the inlet of a property, the phases should be balanced and there is no reason for having more than one voltmeter. I understand that for some rare scenarios, the user would prefer to have different voltage measurements one per phase. Fortunately both the hardware and the software are prepared for that.
60+
61+
### ESP32 analog input pins
62+
63+
The ESP32 DEV Board has two ADC (Analog to Digital Converter) registers but due the Wifi communication, only one is available for this project. Therefore, sensors can only be connected to the following GPIOs: 32, 33, 34, 35, 36, 37, 38 and 39.
64+
65+
66+
### Diagram and assembly
67+
68+
This diagram illustrates the typical connection of a single current probe and a single voltage probe. Multiple current probes require a set of resistors and capacitors for each one. The 22Ω burden resistor is not required for current probes that output 1V.
69+
70+
The voltage meter must be installed between the **neutral line** and one **phase**, not between phases.
71+
72+
![ESP32 Energy Monitor Schematic](images/ESP32-Energy-Monitor.png)
73+
74+
75+
## Software
76+
77+
The project repository contains 3 firmware for the ESP32:
78+
1. The voltage sensor potentiometer calibration tool. It is used only once to set the position of the potentiometer screw.
79+
2. The voltage and current sensor calibration tool. It provides a quick way to determinate all calibration coefficients. You could do this directly from the ESPHome firmware but it takes much longer to compile, boot and measure.
80+
3. The final ESPHome firmware source.
81+
82+
All tools require editing some configuration files before uploading to the ESP32 board.
83+
84+
### Requirements
85+
- [ESPHome](https://esphome.io/)
86+
- [Arduino IDE 2.0 or higher](https://www.arduino.cc/)
87+
- Any text editor for customizing the other files
88+
- Micro USB cable to connect with the ESP32 development board
89+
- Multimeter or voltmeter+ammeter for calibration
90+
- Resistive load for calibration (at least 5A): heater, boiler, electric shower, electric oven, kettle, etc...
91+
92+
### Adding support for the ESP32 to Arduino IDE
93+
94+
Before we can compile ESP32 firmware using the Arduino IDE, we need to install the support for this board.
95+
96+
Add the following URL to the *Aditional Boards Manager* in Arduino IDE preferences:
97+
```https://dl.espressif.com/dl/package_esp32_index.json```
98+
99+
For more information, there is a detailed tutorial in the reference links below.
100+
101+
## Calibrating the ZMPT101B potentiometer
102+
103+
The ZMPT101B has a potentiometer (blue component with a screw on top) that needs to be adjusted only once. The *calibrate-pot.ino* sketch was developed to be used with the Arduino IDE serial plotter for this task.
104+
105+
1. Set up the hardware
106+
2. Plug the ZMPT101B to an AC voltage source. This voltage should be close to the voltage you will eventually read during the operation of this device. Do not connect to AC sources that generate square waves (no-break, inverters, etc...).
107+
3. Edit *calibrate-pot.ino* and change the GPIO pin according to your hardware.
108+
4. Compile and upload the code from Arduino IDE.
109+
5. Open the Serial Plotter view, set baud rate to 115200bps.
110+
6. Turn the potentiometer screw clockwise or counterclockwise until you see that the bottom and top of the curves transition from flat to curved. Do not exceed too much the transition zone (between flat top and curved top) because it decreases the sensibility of the sensor.
111+
112+
![Potentiometer out of calibration](images/potenciometro-descalibrado.png)
113+
*Potentiometer not calibrated (flat top)*
114+
115+
![Potentiometer properly calibrated](images/potenciometro-calibrado.jpg)
116+
*Potentiometer calibrated (round top)*
117+
118+
## Calibrating the current and voltage sensors
119+
120+
The sketch *calibrate-vi.ino* should be used to calibrate the current voltage sensors. It outputs the calibrated values every couple of seconds for each one of the sensors. The ESPHome firmware can also be used but the entire calibration process will take much longer since the device has a longer initialization cycle.
121+
122+
This piece of code can also be used to create your own Energy Monitoring solution without relying on ESPHome at all.
123+
124+
1. Set up the hardware, the potentiometer of the voltage sensor should be already adjusted.
125+
2. Find an "almost pure" resistive load (no motors, no reactors, no electromagnets, no LEDs). Examples: heater, boiler, electric shower, electric oven, kettle...
126+
3. Install a voltmeter and ammeter to use as reference.
127+
4. Connect the voltage measurement and current measurement sensors.
128+
5. Edit the sketch *calibrate-vi.ino* and set the correct GPIO pins for the sensors.
129+
6. Set the calibration coefficients CV1, CV2, CV3, CI1, CI2 and CI3 to 1000 in the same file.
130+
7. Compile and update the code from Arduino IDE.
131+
8. Watch the values in the serial terminal and wait for them to stabilize. Use 115200bps as baud rate.
132+
9. Take a note of the measured current (I) and voltage (V) from the ESP32 and the current and voltage from the reference voltmeter (Vr) and ammeter (Ir).
133+
10. Calculate the calibration factors: CVnew = Vr*CVold/V, CInew = Ir*CIold/I where CVold and CIold are the previous calibrations from the sketch (initially 1000).
134+
11. Change the values under the "Calibration" section of the code to the calculated ones (CInew and CVnew).
135+
12. Compile and upload the code again, watch the serial monitor until the data stabilizes and then check if the measurements are correct.
136+
13. Repeat steps 8 to 12 if necessary.
137+
138+
**TIP:** You can later fine tune the calibration by applying [ESPHome filters](https://esphome.io/components/sensor/index.html#sensor-filters) to each sensor. Note that the "Apparent Power" and "Real Power" will also require calibration because they are computed before the current and voltage filters kick in.
139+
140+
## Configuring the ESPHome firmware
141+
142+
### *esp32emon.h* configuration file
143+
144+
#### Minimum settings
145+
- **Polling interval:** How frequent the device will read report the readings, defaults to 30s (30000ms). If under 5s, the Wifi or MQTT connection can crash due congestion.
146+
- **Pin configuration:** The GPIO where each sensor is connected.
147+
- **Calibration:** Coefficients for voltage (CV) and current (CI) sensors. Add the values obtained from the current and voltage sensor calibration steps.
148+
- **Uncomment/comment** various code sections to enable/disable phases to be measured. Default is two phases enabled.
149+
- **For the *Totals* block**: uncomment **only one block** corresponding to the total amount of phases to be measured.
150+
151+
#### Advanced/optional settings
152+
- **Analog attenuation:** Adjust to improve the accuracy of sensors that operate at lower voltage ranges. This setting is per GPIO.
153+
- **Sample window length / crossings:** How many half wavelengths will be used for the RMS voltage and current computations. Higher values will decrease the noise and make the readings more stable but the device will take longer to compute each one of the parameters. Too long values will activate the watchdog and the ESP32 will restart. Try 30, 60, 90 and 120 and see what fits best.
154+
- **Watchdog timeout:** If the measurement takes too long, the ESP32 watchdog will assume the code crashed and will restart the device. Increase this if the device is restarting after using large crossing values.
155+
156+
### *secrets.yaml* configuration file
157+
- **Rename the file *EXAMPLE_secrets.yaml* to *secrets.yaml*** and add/edit your passwords and login information for different services.
158+
159+
### *esp32emon.yaml* configuration file
160+
161+
#### Minimum settings
162+
- **Custom sensors lambda function:** Uncomment (remove //) from the line corresponding to the amount of phases to me measured. Default is 2 phases. Do not leave more than one *return* line uncommented
163+
- **Phase 1, 2 and 3 *sensor* blocks:** Uncomment (remove #) from the blocks corresponding the phases to me measured. Default is 2 phases so two blocks are enabled.
164+
165+
#### Advanced/optional settings
166+
- **Wifi settings:** Enable/disable multiple networks. The SSID and passwords should be stored in the file *secrets.yaml*
167+
- **MQTT integration:** Uncomment the block to enable MQTT integration. Servers and passwords should be stored in the file *secrets.yaml*
168+
- ***Restore* setting for energy consumption:** Set to *true* to save the integrators value to the flash memory. This prevents data loss during power outages but can reduce the lifespan of the ESP32 device. If you are using Home Assistant you can keep it disabled because Home Assistant will keep track of the values even if the ESP32 counters reset.
169+
- **Home Assistant integration:** There is no need to disable it, even if you are only going to use MQTT.
170+
171+
### Flashing ESPHome firmware to the ESP32 board
172+
173+
```esphome run esp32emon.yaml```
174+
175+
Please refer to [ESPHome website](https://esphome.io/guides/getting_started_command_line.html) for detailed instructions.
176+
177+
**TIP:** If you want to go fast, avoid Docker version of ESPHome, use [manual installation](https://esphome.io/guides/installing_esphome.html) instead. The connection to hardware devices from the manual installation is much easier than from a container.
178+
179+
## Home Assistant Integration
180+
181+
Home Assistant integration is enabled by default. The device should be automatically discovered if in the same network as the Home Assistant server (it can take a up to 30 minutes). If not, add the integration manually using the IP address of ESP32 as host address.
182+
183+
If you have a complex Home Assistant setup, with multiple networks or servers and the default integration does not work, you can fall back to the Home Assistant MQTT mode. Just enable MQTT and the discovery mode in *esp32emon.yaml*.
184+
185+
![Home Assistant Integration Screenshot](images/home_assistant_integration.png)
186+
*Home Assistant Integration after automatic detection*
187+
188+
## MQTT Integration
189+
190+
MQTT integration is disabled by default. To enable, uncomment the lines in the yaml configuration file and adjust the settings in the *secrets.yaml* file.
191+
192+
## Frequently asked questions
193+
194+
- **Can I use a CT clamp rated for another current (20A, 30A, etc...)?** Yes but you need to recalculate the burden resistor or eliminate it.
195+
196+
- **I don't have a neutral wire. Can I use 2 phases for voltage measurement?** Yes, but you need to change the power calculations in the code.
197+
198+
- **Losing Wifi or MQTT connection** Try to decrease the CROSSINGS setting in *esp32emon.h*. The blocking nature for Emonlib sometimes does this.
199+
200+
- **ESPHome webserver is crashing** The web server was disabled because it was crashing the ESP32. due the blocking nature of Emon library. You may be able to run it if you decrease the CROSSINGS setting in *esp32emon.h*.
201+
202+
## Further reading and references
203+
- [Savjee Home Energy monitor with ESP32](https://savjee.be/blog/Home-Energy-Monitor-ESP32-CT-Sensor-Emonlib/)
204+
- [EmonLib for ESP32 from Savjee](https://github.com/Savjee/EmonLib-esp32)
205+
- [IoT Based Electricity Energy Meter using ESP32 & Blynk](https://how2electronics.com/iot-based-electricity-energy-meter-using-esp32-blynk/)
206+
- [Zmpt101b Precision Voltage Sensor Module](https://community.home-assistant.io/t/zmpt101b-precision-voltage-sensor-module/124617/13)
207+
- [Open Energy Monitor original EmonLib](https://github.com/openenergymonitor/EmonLib)
208+
- [Open Energy Monitor - Interfacing CT sensors with Arduino](https://learn.openenergymonitor.org/electricity-monitoring/ct-sensors/interface-with-arduino)
209+
- [Measure AC voltage with ZMPT101B and ESP8266 12E](https://www.hackster.io/SurtrTech/measure-ac-voltage-with-zmpt101b-and-esp8266-12e-24e367)
210+
- [ESP32 ADC – Read Analog Values with Arduino IDE](https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/)
211+
- [Installing ESP32 libraries on Arduino IDE 2.0](https://randomnerdtutorials.com/installing-esp32-arduino-ide-2-0/)

Diff for: calibrate-pot/calibrate-pot.ino

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* Calibrates the potentiometer of the ZMPT101B module */
2+
/* ----------------------------------------------------*/
3+
/* Instructions:
4+
1. Set up the hardware
5+
2. Plug the ZMPT101B to an AC voltage source. This voltage should be close to the voltage you will eventually read during the operation of this device. Do not connect to AC sources that generate square waves (no-break, inverters, etc...).
6+
3. Edit *calibrate-pot.ino* and change the GPIO pin according to your hardware.
7+
4. Compile and upload the code from Arduino IDE.
8+
5. Open the Serial Plotter view, set baud rate to 115200bps.
9+
6. Turn the potentiometer screw clockwise or counterclockwise until you see that the bottom and top of the curves transition from flat to curved. Do not exceed too much the transition zone (between flat top and curved top) because it decreases the sensibility of the sensor.
10+
*/
11+
12+
// Pin configuration
13+
#define ZMPT101B_PIN 34
14+
15+
void setup()
16+
{
17+
Serial.begin(115200);
18+
19+
// Analog attenuation: When using 0-1V sensors the attenuation should be decreased to improve accuracy.
20+
// ADC_0db: sets no attenuation. ADC can measure up to approximately 800 mV (1V input = ADC reading of 1088).
21+
// ADC_2_5db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1100 mV. (1V input = ADC reading of 3722).
22+
// ADC_6db: The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 1350 mV. (1V input = ADC reading of 3033).
23+
// ADC_11db (default): The input voltage of ADC will be attenuated, extending the range of measurement to up to approx. 2600 mV. (1V input = ADC reading of 1575).
24+
25+
analogSetAttenuation(ADC_11db);
26+
27+
pinMode(ZMPT101B_PIN, INPUT);
28+
}
29+
30+
void loop()
31+
{
32+
Serial.println(analogRead(ZMPT101B_PIN));
33+
delay(17);
34+
}

0 commit comments

Comments
 (0)