ESPhome Automation Particulate Matter Sensor update_interval

Hi I am upgrading my Ikea PM1006 Particulate Matter Sensor.

I connected it so i directly read the values. Following the manual it does a update every 20 seconds. The sensor also has a seperated FAN. I want to turn on this fan when the when it is updating the value. If i read correct, i should use an automation for this. But i can’t seem to figure out how to do this. Who can help. Below the components in my config which i would like to like to eachother.

switch:
  - platform: gpio
    pin: GPIO25
    name: "Fan"


uart:
  rx_pin: D2
  tx_pin: D1
  baud_rate: 9600

sensor:
  - platform: pm1006
    pm_2_5:
      name: "Particulate Matter 2.5µm Concentration"
    update_interval: 20s

Manual pm1006

I dont see anything about it having a fan in the manual. You’re a liar!!!
Lol I’m Jk. Is it a 2 wire fan or 3 wires? I was looking for it in the manual to see if its 5v or can use 3.3v, how much current it uses and are you sure its not PWM too? These are meant to be used with esp/microcontroller’s right? It should be ok then.

Is the goal to turn the fan on and cool it right before a reading or is it to cool it after a reading?

Do you need a logic level converter too? Looks like the signal Out is 4.5v.

thanks for your reply.

i use somewhat this drawing to power the fan (but without the resitor and diode)

the pm2.5 meter and the fan are separated and was contolled from the Ikea MCU. But i want to replace the mcu with an ESP 32 D1.


With the ikea MCU the fan only turned on when it was taking samples. I would like to do the same with the ESP32. Hope it makes sense.

PS: Both work on 5 volt

So, you dont have a current limiting resistor on the base of the transistor? Thats bad bad news, youll keep burning it out or worse, damage your esp board. The diode is something you need too.

thanks, i will add them. Is it simple to explain why ?

Also still looking for an way to turn on the fan when the pm2.5 is sampling evenry 20 seconds

Ok so, theres a few ways you could do this. This is how i would do it. First, set up Time. You can use HA as your time source.
https://esphome.io/components/time/homeassistant.html?highlight=time

Then just look at the examples they give you for how to use Time.
Screenshot from 2024-01-28 12-18-37

time:
  - platform: homeassistant
    id: time_source
    on_time:
      # Every 15 Seconds
      - seconds: /15
        minutes: 
        then:
          - switch.turn_on: Fan
          - delay: 5s
          - component.update: Particulate Matter 2.5µm Concentration
          - switch.turn_off: Fan

You’ll also want to remove the update_interval: 20s from the pm1006 sensor.

Yes, the transistor for example can only handle a very small amount of current. The current limiting resistor does just that, it only allows X amount of current so you don’t burn out the transistor.

The diode or in this case, the flyback diode is used to prevent sudden voltage spikes from inductive loads when they are turned off. When you turn that fan off, it’s still spinning and can cause a voltage spike that will damage electronics.

The “component_update” only works for some components so, if it gives you a compile error let me know and we can go another route.

1 Like

seeing how the data voltage is 4.5v you will need a logic shifter too. This just steps up/down voltage back and forth. 4.5v will come from the sensor and into the logic shifter which steps it down to a safe and usable 3.3v. UART data being sent to the sensor will go out the esp32 gpio at 3.3v, the logic shifter will bump it up to 5v and send it to the sensor.

https://www.amazon.com/WWZMDiB-Channels-Converter-Bi-Directional-3-3V-5V/dp/B0BD8JNXWB/ref=sr_1_1_sspa?crid=2K78FPY5TWE1S&keywords=logic+level+shifter&qid=1706463693&sprefix=logic+level%2Caps%2C125&sr=8-1-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1

1 Like

Thanks so much!! for all your replies. they all make sense to me and totaly understand why i should add the resistor and diode. The diode i didn’t had laying around anymore and will order one. The resistor is in, and with your example for the code i saw that i already had something like that in place so only had to add the fan and component update in there and it is working! Cool, this topic can be closed very quickly. Many thanks!

My current ikea vindriktning ESPhome code (still in development):

switch:
  - platform: gpio
    pin: GPIO25
    name: "Fan"
    id: Fan
