Extending the life span of the PMS5003 sensor

Hmmm. It can use an I2C mode… I wonder if that would be better than UART

We actually support sleep mode with an undocumented command in the AirGradient Arduino library.

To put into sleep, try:

to wake up:

Hope that helps.

Maybe you can copy that code over to ESP home in case you do not use our Arduino library.

1 Like

That’s very helpful information @AirGradient. I would also be interested in implementing a sleep/wake up routine for my sensor but I’m using ESPHome instead of the Arduino library. Based on my understanding of your code on GitHub, the PMS also supports the functionality of the SET pin via the I2C bus, right?

Do you maybe have a datasheet that explains how to use SET and maybe also RESET via I2C so that I can contribute towards implementing this in ESPHome? I was looking for a datasheet earlier today but couldn’t find a proper one. It seems like the Chinese version of the Plantower website has much more information than the English version.

Yes datasheets are a bit difficult to get hold off, especially English ones.
I would suggest you check the sleep, wakeup code in our Arduino library and then just copy it over to ESP home.
We do not use the SET pin on our PCB. So besides TX, RC, VCC, G our PCB does not support the other PMS pins. However the sleep and wakeup is purely software driven so it should work.
As far as I know, the PMS5003 does not suppory i2c.

Oops, I just realized that I mixed up I2C and UART here. In any way, I will see if I can extend the ESPHome PMS component to support sleep/wake up too.

I’ve work Jeff Geerling project and rework it for VS Code with PlatformIO.

I took your suggestion and I’m waking up the sensor every 120s for 30s, do the reading and then let’s it go back to sleep.

I’ve been running this for more than 24h and the values I’m getting are pretty good.
I chose 30s because the documentation on @airgradient lib was suggesting to wait 30s after waking up the sensor.

1 Like

For anyone using ESPHome, here is the equivalent code that’s working for me that does not require an additional pin:

  - interval: 150s
    # Two-minute interval to extend the life span of the PMS5003 sensor
      - switch.turn_on: pms_switch
      - delay: 30s
      - switch.turn_off: pms_switch

# Source: https://github.com/airgradienthq/arduino/blob/master/AirGradient.cpp#L123
  - platform: template
    name: "PMS5003"
    id: pms_switch
    optimistic: true
      - uart.write:
          id: pms5003_uart
          data: [0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74]
      - uart.write:
          id: pms5003_uart
          data: [0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73]

There is a warning in the log when sleep is called:

[W][pmsx003:108]: PMSX003 length 4 doesn't match. Are you using the correct PMSX003 type?

(maybe that 0x00 at pos 4 should be 0x01 like turn on? not sure)

But it doesn’t seem to affect anything, I can hear the fan cycling on and off and watch the readings stop and go in the logs.

Full example, forked from this one is here


Very elegant solution to use ESPHome UART commands. I thought about adding the functionality to the ESPHome code base but did not get to it so far.

Regarding your question: According to the PMS datasheet at [1], the 0x01 on position four is the actual sleep/wake command and the difference in the last bit is a checksum. My assumption without having looked into the ESPHome code base so far is that currently the PMS component always expects a 32 byte answer because that is the usual communication pattern for measurement data. I’m not sure what the sensor responds after a sleep/wake up but it only seems to be 4 bytes long.

[1] https://www.aqmd.gov/docs/default-source/aq-spec/resources-page/plantower-pms5003-manual_v2-3.pdf

1 Like

I took a look into the ESPHome code base and confirmed my assumption. Here are the relevant lines of code: esphome/pmsx003.cpp at dev · esphome/esphome · GitHub

I don’t know yet what exactly the sensor sends in these four bytes and if the response differs between sleep and wake up but it should not be hard to create a PR that prevents this constant warning.

1 Like

I ran a small test with the UART debug config this evening.

  - rx_pin: D5
    tx_pin: D6
    baud_rate: 9600
    id: pms5003_uart
        delimiter: "\n"
        bytes: 32

The relevant output lines consistently show this:

