Read value analogRead(0); while digitalWrite(13, HIGH);

Hi, I’m trying to convert an Arduino I’ve had running a tank level program for a few years to ESPHome.
The actual tank level sensing if via a pressure sensor, where the current is measured across it.
The values are stored locally, using EPROM.h although I’m guessing I can just pull the values in to HA.

To read the current it needs to pull a pin high, then read the value then drop the pin low.

I think these are the relevant parts.

// put your setup code here, to run once:
  pinMode(0, INPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  pinMode(15, INPUT);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);

  EEPROM.begin(4);
  EEPROM.get(0, min_tank_level);
  EEPROM.get(2, max_tank_level);
  if( min_tank_level == 65535 && max_tank_level == 65535 )
    max_tank_level = 0;
  if( max_tank_level < min_tank_level )
    max_tank_level = min_tank_level;
}

  Serial.println("Read water level");
  digitalWrite(13, HIGH);
  delay(500);
  for( i = 0; i < 64; ++i ) {
    val += analogRead(0);
    if( i != 63 )
      delay(5);
  }
  digitalWrite(13, LOW);
  Serial.println("Done");
  last_tank_levels[cur_tank_level] = val;
  if( ++cur_tank_level == NUM_MINMAX_TANK_LEVELS )
    cur_tank_level = 0;
    // debug to see cur_tank_level value
    Serial.print("cur_tank_level");
    Serial.println(cur_tank_level);
    // end of debug
  if( total_tank_levels < NUM_MINMAX_TANK_LEVELS )
    ++total_tank_levels;
    // debug to see total_tank_levels value
    Serial.print("total_tank_levels");
    Serial.println(total_tank_levels);
    // end of debug
  reset_min_max_levels = digitalRead(15);
  if( reset_min_max_levels )
    Serial.print("resetting min/max levels");
  if( total_tank_levels == NUM_MINMAX_TANK_LEVELS || reset_min_max_levels ) {
    Serial.println("total_tank_levels == NUM_MINMAX_TANK_LEVELS");
    unsigned short min_level = 65535, max_level = 0, changed = 0;
    for( i = 0; i < NUM_MINMAX_TANK_LEVELS; ++i ) {
      Serial.print("For Loop ");
      Serial.println(i);
      if( last_tank_levels[i] < min_level )
      Serial.print(last_tank_levels[i]);
      Serial.println("last tank level less then min level");
        min_level = last_tank_levels[i];
      if( last_tank_levels[i] > max_level )
      Serial.print(last_tank_levels[i]);
      Serial.println("last tank level more then max level");
        max_level = last_tank_levels[i];
    }
    Serial.print("min = ");
    Serial.print(min_level);
    Serial.print(", max = ");
    Serial.println(max_level);
    if( reset_min_max_levels ) {
      min_tank_level = 65535;
      max_tank_level = 0;
    }
    if( max_level < min_tank_level && max_level > 5000 ) {
      min_tank_level = max_level;
      Serial.print("Update to eprom min level ");
      Serial.println(min_tank_level);
      EEPROM.put(0, min_tank_level);
      changed = 1;
    }
    if( min_level > max_tank_level ) {
      max_tank_level = min_level;
      Serial.print("Update to eprom max level ");
      Serial.println(max_tank_level);
      EEPROM.put(2, max_tank_level);
      changed = 1;
    }
    if( changed )
      Serial.println("Commit Data");
      EEPROM.commit();
  }

So far I’m only reading Pin0, I can workout how to read only while holding another pin high.

esphome:
  name: tank-level
  friendly_name: Tank Level

  libraries:
    - Wire
    - SimpleDHT
    - EPROM
    
esp8266:
  board: esp01_1m

sensor:
  - platform: adc
    pin: A0
    name: "Voltage"

My progress so far.

switch:
  - platform: gpio
    name: "GPIO13 Switch"
    pin: GPIO13
    id: GPIO13_switch
    internal: True

binary_sensor:
  - platform: gpio
    pin: GPIO4
    id: GPIO4
    internal: true

  - platform: gpio
    pin: GPIO5
    id: GPIO5
    internal: true

sensor:
  - platform: template
    name: "Tank Level"
    id: tank_level

interval:
  - interval: 5min
    then:
      - switch.turn_on: GPIO13_switch
      - delay: 500ms
      - lambda: |-
          int i;
          int val = 0;
          for (i = 0; i < 64; ++i) {
            val += analogRead(A0);
            if (i != 63)
              delay(5);
          }
          id(tank_level).publish_state(val / 64.0);
      - switch.turn_off: GPIO13_switch

This is how I have it working so far, if anyone can think of a better way please let me know.
I would like to have been able to do all the calculations on the WeMos device.

This is my ESPHome YAML file

esphome:
  name: tank-level
  friendly_name: Tank-Level
  libraries:
    - Wire

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxx"

ota:
  password: "xxxxx"

#web_server:
#  port: 80

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 10.x.x.x
    gateway: 10.x.x.x
    subnet: 255.255.255.0
    dns1: 10.x.x.x
    dns2: 10.x.x.x
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Tank-Level Fallback Hotspot"
    password: "xxxxxxx"

#captive_portal:

switch:
  - platform: gpio
    name: "GPIO13 Switch"
    pin: GPIO13
    id: GPIO13_switch
    internal: True

binary_sensor:
  - platform: gpio
    pin: GPIO4
    id: GPIO4
    internal: true

  - platform: gpio
    pin: GPIO5
    id: GPIO5
    internal: true

sensor:
  - platform: template
    name: "Tank Level"
    id: tank_level
    update_interval: 5min

interval:
  - interval: 5min
    then:
      - switch.turn_on: GPIO13_switch
      - delay: 500ms
      - lambda: |-
          Serial.print("Read water level");
          int i;
          int val = 0;
          for (i = 0; i < 64; ++i) {
            val += analogRead(A0);
            if (i != 63)
              delay(5);
          }
          id(tank_level).publish_state(val / 64.0);
      - switch.turn_off: GPIO13_switch

Then I created the following sensors, and min max statistics.

template:
  - sensor:
      - name: "Raw Tank Level"
        unit_of_measurement: V
        unique_id: raw_tank_level
        state: >
          {% set raw_tank_level = states('sensor.tank_level_tank_level_2') | float %}
          {{ (raw_tank_level) }}

  - sensor:
       name: Tank Percent
       unit_of_measurement: "%"
       unique_id: tank_percent
       state: > 
        {% set cur_val = states('sensor.raw_tank_level') | float %}
        {% set max_val = states('sensor.max_tank_level') | float  %}
        {% set min_val = states('sensor.min_tank_level') | float  %}
        {% if max_val == min_val %}
          0
        {% else %}
          {{ ((cur_val - min_val) * 100 / (max_val - min_val)) | int }}
        {% endif %}

sensor:
  - platform: statistics
    name: "Min Tank Level"
    entity_id: sensor.tank_level_tank_level_2
    unique_id: min_tank_level
    state_characteristic: value_min
    sampling_size: 8640
    max_age:
        days: 30

  - platform: statistics
    name: "Max Tank Level"
    entity_id: sensor.tank_level_tank_level_2
    unique_id: max_tank_level
    state_characteristic: value_max
    sampling_size: 8640
    max_age:
        days: 30

I don’t really know what I’m doing, I actually used OpenAI and asked it lots of questions until I had the code above.
I need to fix the percent so that it doesn’t go below 0 or above 100.
And I need to keep an eye on the min and max, as ideally those figures need to be very long lived, in that my rain water tank can take several months to go from 0% to 100% with lots of cycling between 20% and 80%.