light:
  - platform: partition
    name: "Partition Light 1"
    segments:
      - id: light1
        from: 0
        to: 1
  - platform: partition
    name: "Partition Light 2"
    segments:
      - id: light1
        from: 2
        to: 3
  - platform: partition
    name: "Partition Light 3"
    segments:
      - id: light1
        from: 4
        to: 5
  - platform: partition
    name: "Partition Light 4"
    segments:
      - id: light1
        from: 6
        to: 7

  - platform: neopixelbus
    id: light1
    type: GRB
    variant: WS2811
    pin: GPIO27
    num_leds: 8
    name: "Status Light"
    effects:
    - random:
    - pulse:
    - strobe:
    - flicker:
    - addressable_rainbow:
    - addressable_color_wipe:
    - addressable_scan:
    - addressable_twinkle:
    - addressable_random_twinkle:
    - addressable_fireworks:

font:
  - file: 'arial.ttf'
    id: font1
    size: 16
uart:
  - id: uart_1
    rx_pin: GPIO17
    tx_pin: GPIO16
    baud_rate: 256000
  - id: uart_2
    rx_pin: GPIO03
    tx_pin: GPIO01
    baud_rate: 9600

i2c:
  sda: GPIO21
  scl: GPIO22
  scan: true
  id: bus_a


ld2410:
  uart_id: uart_1

binary_sensor:
  - platform: ld2410
    has_target:
      name: Presence
    has_moving_target:
      name: Moving Target
      id: moving
    has_still_target:
      name: Still Target
    out_pin_presence_status:
      name: out pin presence status
  - platform: homeassistant
    entity_id: switch.ikeafan
    id: enable_automation

sensor:
  - platform: pm1006
    uart_id: uart_2
    id: pm25
    pm_2_5:
      name: "Particulate Matter 2.5µm Concentration"
      on_value:
        - if:
            condition:
              - binary_sensor.is_off: enable_automation
            then:
              - homeassistant.service:
                  service: number.set_value
                  data:
                    entity_id: $ap_id
                    value: !lambda |-
                      auto range = (x - $pms_low) / ($pms_high - $pms_low) * $af_speeds;
                      auto value = (x < $pms_low) ? 0 : (range > $af_speeds) ? $af_speeds : range;
                      return ceil(value);
            else:
              # If the "$auto_enable" binary sensor is on, set the fan speed to 0
              - homeassistant.service:
                  service: number.set_value
                  data:
                    entity_id: $ap_id
                    value: '0'

  - platform: bme280
    temperature:
      name: "BME280 Temperature"
      oversampling: 16x
      id: temperature
    pressure:
      name: "BME280 Pressure"
    humidity:
      name: "BME280 Humidity"
      oversampling: 16x
      id: humidity
    address: 0x76
    update_interval: 60s

  - platform: ccs811
    eco2:
      name: "Bedroom eCO2 Value"
    tvoc:
      name: "Bedroom Total Volatile Organic Compound"
    address: 0x5A
    update_interval: 60s
    baseline: 0x4481
    temperature: temperature
    humidity: humidity
    
  - platform: ld2410
    light:
      name: light
    moving_distance:
      name : Moving Distance
      id: distance
    still_distance:
      name: Still Distance
    moving_energy:
      name: Move Energy
    still_energy:
      name: Still Energy
    detection_distance:
      name: Detection Distance

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    id: my_display
    address: 0x3C
    update_interval: 1s
    pages:
      - id: page1    
        lambda: |-
          it.print(0, 0, id(font1), "Human Sensor");
          it.printf(0, 20, id(font1), "Afstand: %.1f cm", id(distance).state);
          it.printf(0, 40, id(font1), "Beweging: %s", id(moving).state ? "Ja" : "Nee");
      - id: page2    
        lambda: |-
          it.print(0, 0, id(font1), "Temp/Hum");
          it.printf(0, 20, id(font1), "Temp: %.1f°", id(distance).state);
          it.printf(0, 40, id(font1), "Hum: %.1f %%", id(distance).state);

interval:
  - interval: 15s
    then:        
      - display.page.show_next: my_display
      - component.update: my_display
      - switch.turn_on: Fan
      - delay: 5s
      - component.update: pm25
      - switch.turn_off: Fan
1 Like

Nice! This sensor has me curious. Can you let me know how it is and if it’s worth buying one for myself?

Sorry, saw i did not replied yet. The project is still in the make. Sensors are working but are not accurate, so that needs some work. When ready will post an update. As of now it takes a lot of time and not sure it is worth it. It is a fun project and learning a lot on how to advanced use esphome