Air Sensors Unit

I have an AirGradient unit for monitoring the air quality in my home, but wanted something that would hang off a wall outlet. I discovered the SparkFun qwiic boards and went a bit overboard buying the most accurate temperature (TMP117), humidity (SHTC3), CO2 (SCD41) and barometric pressure (BMP581) sensors SparkFun has in this format.

Originally, the plan was to use a pi pico (or zero), but then I came across the Pocket ESP32-C6 and it fit in with the sensor boards too well to pass up.

Since I’d prefer not to burn down my house, I’m using an off-the-shelf Anker USB-C charger without any modification.

To make sure it doesn’t measure stale air, and to keep the heat from the power adapter and esp32 from influencing the sensors, I threw in a PWM-controlled 5V fan (yes, I have a Noctua problem). This runs at a silent speed, and even that is probably overkill. Unfortunately there aren’t qwiic fans (yet? :wink: ), so I did have to do some less pretty wiring to connect the fan to the esp32.

The enclosure was designed in Fusion and 3d-printed. I am still new to both. If you haven’t gotten a 3d printer, just do it. It really opens up a lot of possibilities.

Here’s what the internals look like:

I’m using esphome to create the firmware. There’s a substantially larger amount of work I need to get to for recording and displaying the data from these sensors. That’s a whole other set of projects.

I wanted to throw this up in case it inspires someone else to think about building their own smart sensors. The esp32 boards and esphome make it a lot easier than you probably think it is. Let me know if you have any questions. Besides how much it cost. It cost too much. :laughing:

P.S. SparkFun: are there going to be Qwiic versions of the new Sensirion SEN6x series sensors? They appear to be 3.3V native, so no longer need to step up to 5V!

2 Likes

P.P.S. I know bots are a problem and all, but limiting me to only having 2 links and one inline image was not a great roadblock to get thrown up after I had carefully created good links and attached more images.

Here’s what it looks like with the cover on and plugged in:

Cool!

Yea, the rules for first-time posters are stringent…there are many attempts to abuse our system over here lol…most first posts aren’t this detailed

I’d say it’s a 80% chance of for the Sensirons, it’s always a moving target of balancing product roadmaps…but classically we have released breakout boards with their releases, I’d expect we will again :slight_smile: https://www.sparkfun.com/catalogsearch/result/?q=sensiron

1 Like

Here’s my esphome config

esphome:
  name: sensor
  on_boot:
    - then:
      - output.set_level:
          id: fan_pwm
          level: 30 %

esp32:
  board: sparkfun_qwiic_pocket_esp32c6
  framework:
    type: esp-idf

logger:
  level: INFO
  logs:
    esp-idf: WARN

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  use_address: sensor
  reboot_timeout: 0s

web_server:
  port: 80
  version: 3

api:
  reboot_timeout: 0s

ota:
  - platform: esphome
    password: !secret ota_password

time:
  - id: wall_clock
    platform: sntp
    timezone: Etc/UTC

i2c:
  sda: GPIO6
  scl: GPIO7

output:
  - platform: ledc
    pin: GPIO3
    frequency: 25000 Hz
    id: fan_pwm

text_sensor:
  - platform: wifi_info
    ip_address:
      name: wifi_ip
      icon: mdi:ip
  - platform: template
    name: clock
    icon: mdi:clock-time-nine-outline
    entity_category: diagnostic
    lambda: return id(wall_clock).now().strftime("%Y-%m-%d %H:%M:%S");
    update_interval: 5s

sensor:
  - platform: wifi_signal
    name: wifi_signal
    icon: mdi:signal
    entity_category: diagnostic
    update_interval: 5s
  - platform: pulse_counter
    pin: GPIO2
    name: fan_rpm
    entity_category: diagnostic
    update_interval: 5s
    icon: mdi:fan
    filters:
      - multiply: 0.5
    unit_of_measurement: RPM
  - platform: uptime
    name: uptime
    icon: mdi:timer
    entity_category: diagnostic
    update_interval: 5s
    type: seconds
  - platform: tmp117
    name: temperature
    icon: mdi:thermometer
    update_interval: 5s
  - platform: shtcx
    humidity:
      name: humidity
      icon: mdi:water-percent
    update_interval: 5s
  - platform: scd4x
    id: scd41
    co2:
      name: co2
      icon: mdi:molecule-co2
    update_interval: 5s
    automatic_self_calibration: false
  - platform: bmp581
    address: 0x47
    pressure:
      name: pressure
      icon: mdi:gauge
      oversampling: 4x
      on_value:
        then:
          - lambda: |-
              float hpa = x / 100.0;
              ESP_LOGD("bmp581_pressure_compensation", "Pa %f -> hpa %f", x, hpa);
              id(scd41)->set_ambient_pressure_compensation(x / 100.0);
    update_interval: 5s

@TS-Russell : this reminded me that esphome’s default address for the BMP581 is 0x46, but the sparkfun board defaults it to 0x47. I don’t know who is in the “right” here, or if this is even uncommon to run into, but it was the only one of my 4 sensors where there wasn’t agreement in defaults.