'adc' and 'ct_clamp'

I’ve tried searching for similar questions to mine, but they’re mostly about the circuit requirements for wiring up an AC current clamp to the ADC. I don’t have an issue with that, I measure a constant DC voltage proportional to the peak AC current measured by the clamp (via a DF Robot Gravity AC current sensor board).

My questions are:

- What is the uncalibrated relationship between adc and ct_clamp?
For a scaled voltage between around 0.773 and 1.144 volts (at the NodeMCU input, i.e. the input to the potential divider, not the output), I get a ct_clamp value of 0.00395 A to 0.00587 A. I was expecting a 1:1 ratio.

The values I’ve got do seem to infer a 0,0 intercept, but I don’t understand the scaling? I know my CT is 20A, so I should get roughly 3.3 V DC for 20 A AC current. The voltage reported by ‘adc’ in the logs is correct, but the current reported by ct_clamp is multiplied by a factor of 0.0052. Where does this come from?

- Why does ct_clamp have 'sample_duration’
Why is this relevant, when the value is being updated by ‘adc’, at a much slower rate?

- Why does ct_clamp appear to update more regularly than adc?
The logs appear to show updating ct_clamp values that are changing more frequently than the update internal configured for ‘adc’. To test this, I left ‘adc’ at the default 60 seconds, and set ‘ct_clamp’ to 5 seconds.

- Is a fast update feasible?
Ultimately, the aim is to switch an output if the current goes above a threshold. I need this to happen within 0.5 seconds or less. So far, my testing with trying to increase the update rate has resulted in the ESP8266 failing to connect to the wifi and/or ESPhome. Any ideas on this?

  - platform: ct_clamp
    sensor: adc_sensor
    name: "${friendly_devicename} Current"
    update_interval: 5s 

  - platform: adc
    pin: A0
    name: "ADC sensor"
    id: adc_sensor
      - multiply: 3.3

possibly because a physical ct_clamp is going to be varying in voltage in sync with (but 90 degrees off) the AC circuit it’s measuring.
So, if your ADC took an instance reading from it, ADC could see anything from -X, to 0, to +X, where X is the peak-to-peak voltage induced into the clamp.
You would need either a smoothing circuit on the clamp (e.g. rectifier and capacitor, plus bleed-off resistor, and all the relevant math to know what their effective output actually represents) or a sampling algorithm that ‘knows’ how to take multiple voltage samples across (perhaps) multiple cycles of the circuit’s AC period in order to compute the actual RMS value (which is probably what you’re seeking).

If the ct_clamp module wants to know the period of the input signal, that would be a big hint to me that it’s the better choice. It does in fact want the sample_interval, which is even better, and the dox indicate that it will be sampling across several periods of the input waveform, which is what it needs to do in order to obtain a meaningful reading.
Go with ct_clamp.

Having done some more reading, I think ct_clamp is intended to process a raw offset sine wave, like this.


So in my case, ct_clamp was attempting to calculate an RMS value from the noise on my DC voltage - not very useful at all.

I’ve just dropped the ct_clamp and used adc by itself, it does everything I need, as my analogue input is already a steady DC voltage proportional to the RMS AC current, not the waveform itself.

  - platform: adc
    pin: A0
    name: "Auto Socket ADC sensor"
    id: auto_socket_adc_sensor
    update_interval: 100ms
    device_class: current
    state_class: measurement
    unit_of_measurement: "A"
    icon: mdi:flash
    accuracy_decimals: 2
    - calibrate_linear:
         # Measured value of 0 maps to 0A
      - 0.0 -> 0.0
          # ESPhome uses ESP8266 voltage (0-1V), after potential divider
          # Known load: 20.0 A at 1.0V, from datasheet
      - 1.0 -> 20.0

    - sliding_window_moving_average:
        window_size: 5
        send_every: 1

That’s great! Yeah, your CT device is already doing the electrical conversion I mentioned, so yes, it’s designed to do exactly what you did, since its output is already converted for use by a ADC.