Esphome ct clamp 30A/1V

Have a look at these plots:

JSSut

The first blue plot is similar to what comes out of the CT. A sine wave centred on 0V swinging both positive and negative.

The ADC can only measure from 0 to 3.3V (middle red plot).

By shifting the CT output up a constant DC amount (1V in the third magenta graph) The ADC can now measure the full waveform as it is all above 0V.

The position of this DC bias point should be half way between 3.3V and 0 to meaure the maximum possible positive and negative parts of the CT waveform.

Supplying the voltage divider with 5V would shift this bias point too high (2.5V instead of 1.65V).

1 Like

Thanks @tom_l . Very clear explanation. The CT sensor I am using is from the Emporia Vue2 kit and I’m pretty sure it has something built into it. Only outputs 0-0.333v for the 50A clamp.

How are you measuring the 0 a 3.333v? You should be using a voltmeter set on AC voltage measurement. A Current Transformer monitoring an AC device generates an AC current or voltage, depending on the specific type of device. A normal AC voltmeter will not show any negative values. You need an oscilloscope to show the waveforms above.

Yes just using voltmeter connected to the 2.5mm jack pin of the CT clamp. The AC voltage I am measuring is in perfectly in line with the specs of the CT clamp when I use a known current.

Great! That means the voltage is alternating from positive to negative, and thus the voltage will need to be biased by +1.65v. Otherwise you’ll lose half of the waveform.

# using A6 instead of GPIO34, and setting the attenuation should sort it out.

# add a web server , this will help with debugging, calibration etc. very usefull,
# find the webserver at either 'webserver.local' or at port80 of the esp32's IP eg. 192.468.0.22:80
# to add a webserver include the following:
web_server: 					
 port: 80
 include_internal: true				
 ota: true
 local: true
 version: 2
 id: webserver


# not sure if it makes a diffrence but your code does not specify the framework type, 
# All of my sensors are set as follows:
esphome:
  name: esp32ct
esp32:
  board: esp32dev
  framework:
    type: arduino

# then remember to add time, you need this for daily consumption sensors
# add the following:
time:						
  - platform: sntp
    id: my_time

# then try the following sensors, you will be able to see the following in the front end: 
# your measured current (Amps) 
# your current consumption for the day (AmpHour)
# your measured Power (watts)
# daily power consumption (KiloWhattHour)

# the following should work fine :

sensor:                                       
  - platform: adc                      	# First sensor gets the voltage from the ADC
    pin: A6                       		# GPIO34 is A6
    attenuation: auto			# very imporatant esp32's give whacky results without this...
    accuracy_decimals: 5
    id: adc_sensor

  - platform: ct_clamp			# this internal sensor gives a calibrated 'raw' result 
    sensor: adc_sensor
    name: "Measured Current"
    internal: true
    update_interval: 5s
#    filters:					#uncomment this after calibration
#      - calibrate_linear:
#          - 0.01407 -> 0            
#          - 0.01759 -> 1
    accuracy_decimals: 5    
    id: measured_current

  - platform: template				# this will be the final current reading visible in the front end		
    name: "Current"            
    id: current
    lambda: |-					        # ignore readings below 1 Amp 
      if (id(measured_current).state > 1){ 
        return (id(measured_current).state);
      } else {
        return 0.0;
      }
    device_class: current
    update_interval: 5s
    accuracy_decimals: 2			
    unit_of_measurement: A  
    
  - platform: total_daily_energy		#this will calculate the total current used for the day (AmpHour)
    name: "Daily Current"
    power_id: measured_current
    accuracy_decimals: 2
    unit_of_measurement: Ah
    
  - platform: template				#this sensor will measure your power consumption (Watt)
    name: "Measured Power"            
    id: power
    lambda: |-
      return id(ct1_current).state * 235; 	#change the 235 to whatever your voltage is
    accuracy_decimals: 2
    update_interval: 5s
    device_class: power
    unit_of_measurement: W
    
  - platform: total_daily_energy  		#this will keep track of power consumed daily (kwh)      
    name: "Total Daily Power Consumption"
    unit_of_measurement: kWh
    power_id: power
    accuracy_decimals: 2
    filters:
      - multiply: 0.001
    device_class: energy


