Esphome ct calmp sct-013-000 and nodemcu

I am trying to connect my CT Clamp to my NodeMcu Amica using the CT Clamp ESPhome Integration.


# Example configuration entry

sensor:

- platform: ct_clamp

sensor: adc_sensor

name: "Measured Current"

update_interval: 60s

# Example source sensor

- platform: adc

pin: A0

id: adc_sensor

I am having limited success and non-linear readings.

I now understand that the burden resistor is there to convert the current into a voltage for the ADC input to use.

This is my setup.

I am using this example from a modified Wemos input board available on a popular auction site.

image
R1 is the burden resistor while R2 / R3 are the voltage divider

SCT-013-000 Non-invasive Split Core Current Transformer AC Current Sensor 100A

Having looked more closely the NodeMcu has the voltage divider circuit built in and measures 0-1V only on the A0 input.
image
image

After looking more closely at the calculated resistance required for the burden value I came up with the following based on other examples I have seen on the web.

CT RATIO OUTPUT
100/2000 100 2000 0.05 50 mA
3.3V/2 3.3 2 1.65 V
1.65V/0.05mA 1.65 0.05 33 ohm BURDEN

So my question is as follows, should I do away with the external voltage divider and change my burden resistor to 33 ohms and just connect a 10uF capacitor between GND and 3.3v?

Yes some nodeMCU boards take 3.3V full scale at the pin. So drop the external divider if yours does.

100A of current in the sense wire through the CT will produce 50mA out of the CT. You want 50mA to produce 3.3V. So for your burden resistor you need:

R = V / I

  = 3.3 / 50e-3

  = 66 Ohm (use 2x 33 Ohm in series)

Note that the resistors and the ADC voltage reference are not perfect and this will require some calibration (which can be done in software, see below). Also the 66 ohm burden resistor is in parallel with the 100K resistor, very slightly affecting the burden resistor - to the tune of about 0.1% so negligible compared to the 1% tolerance of the voltage divider resistors.

Your ESP template should use the this filter to get the actual amps through the CT from the ADC voltage

  - platform: adc
    pin: A0
    name: "Current"
    unit_of_measurement: "A"
    filters:
      - multiply: 100 # or 30.3 if your Nodemcu has a 3.3v output full scale like mine.

Make the multiplier smaller to reduce the displayed current to match the actual current as measured by a meter. Or make it larger to increase the displayed value.

1 Like

Thanks for that explanation.

I have done some more testing and I have simulated the A0 input with a voltage reference source.


3.3 v gives me
[07:09:07][D][adc:056]: ‘Current’: Got voltage=0.99V

1.65 v 50% gives me
[07:13:12][D][adc:056]: ‘Current’: Got voltage=0.43V

a little off but yeah I can calibrate it.

image

So from reading the above I should do away with the external divider, connect one leg of the CT to 3.3v and a 10 uF cap to GND.
66 ohm resistor in parallel with the CT and connect the other leg of the CT direct to A0.

Calibrate sensor as the following example.

 filters:
      - calibrate_linear:
          # Measured value of 0 maps to 0A
          - 0 -> 0
          # Known load: xA
          # Value shown in logs: x.xxxA
          - x.xxx -> .0

Next step hook up to CT and try to calibrate assuming my understanding of the above is correct?

Regards,

1 Like

There is no need for the 3.3v connection. The sense current will be produced by the current flowing in the wire you are measuring. So 66R in parallel with CT. One end of CT to GND other end to A0 (polarity is important!). If you want to protect the ADC input you can connect a Schottky diode from A0 (anode) to 3.3V (cathode). That way the voltage produced will flow to the supply rail if it exceeds 3.3V+Vf of the diode.

No need for the external divider. Use the 10uF (and possibly a 0.1uF as well) between A0 and ground if noise is a problem. Keep the capacitor leads as short as possible and as close to A0 and GND as possible.

Hi,
Not having much luck, not getting any output / input and just wondering if it has anything to do with the CT type, I have put the link below to the CT and my model is SCT013 100A:50mA.

Data sheet states ※ Output type: voltage output type built-in sampling resistor, current output type built-in protective diode.

Data Sheet

You mentioned before polarity is important and according to the data sheet the plug is labelled as L output and K output? is the output not AC as I have been able to measure AC mV between A0 and GND.

so to summarise what I have tried…

CT L Output to GND
CT K Output to A0
Burden resistor 60 ohm parallel accross L Output and K Output
10 uF Cap between GND and A0.

