PMSA003 ESPhome sensor not working

I can’t seem to get my PMSA003 sensor on my ESP32 to work for HA. I also attached a BME680, which is working flawlessly. But the PMSA003 sensor does not seem to be outputting any data. I can see the little fan spin up, but no data is being sent to home assistant.

esphome:
  name: pmsa003-bme680
  friendly_name: PMSA003 BME680 

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

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

ota:
  password: "Censored"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Pmsa003-Bme680 Fallback Hotspot"
    password: "Censored"

captive_portal:

# Configure I2C for BME680
i2c:
  sda: 21
  scl: 22
  scan: True

# UART configuration for PMSA003
uart:
  rx_pin: GPIO16
  baud_rate: 9600
  
# BME680 Sensor configuration
sensor:
  - platform: bme680
    temperature:
      name: "BME680 Temperature"
      oversampling: 16x
    pressure:
      name: "BME680 Pressure"
    humidity:
      name: "BME680 Humidity"
    gas_resistance:
      name: "BME680 Gas Resistance"
    address: 0x77
    update_interval: 60s



  # PMSA003 Sensor configuration
  - platform: pmsx003
    type: PMSX003
    pm_1_0:
      name: "PM <1.0µm"
    pm_2_5:
      name: "PM <2.5µm"
    pm_10_0:
      name: "PM <10.0µm"

Current wiring is:

PMSA003:
VCC -> +5V
GND -> GND
TXD: Pin 16

BME680:
VCC -> +3.3v
GND -> GND
sda -> 21
scl -> 22

I have tried to wire up “SET” to +3.3 and GND, but no luck.

Anything in the ESPHome logs?

Did you try the RX wire from the PMS too in case they are switched?

“SEND/TX pin (may also be called the RX pin, depending on the model) of the PMS.”

Nothing in the logs aside from it being identified. I know other users had issues with the high/low states of the “Set” and “Reset” pins. Having one of them in the wrong state essentially puts the PMSA003 sensor in sleep mode despite being connected.

I tried both TX and RX from PMSA003 to UART RX on the ESP32.

I also tried to ground “SET” and “RESET” while having TX or RX pins connected. I have also tried both on +3.3V.

Here is a link to the product I bought. There is one review that says the little connection board does not match the actual pinout on the device.

I also attempted to hook up the SET and RESET pins to a GPIO and added this code to ESPhome without success.

switch:
  - platform: gpio
    pin: GPIO18  
    name: "PMSA003 Set Pin"
  - platform: gpio
    pin: GPIO19  
    name: "PMSA003 Reset Pin"

Any advice would be appreciated

Also attempted to setup using I2C protocol with both pins. Logs are coming back as:

[1085][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263
[E][component:113]: Component pmsa003i.sensor was marked as failed.
[I][i2c.arduino:069]: Results from i2c bus scan:
[I][i2c.arduino:071]: Found no i2c devices!

Definitely seems like the UART version.

Maybe this helps. Although maybe you already tried it all. Possibly it is the person who left the Ali Express review.

https://www.reddit.com/r/Esphome/comments/17561va/pmsa003_particulate_sensor_not_working/

I kept it basic and used UART RX pin on the ESP, +5V to VCC, and GND to GND. No other connections among the two.

I tried every pin on the PMSA003 and have had no luck. The only other scenario is that two of the pins are missing on the connector included on the tiny board. One of those missing pins could potentially be the TX for the PMSA003 sensor. I don’t have anything to connect to the small pins on the PMSA003. Why they decided to omit the two is beyond me.

But I am suspecting this massive flaw is the reason I cannot receive any data from the PMSA003 sensor.

Did you try wiring it as per the Reddit post the author says is working?

I.e from what I could see they hooked up tx to tx and rx to rx.

Yep, no luck

I know, I am a bit late to the party here, but maybe someone is still interested… I wrote that review you are referring to.
One of the main differences was that on my board, the black pin header was not on the same side as the white connector. Unfortunately, I did not take any pictures myself. It looks similar to this picture but the black pin header is below the board.
image
Since the pin header is not coded, the board can be inserted in two directions. I am using it like this:
image
I did not write down the pin numbers of the black connector, but I hope the colors on the cable are the same:

Pin PMA Connector Signal Wemos
1 - violet Vcc 5V
2 - organge GND G
3 - white TX RX - GPIO 3
4 - blue NC
5 - green Set D7 - GPIO 13
All others NC

The ESPHome yaml looks like this:

esphome:
  name: air-quality-sensor
  friendly_name: Air Quality Sensor

esp8266:
  board: d1_mini

# Enable logging
logger:
    baud_rate: 0

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

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Air-Quality-Sensor"
    password: "yyyyyyyyyy"


i2c:
  sda: GPIO4 # D2
  scl: GPIO5 # D1

captive_portal:

mqtt:
  broker: 192.168.1.xxx
  #discovery: false
  topic_prefix: sensor/air-quality

uart:
  tx_pin: GPIO1 # TX
  rx_pin: GPIO3 # RX
  baud_rate: 9600

# The 3-second debounce only publishes the average (otherwise published
# every second) once the per-second readings stop (i.e. the measurement 
# period ends). This makes sure the output average doesn't slip back a
# reading every measurement period.
sensor:
  # PMA003
  - platform: pmsx003
    type: PMSX003
    pm_1_0:
      name: "Particulate Matter <1.0µm Concentration"
      id: pms_10
      accuracy_decimals: 3
      filters:
      - lambda: |-
          if (id(warmed_up).state) {
            return x;
          } else {
            return {};
          }
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
          send_first_at: 1
      - debounce: 3s
    pm_2_5:
      name: "Particulate Matter <2.5µm Concentration"
      id: pms_25
      accuracy_decimals: 3
      filters:
      - lambda: |-
          if (id(warmed_up).state) {
            return x;
          } else {
            return {};
          }
      - sliding_window_moving_average:
          window_size: 10
          send_every: 1
          send_first_at: 1
      - debounce: 3s
    pm_10_0:
      name: "Particulate Matter <10.0µm Concentration"
      id: pms_100
      accuracy_decimals: 3
      filters:
      - lambda: |-
          if (id(warmed_up).state) {
            return x;
          } else {
            return {};
          }
      - sliding_window_moving_average:
          window_size: 10
          send_first_at: 1
          send_every: 1
      - debounce: 3s
  # AHT20   
  - platform: aht10
    variant: AHT20
    temperature:
      name: "AHT20 Temperature"
      id: aht20_temperature
    humidity:
      name: "AHT20 Humidity"
      id: aht20_humidity
    update_interval: 180s

binary_sensor:

  - platform: template
    name: "Warmed Up"
    id: warmed_up
    filters:
      - delayed_on: 30s
    on_press:
      - delay: 10s
      - switch.turn_off: measuring

switch:

  - platform: gpio
    name: "Measuring"
    id: measuring
    pin:
      number: GPIO13 # D7
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - binary_sensor.template.publish:
          id: warmed_up
          state: ON
    on_turn_off:
      - binary_sensor.template.publish:
          id: warmed_up
          state: OFF

  - platform: restart
    name: "Restart"

interval:

  - interval: 300s
    then:
      #- wait_until:
      #    condition:
      #      mqtt.connected: # Can use api.connected if using HA API instead
      - switch.turn_on: measuring # Will turn itself off later

I did not create the code myself. I copied it from somewhere and adapted it.
First I only got zero values. Then I noticed that it takes a few hours before the readings start to make sense.

Unfortunately there is no calibrated station in my area so I don’t know if the readings are actually close to reality.