Variables In calibrate_linear

I have a pH meter that I want to re-calibrate by setting measured values for pH 4 and 7. Currently, I do this manually my logging raw measurements and updating the config.

  - platform: adc
    pin: A0
    update_interval: 1s
    unit_of_measurement: pH
    # https://esphome.io/components/sensor/index.html#sensor-filters
    filters:
      # Smoothing out significant variance, switch to an Apera probe and ASD1115 for better accuracy
      - quantile:
          window_size: 10
          send_every: 1
          send_first_at: 1
          quantile: .8
      - lambda: |-
           ESP_LOGD("adc", "Quantized voltage=%fv", x);
           return x;
      - sliding_window_moving_average:
          window_size: 5
          send_every: 3
          send_first_at: 1
      - lambda: |-
           ESP_LOGD("adc", "Moving average voltage=%fv", x);
           return x;
      # Measured voltage -> Actual pH (buffer solution)
      # Lower the potentiometer (counter-clockwise) at pH 7.
      # Pick a baseline voltage (the log entry above) on the low end of the range to leave room for the higher voltage of low pH.
      # Then, switch to pH 4 and note the voltage. Do not worry about expected voltages (e.g. 2.5v) found in random tutorials.
      - calibrate_linear:
          - 0.79 -> 7.0
          - 0.93 -> 4.0
      - lambda: |-
           ESP_LOGD("ph", "read=%fpH", x);
           return x;

I know how to set globals, I just want to read them in calibrate_linear like this pseudo-code:


globals:
  - id: ph7_value
    type: float
    restore_value: yes
    initial_value: 0.79
  - id: ph4_value
    type: float
    restore_value: yes
    initial_value: 0.93

...
     - calibrate_linear:
          - !lambda 'return ph7_value -> 7.0;'
          - !lambda 'return ph4_value -> 4.0;'

I haven’t tried but I don’t think my lambda syntax is right. Is there a simple way to do this? Can I naively return a string formatted with the → arrow? Or should I implement my own linear calibration math in a lambda tag.

The calibrate linear filter does not support lambdas.

If you want to do this you will have to create a Lambda Filter that implements the linear transform.

You can calculate the linear equation y = mx + c from the following:

m = (7.0 - 4.0)/(ph7_value - ph4_value)
c = 7.0 - (m * ph7_value)
1 Like

Thank you, I successfully managed to replace calibrate_linear by a lambda function.

- calibrate_linear:
  - voltage_full -> 100
  - voltage_empty -> 0

was replaced by

- lambda: return ((100 - 0)/(id(voltage_full).state - id(voltage_empty).state)) * x + (100 - (((100 - 0)/(id(voltage_full).state - id(voltage_empty).state)) * id(voltage_full).state));`