I have tried swapping the leads of the CT, no change.

Multi meter connected between GND and A0.

Regards,

Ah crap. I was stupidly assuming it was DC output. Forget everything I said. Your original circuit is correct.

See:

https://openenergymonitor.org/forum-archive/node/156.html

So all up and running wired as per my original config with 22 ohm burden resistor but my issue is with the erratic reading at zero amps.

image

This can affect the calibrated reading anywhere between 0 and 0.5 Amps, not ideal.

Is there anyway to factor this out in the calibration, something like

    filters:
      - calibrate_linear:
          - 0.00040 -> 0.0
          - 0.01393 -> 3.54
          - 0.02442 -> 6.56
          - 0.02455 -> 6.59

< 0.00100 -> 0.0 ?

I did see some example of

lambda Filter
filters:
  - lambda: return x * (9.0/5.0) + 32.0;

or am i off track?

Is there anything else other than the 10uF cap I can add to the circuit?

Regards,

I just saw your thread now, I have the same issue… My setup:
image

I get just crap. 0.46V all the time from the adc_sensor until I remove it from the A0 .
I use a Amica Nodemcu

Hi, my setup is working Okay and is repeatable, just trying to find a way to offset the zero.

So In my configuration I added another sensor to monitor the raw reading when I have the calibrate linear filter applied to the main Measured Current…

  • platform: ct_clamp
    sensor: adc_sensor
    name: “raw values”

If you look at your logs you will see for example 0.01801 represents 6.42298 A, this is implemented in the filters, - calibrate_linear:

forget using the adc_sensor for your reading.

[14:15:52][D][sensor:092]: 'adc_sensor': Sending state 0.41895 V with 2 decimals of accuracy

[13:49:04][D][sensor:092]: ‘raw values’: Sending state 0.01801 mA with 5 decimals of accuracy
[13:49:07][D][ct_clamp:051]: ‘Measured Current’ - Raw Value: 0.02A
[13:49:07][D][sensor:092]: ‘Measured Current’: Sending state 6.42298 A with 2 decimals of accuracy
[13:49:14][D][ct_clamp:051]: ‘raw values’ - Raw Value: 0.02A
[13:49:14][D][sensor:092]: ‘raw values’: Sending state 0.01807 mA with 5 decimals of accuracy

My config, I added the "raw values so I could log the values easier.

sensor:
  - platform: ct_clamp
    sensor: adc_sensor
    name: "Measured Current"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.0 -> 0
          - 0.01826 -> 5.15
          - 0.01952 -> 6.754
          - 0.01925 -> 7.09
          - 0.04057 -> 16.02
          - 0.07834 -> 31.37
            
          
  - platform: adc
    pin: 17
    id: adc_sensor


  - platform: ct_clamp
    sensor: adc_sensor
    name: "raw values"
    update_interval: 10s
    unit_of_measurement: mA
    accuracy_decimals: 5   

My setup for the initial calibration.

Portable electric heater with low (3.5 A) and high (6.9 A) low/high selector, CT and Multi meter in series measuring amps.

so taking the reading from the logs and then writing the linear values in the configuration gives a good repeatable reading.

My issue is when the load is zero i get an erratic reading. drifting between 0.2 a 0.5 A.
For the higher calibration values i transferred my setup to measure the main incoming supply to the house.
I then was able to put increased loading on the the CT as my Fluke can measure 10 Amps max,

With this I was able to calibrate the higher loads,16 A and 31 A by comparing readings from my smart meter and the readings from the log and modified the calibration linear table accordingly.

Thank you, I will try this and see if I can get it to work

did you get this working? Im stuck at the same level you were.

Hi,
I´m trying to connect a SCT013-20A-1V to ESPhome.
I cannot find any schematics for this CT (1V). Do you know where i can find one?!"

Best regards
Petter

Hi,

Use this

remove R1 burden resistor as your CT has it inbuilt.

Also have a look at

Regards,

1 Like

Sweet!
Works fine now!
Thanks a lot!

@MarkB1,
I’m trying to do the same thing with the SCT013 100A/50mA.
Can you share your final wiring diagram and ESP code? I want to do this with a D1 mini, I assume I can just map the pins from the nodemcu to the D1 mini?

Thanks!

Get one of these

ESP8266 Mains Current Sensor - Wemos - Current transformer - SCT013 - 100A/50mA

code

esphome:
  name: wemos_d1_mini_1
  platform: ESP8266
  board: d1_mini
  
  
