Geiger counter with HA integration?

Hi …
Had a journey … here what worked for me …

Hardware:

waveshare com/wiki/ESP32-S3-ETH
waveshare com/esp32-s3-eth.htm?sku=28771

cajoe kit

amazon de/dp/B0CH39N36H

J321 geiger tube
amazon de/dp/B0D1GVYJC6

Had a lot of problems getting the signal detection on vin right.
Gave up and now use the J1 jumper signal that normaly feeds the mini speaker … That gave me a clean signal in the esp32.

geiger.yaml

esphome:
  name: geiger
  friendly_name: Geigercounter

esp32:
  board: esp32-s3-devkitc-1    # did not find a better match
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  homeassistant_services: True
  homeassistant_states: True

ota:
  - platform: esphome
  

ethernet:
  type: W5500
  cs_pin: GPIO14
  interrupt_pin: GPIO10
  reset_pin: GPIO9
  clk_pin: GPIO13
  miso_pin: GPIO12
  mosi_pin: GPIO11
  
  # Optional manual IP
  manual_ip:
    static_ip: 192.168.1.48
    gateway: 192.168.1.1
    subnet: 255.255.255.0    


globals:
  - id: pulse_history
    type: int[60]
    restore_value: no
    initial_value: "{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}"

  - id: pulse_index
    type: int
    restore_value: no
    initial_value: "0"

  - id: pulse_sum
    type: int
    restore_value: no
    initial_value: "0"

switch:
  - platform: restart
    name: "geiger Restart"

sensor:
  - platform: uptime
    name: "geiger Uptime"
    update_interval: 60s

  - platform: pulse_counter
    id: geiger_cps
    internal: false
    pin:
      number: 21
      inverted: True
      mode:
        input: True
        pullup: False
        pulldown: False
    unit_of_measurement: 'CPS'
    name: 'Ionizing Radiation Power CPS'
    count_mode:
      rising_edge: DISABLE
      falling_edge: INCREMENT
    accuracy_decimals: 0
    update_interval: 1s
    filters:
      delta: 1
    on_raw_value:
      then:
        - lambda: |-
            x=round(x/60); // esphome calculating based on pulses per minute. round required to avoid problem when esphome calc value less than 60 pulses per minute (for example 59.7)
            id(pulse_sum) -= id(pulse_history)[id(pulse_index)]; // remove old value from overall sum
            id(pulse_history)[id(pulse_index)] = x; // 'x' is the raw pulse count
            id(pulse_sum) += x; // add new value to overall sum

            id(pulse_index)++; // change array index where next value will be stores
            if (id(pulse_index) >= 60) id(pulse_index) = 0; // Reset at 60
    on_value:
      then:
        component.update: geiger_cpm

  - platform: template
    id: geiger_cpm
    unit_of_measurement: 'CPM'
    name: 'Ionizing Radiation Power CPM'
    accuracy_decimals: 0
    update_interval: 1s
    state_class: measurement
    lambda: return id(pulse_sum);
    filters:
      delta: 1

  - platform: copy
    source_id: geiger_cpm
    id: ionizing_radiaton_power
    unit_of_measurement: 'µSv/h'
    name: 'Ionizing Radiation Power'
    state_class: measurement
    icon: mdi:radioactive
    accuracy_decimals: 5
    filters:
      - skip_initial: 15
      - sliding_window_moving_average: # 15 measurements moving average (MA5) here
          window_size: 15
          send_every: 1
      - multiply: 0.00332 # 0.0057 original value or 0.00332 for J305 by IoT-devices tube conversion factor of pulses into uSv/Hour

  - platform: integration
    name: "Total Ionizing Radiation Dose"
    unit_of_measurement: "uSv"
    sensor: ionizing_radiaton_power # link entity id to the pulse_counter values above
    icon: "mdi:radioactive"
    accuracy_decimals: 5
    time_unit: min # integrate values every next minute
    filters:
      # obtained dose. Converting from uSv/hour into uSv/minute: [uSv/h / 60] OR [uSv/h * 0.0166666667]. 
      # if my_dose_meter in CPM, then [0.0057 / 60 minutes] = 0.000095; so CPM * 0.000095 = dose every next minute, uSv.
      - multiply: 0.0166666667
    
    
binary_sensor:
  - platform: template
    device_class: safety
    name: "geiger Radiation Warning"
    # # This doesn't necessarily represent a "dangerous" count, but one that is abnormally high
    lambda: |-
      if (id(geiger_cpm).state > 100) {
        // High Count.
        return true;
      } else {
        // Normal Count.
        return false;
      }

text_sensor:
  - platform: version
    name: "geiger  ESPHome version"

time:
  - platform: homeassistant
    id: homeassistant_time

Result …

Some settings like cpm still needs calibration but it is somewhat accurate.

may it help some :wink:
Live long and Prosper

edit: as lurker didnt have rights to post links