Energy Tracking with ESP32 + CT Clamp Sensor from an Efergy elite 1.0R

After seeing the introduction of the Energy section in Home Assistant, I wanted to get onboard with monitoring the homes electricity consumption.

The CT clamp from an old wireless Efergy elite energy monitor can be used.
There are no codes wrote on this, so it wasn’t clear at the time if there was a burden resistor already fitted.

With a customised clampable extension lead, an accurate plug in power monitor and an oscilloscope, I was able to measure the AC voltage coming out of the clamp.

After some trial and error, I used a 22 Ohm burden resistor and a 2KW fan heater.
The peek to peek voltage on the clamp was just under 0.5 volts AC

This means its possible to read up to 12KW (52amps @ 230v)
At this current, the clamp will read about 3v AC (upper limit of the ESP32 ADC)
4KW is generally the maximum load that we use at home, so should be ok, although I might lower the burden resistor value in the future.

The circuit was built based on the one that’s everywhere online. The image is using my own resistor values.
Electricity monitor

I will be re-building this circuit and put it all in an enclosure.
This was just a (very) rough quick build !
There is also another 10uF cap across the 3.3v supply. Its not included in the circuit diagram. In all honesty, its probably not even needed.

After hooking it all up, figuring out the code and the calibration values, everything works great:

esphome:
  name: electricity-monitor
  platform: ESP32
  board: esp32dev

wifi:
  networks:
  - ssid: !secret wifi_ssid1
    password: !secret wifi_password1
  - ssid: !secret wifi_ssid2
    password: !secret wifi_password2

  manual_ip:
    static_ip: 192.168.0.223
    gateway: 192.168.0.1
    subnet: 255.255.255.0

captive_portal:

api:

ota:

sensor:
  - platform: ct_clamp
    sensor: adc_sensor
    name: "raw"
    update_interval: 10s
    accuracy_decimals: 5
    
  - platform: ct_clamp
    sensor: adc_sensor
    sample_duration: 300ms
    name: "Electricity usage (amps)"
    update_interval: 10s
    accuracy_decimals: 3
    filters:
      - calibrate_linear:
          - 0.003 -> 0
          - 0.147 -> 8.63    # value as per power plug
    
  - platform: ct_clamp
    sensor: adc_sensor
    sample_duration: 300ms
    name: "Electricity usage"
    id: esp_watts
    update_interval: 10s
    accuracy_decimals: 3
    filters:
      - calibrate_linear:
          - 0.003 -> 0
          - 0.147 -> 8.63    # value as per power plug
      - lambda: return x * 230.0 / 1000;
    unit_of_measurement: "Kw" 

  - platform: adc
    pin: A0
    id: adc_sensor
    attenuation: 11db
#    name: "Volts"
    update_interval: 10s
#========================  
    
  - platform: total_daily_energy        # This sensor will give you a Daily kW reading
    name: "Total Daily Energy"
    unit_of_measurement: 'kWh'
    power_id: esp_watts
    accuracy_decimals: 3
    filters:
    device_class: energy
    
time:
  - platform: sntp
    id: my_time

I’m surprised and impressed just how accurate this is.
As of writing this, its been running for almost 24 hours now and has been spot on.

I originally attempted to get this to work with an ESP8266 - nodemcu version.
It worked - sort of, but was not accurate and picking up noise which sent the numbers all over the place.
This was before I realised what the burden resistor was for.
If it wasn’t for the low resolution of the 8266s analogue connection, I would pursue this - just for the hell of it !!

Please let me know if you have any comments/suggestions/questions.
I’m aware the code could be more efficient. Feel free to suggest improvements.
Some of the code was just to see visually what’s going on during the calibration process (easier to look at on a dashboard compared to the log file).

Enjoy,
Ian.

5 Likes

I made this!
I did it with ES8266

Hi Adagio. Is that still working well with the ESP8266?

A lot has changed in the world since I posted (can’t believe its over a year ago).
Now more than ever we need to keep track of energy usage !!

1 Like

Hey dj-eon!
Honestly, it worked great for a while I got good and accurate readings then one day it didn’t. I moved some wires around and it just wouldn’t give me a good reading anymore. My current clamp was damaged at some point and I repaired it, and I think that one of the wires in the coil broke.

So I bought a DFRobot kit and installed that with some changes to the YAML and it works great now.

Thank you for sharing your project!
And thank you for reaching out!

I’ve attempted to replicate this project using ESP32 and SCT-013-000 (100A clamp without the burden resistor. using ESPHOME.
I cannot get it to work, and it has become a matter of pride now. :slightly_smiling_face:
I know that the ESP32 ADC is not very accurate, but I was not expecting it to be this bad!

It looks to me like the ADC is getting swamped at very low current levels.

Here is my YAML from the ESPHOME add-on:

esphome:
  name: "esphome-web-xxxxx"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "xxxxxxxxx"
    password: "xxxxxxxxx"

captive_portal:

sensor:
  - platform: ct_clamp
    sensor: adc_sensor
    name: "ESP xxxxxxx Measured Current"
    id: current
    sample_duration: 3000ms
    update_interval: 5000ms
    #filters:
    #  - calibrate_linear:
    #      - 0.017 -> 0
    #      - 1.410 -> 13.33

  - platform: adc
    pin: GPIO34
    id: adc_sensor
    accuracy_decimals: 5
    attenuation: 11db
    # update_interval: never
    # update_interval: 3000ms   

and here is the output of this charted (raw Amps) - not calibrated.

and here is the circuit:


where the ADC used is GPIO34.
From my calculations the R3 of 22kohms is about what I should be using for this setup.
But when I initially did the circuit I did omit the burden resistor and I wonder If I’ve damaged the ESP32.
But then would the ADC work at all?

does anyone have any ideas on what I’ve done wrong?
I’ve got a multimeter, so can measure the circuit at different diagnostic points if that would help.
I’ve checked and rechecked it!
other things I’ve wondered:
-do I need to ground all the GND pins on the board?
-do I need to go with a different burden resistor if I in reality want to measure currents well below 100A - I really only need 30A max, maybe less. I could not get the lower amperage CT clamp at the time, and if necessary I can get another one, but at the same time I don’t see why it should not work to some degree.

Any help anyone offers would be appreciated!!!

Edit 22 April 2023:
I’ve realised my burden resistor was 22K not 22 ohms. All sorted now.