wifi:
  ssid: 
  password: 
  power_save_mode: none
  
  manual_ip:  
   static_ip: 192.168.0.107
   gateway: 192.168.0.2
   subnet: 255.255.255.0
   
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Wemos D1 Mini 1 Fallback Hotspot"
    password: "VGaeoNIRWbVa"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:


# Enable Web server.
web_server:
  port: 80


text_sensor:
  - platform: version
    name: "ESPHome Version Wemos D1 Mini 1"

    
# Example configuration entry

  - platform: wifi_info
    ip_address:
      name: ESP IP Address Wemos D1 Mini 1
    ssid:
      name: ESP Connected SSID Wemos D1 Mini 1
    bssid:
      name: ESP Connected BSSID Wemos D1 Mini 1
      
      
# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

binary_sensor:

  - platform: status
    name: "wemos_d1_mini_1 Status"  
    
sensor:
  - platform: ct_clamp
    sensor: adc_sensor
    name: "Measured Current"
    update_interval: 10s
    filters:
      - calibrate_linear:
          - 0.00009 -> 0.0
          - 0.01300 -> 1.6
          - 0.01438 -> 1.94
          - 0.02088 -> 3.25
          - 0.02184 -> 3.51
          - 0.02312 -> 3.72
          - 0.02600 -> 4.34
#          - 0.02740 -> 5.0
#          - 0.04340 -> 6.75
#          - 0.08990 -> 17.1
            
          
  - platform: adc
    pin: A0
    id: adc_sensor   
    
    
# Sensors with general information.


  # Uptime sensor.
  - platform: uptime
    name: Wemos D1 Mini 1 Uptime


  # WiFi Signal sensor.
  - platform: wifi_signal
    name: Wemos D1 Mini 1 WiFi Signal
    update_interval: 60s


status_led:
  pin:
     number: D4
     inverted: FALSE
5 Likes

That’s a super neat and clean little board!

I have a question, how do you get voltage reported to HA?

I can get the Amperage with the ct_clamp platform no problem, but I cannot wrap my head around implementing lamda to do the math and send both amps and voltage to HA.

Instead of relying on the terrible ESP8266 ADC, and you will get a lot more information:

I don’t believe you can get Voltage from the sensor (assuming you are talking about the mains voltage.
If you mean the Voltage reading from the clamp then change the internal: to false as I have done below:

  - platform: ct_clamp
    sensor: adc_sensor
    name: "raw values"
    internal: false
    update_interval: 10s
    unit_of_measurement: mA
    accuracy_decimals: 5

I just thought I’d put my config in here if anyone likes the look of it, it deesn’t report any fluctuations below 0.1A, can be changed.

sensor:
  - platform: ct_clamp
    sensor: adc_sensor
    name: "True Current"                # This first sensor gets the Amps, note that is set to internal only.
    id: the_clamp
    internal: true
    update_interval: 10s
    filters:
      - calibrate_linear:               # Calibrate your own stuff here, mine is only used for the car charger, therefore I'm pulling approx 28A
          - 0.00026 -> 0.0
          - 0.02856 -> 8.37
          - 0.09489 -> 27.9

  - platform: template
    name: "ESP8266 Current"             # This sensor is the one that gets seen by HA, if the reading is below 0.1A then it reports 0, keeps your 0 at 0
    id: templated_sensor
    lambda: |-
      if (id(the_clamp).state > 0.1){
        return (id(the_clamp).state);
      } else {
        return 0.0;
      }
    device_class: current
    update_interval: 10s
    accuracy_decimals: 2
    unit_of_measurement: A

  - platform: template
    name: "ESP8266 Watts"               # This sensor converts the Amps to Watts (this is assuming that your voltage is 230, if not change the 230 accordingly)
    id: esp_watts
    lambda: |-
      return id(templated_sensor).state * 230;
    accuracy_decimals: 2
    update_interval: 10s
    device_class: power
    unit_of_measurement: W
                   
  - platform: total_daily_energy        # This sensor will give you a Daily kW reading
    name: "ESP8266 Daily Energy"
    unit_of_measurement: 'kW'
    power_id: esp_watts
    filters:
      - multiply: 0.001
    device_class: energy

  - platform: adc
    pin: A0
    id: adc_sensor   

  - platform: ct_clamp
    sensor: adc_sensor
    name: "raw values"
    internal: true
    update_interval: 10s
    unit_of_measurement: mA
    accuracy_decimals: 5
4 Likes