[22:13:23][D][uart_debug:114]: >>> 42:4D:E4:00:00:01:73
[22:13:23][W][pmsx003:108]: PMSX003 length 4 doesn't match. Are you using the correct PMSX003 type?
[22:13:23][D][uart_debug:114]: <<< 42:4D:00:04:E4:00:01:77

So the four payload bytes coming back from the sensor are 0x00 0x04 0xE4 0x00. Looking at the PMS datasheet, I’m not sure what this is supposed to mean though.

I thought about this once more and my best guess is as follows:
0x42 0x4D → standard header
0x00 0x04 → length of following bytes
0xE4 0x00 → repetition of the initial command
0x01 0x77 → checksum bytes

So I guess that the PMS simply confirms any of these “management” commands like sleep/wake or active/passive by replying with the command code.

1 Like

Just wondering, will sleeping/waking the PMS5003 sensor every 30 seconds be integrated into the Airgradient Arduino code?


1 Like

@lbhm - Did you ever get a chance to submit a PR to enhance the PMS5003 ESPHome support with software based sleep? I do not know how to so if you have not, I was going to open an issue in Github adding the information you kindly shared in hopes that someone will submit a PR.

@aruffell I did not follow up on that yet since the workaround by @k-d worked fine for me. I haven’t actively tinkered with my AirGradient in the last months so I’d first have to read up on the topic again.

@lbhm - I hope you do not mind… I created a feature request to enable this in ESPHome. I linked back to this thread.

@aruffell As far as I understand. ESPhome already puts the device to sleep when you have a bigger interval than 0. Mine is set to 3min so it wakes up to do a measurment. Its in the pmsx003 documentation.

I did not see anything about stopping the fan while sleeping in the documentation so I used the Set pin where I had control over the circuit and the sw method on the AirGradient setup. I will test it out to see if mine stops without having to do so specifically. Thanks for letting me know!

Building on @rhermsen 's work here PM2.5 value often -1, I have added it to mine with the following code. My recommendation is you save your existing code as a new file, open it, look for the sections below and edit. Note that my settings enable the device for 30 seconds every one minute (3.5 years lifespan seemed short to me but 18 years longer than needed, as estimated in the opening post of this thread).

//following line remarked out to support pm25 sensor sleep
//const int pm25Interval = 5000;
unsigned long previousPm25 = 0;
int pm25 = 0;
//following 3 lines added to support pm25 sensor sleep
const int pm25Interval = 30000;
const int pm25SleepIntvl = 90000;
boolean pm25sleep = false;

//following void added to support pm25 sensor sleep
void sleepPm25()
    if (currentMillis - previousPm25 >= pm25SleepIntvl && pm25sleep) {
      pm25sleep = false;

void updatePm25()
//following 2 lines remarked out to support pm25 sensor sleep
//    if (currentMillis - previousPm25 >= pm25Interval) {
//      previousPm25 += pm25Interval;
    if (currentMillis - previousPm25 >= pm25SleepIntvl + pm25Interval) {
      previousPm25 = currentMillis;
      pm25 = ag.getPM2_Raw();
//following 2 lines added to support pm25 sensor sleep
      pm25sleep = true;

Thanks for finding and using my changes.

I increased the time the sensor is enabled to 45 seconds. That gave a more comparable result to my two other PM2.5 meters, similar to before introducing the life span changes.

Btw, I did notice that turning on the fan gives some seconds of higher and unstable fan-speed. Not sure if this might impact the life-span of the fan (while trying to increase the life-span of the laser).

Left my changes, on top of Themi’s, here: GitHub - rhermsen/AirGradientUpgrades: Various software upgrades for the AirGradient Pro 3.7

1 Like

I just looked up the sensor, sells for $40 shipped on Amazon in the US.
At that price - while not totally cheap, that’s about $10 a year. Probably most people should just do what they’d do anyway and leave as is. In 4 years we might have better and/or cheaper sensors and AirGradient devices available.

We have many PMS5003 still working after four years without issues. If you are not living in a very polluted environment they will probably last longer than 3 years.

1 Like