#hope this helps, this works on my esp32's , cant see why it wont work on yours.
##cheers
6 Likes

Hi
I like to do this project.
Question. If I search for a D1 Mini then there seem to be various makes & models.

Geekcreit® D1 Mini V3.0.0 WIFI
WEMOS D1 Mini Pro V3.0 NodeMcu
WEMOS D1 Mini Pro 4M 16M
D1 ESP32 Dev Board
D1 Mini Pro - ESP8266 - 16M
etc…

Which model D1 Mini should I select for this project?
Thanks.

Hi,
I’m a bit confused with my ESP32. I’m using the same circuit with 2x10k resistor and 10µF capacitor.
I need two ADC sensors for measuring my home power consumption and the production of my solar panels.
Both ADC sensors give 1.65V (as expected because of the voltage shift) and I can’t obtain usable values. My ESP32 is an AZ Delivery ESP32, I don’t know what is the ADC range for this device (0-1.1V or 0-3.3V)
Has someone solved the issue? Thanks

Seems like a lot of people are struggling with this. I think it is because the instructions don’t tell you to set the attenuation on ESP32 and to sample multiple times.

This worked for me on ESP32 with 10kOhm, 10uF capacitor, no burden resistor:

  - platform: ct_clamp
    sensor: adc_sensor
    name: "Measured Current"
    id: current
    sample_duration: 600ms
    update_interval: 3000ms
    filters:
      - calibrate_linear:
          - 0.012 -> 0
          - 0.025 -> 1.0

  - platform: adc
    pin: GPIO32
    id: adc_sensor
    attenuation: 11db
    # update_interval: never
    update_interval: 3000ms

If this helps someone else, please reply and I’ll update the ESPhome CT Clamp instructions.

4 Likes

The diagram and circuit you see here only works well on ESP32.
The reference voltage used internally by ESP32 ADCs for measuring the input voltage.
The ESP32 ADCs can measure analog voltages from 0 V to Vref (3.3v/2). The analog input pins of ESP32 have 12-bit resolution. You can measure varying voltage levels between 0 V and 3.3 V. (Espressif docs)
The ESP-12E ADC has a resolution of 10 bits and the analog input measures varying voltage levels between 0V to 1.0V.
The measured voltage will assigned to a value between 0 and 1023bits, in which 0V corresponds to 0, and 1.0V corresponds to 1023 bits. For ESP8266 you need a voltage divider to get 0.5V as Vref.

Sorry to resurrect an older post but I’m struggling to understand the hardware design comments above and appreciate any insight.

The espressif spec seems to say here that the ESP32 can not measure 0-3.3V rather only 0.15-2.45V at maximum attenuation (11db).

So for a CT clamp to operate within this range, the bias voltage would need to be centred at 1.3V (not 1.65V). Even then, a 1V output CT would get clipped when measuring high current loads as 1Vrms is 1.4Vpeak and would generate a signal of -0.1 - 2.7V at the input pin (i.e. beyond its range). If using a 50mA CT then you would need a burden resistor of around 15 ohms (not 22 ohms) to scale the signal down to a range the ADC attenuation can accommodate.

Does this make sense or am I about to have a “doh” moment ?

--------------- Extract from ESP32 spec --------------------------

While searching for how to set up a similar ct clamp solution for a 3 phase power connection I stumbled upon this old topic. After reading through the thread it stopped after posting 32. So, did anyone got this working properly and if so, what would be the correct schematic and yaml? I dont mind experimenting, but I hardly have any theoretical knowlegde about electronics.
Links to other topics or websites discussing this are also welcomed :slight_smile:

The raw analog input on the ESP32 chip is most likely only capable of measuring 0-1V (with the Attenuation set to 0).

Most microcontroller boards in include an onboard voltage divider that scales 0-3.3V to 0-1V. Thus, external 0-3.3V signals can be handled without a problem.

If you’re using a raw ESP32 chip, then you will need to scale the voltage yourself in hardware, to not overload the ESP32’s ADC.

My clamp says 20A/1V
so where does that put me with resistor/capacitors on an ESP32?