Dust Sensor - PMS 5003/6003/7003

Hi, the code at post #21, which is here: Dust Sensor - PMS 5003/6003/7003
is good for me. It works! Did you try it?

Thanks for your reply.
I’m sorry.
Would it be possible for these questions:

  1. For PMS 5003, I know it works that you say; but, In addition arduino,are there other?
  2. Did you try for PMS5003ST with ST? Or stm32fxxx?

Hi all.

I just received 2x PMS7003 - trying to get one hooked up to my Electron.

I have used a header to connect the PMS7003 to my breadboard, but now struggling to work out what/where I should connect to my Electron.

Here is the pin details from data sheet from PMS5003 (can’t find 7003), I’m hoping that it has the same connections.

I understand Pins 1, 2, 4, 5. But where should the others go?

A couple of other quick questions:

  • @MartyMacGyver - using your code - does one need to define pins and/or IC2 address anywhere?
  • The data sheet seems to suggest power is 5V. Is it an issue to power by 3.5V through Photon?

As you can see I’m new to electronics :smile:



There’s a pretty decent datasheet here (unlike the one I started with, this one even has a handy wiring diagram):

(Yes, it’s in Chinese but you can put the URL through Google Translate to convert the whole doc.)

I haven’t tried using 3.3V for VCC (since I can source the 5V from the Photon for the purpose of VCC< I do). I wouldn’t expect 3.3V to be enough though.

The pins aren’t in the same configuration as the 5003. Refer to the datasheet for the pin ordering, but translated:

PIN1 VCC Power is 5V
PIN2 VCC Power is 5V
PIN3 GND Power supply negative
PIN4 GND Power supply negative
PIN5 RESET Module reset signal / TTL level @ 3.3V, low reset
PIN7 RX Serial receive pin / TTL level @ 3.3V
PIN9 TX Serial transmission pin / TTL level @ 3.3V
PIN10 SET Set the pin to TTL level @ 3.3V, high or floating
Normal working state, low for the sleep state

This device is serial-only (no I2C), so when you connect it up, you use the serial pins on your Photon/Electron. Float or pull SET high to let the device run all the time, and pull RESET high unless you want to directly reset it (which I’ve yet to need to do).

5V power, ground, and serial TXD/RXD (which are at 3.3V levels per the datasheet) should be all you really need.

(Since it’s an Electron you might want to make your own code - mine would use a lot of data.)

Thanks for your guidance. Here is what I’ve done so far, but not working… :frowning: Any help diagnosing would be much appreciated:

So on the connector that came with my PMS7003, the connections are a bit different to the data sheet. Goes from 10 pins down to 8 through the connector. See below:

I’ve connected it up to my breadboard, Electron as follows. Pretend PMS7003 is connected to the generic header in diagram.

In the Fritzing above, used a header where pins 1-8 align with pins 1-8 on the PMS7003 connector (as per first photo).

I’ve then used @MartyMacGyver’s code - adding the following to try and pull SET high:

pinMode(D3, OUTPUT);
digitalWrite(D3, HIGH);

I suspect this is completely wrong, and have no idea how to pull RESET high. Tried doing a quick search but couldn’t find much on how to do this. Should pulling have been done through hardware?

Also, is there any code missing from @MartyMacGyver’s repository? I would have expected to see normal stuff like defining pins etc - like I’ve tried to do above? Am I missing something?

When viewing serial output, I’m just getting:

-- Initializing...
-- Reading PMS7003

And nothing else.



That’s my repo - it should be easier than all that.

Looks like the breakout (oh how I wish that had come with mine!) simply omits/combines the two VCC and the two Gnd pins into one each.

You likely need to only wire four things: VCC (5V), Gnd, TXD and RXD. That’s all. I suspect Set and Reset are already pulled to their appropriate states (Reset should be pulled high internally, and I think Set is internally pulled high too).

Either way, the wiring looks OK to me in terms of pulling things up to 3.3V, though you’re going to need to do the same thing for D6 (reset) you’re doing for D3 (set).

That said, I’d unplug those two for a moment and let the resistors do the work.

What’s wrong here is that I don’t see VCC for the PMS7003 going to +5V… I see it going to 3.3V. While that’s fine for the pull-ups, the VCC must be 5V as far as I know (otherwise you’ll affect the fan speed, and that’s part of the measurement pathway - not to mention it might not even power up).

On a Photon, when powered from USB, VIN will supply +5V.

On the Electron I think the only option is VUSB (and that means having a USB supply… I don’t think the LiPo won’t suffice). Only wire +5V to VCC… never the other pins or pull-ups on the PMS7003!

EDIT: Once you have the power thing sorted, you might have to reverse the TX and RX connections. I don’t recall which is which but try what you have first.

EDIT2: and by the way… where did you get these? eBay, AliExpress, somewhere else? Would be good to know. :smile:

Thanks - you’re right the fan wasn’t working at all under 3.3V - moving to 5V got the fan going for a while, but seems I killed it somehow - it’s not starting up at all now when powering it, perhaps I shorted it or something. I’ll try my second PMS7003.

From AliExpress. Cheaper than eBay and included the connector.

Thanks again. I’ll post my progress for other’s reference once I get it going.


If SET is low that would turn the fan off too:

When the sleep function is applied, be aware that the fan stops working while the fan is inactive and requires at least 30 Sec settling time, so in order to obtain accurate data, the sleep sensor working time after wake-up should not be < [?] 30 seconds.

Try giving the device VCC and GND only, and leave all the other wires completely unconnected. The fan ought to run.

If not, pull the SET line up to 3.3v (I don’t think that’s necessary but it’s worth a try too).

If that doesn’t work… maybe it really is dead. I have a hard time seeing how any of this would’ve killed it unless its power lines were reversed or something though.

As for AliExpress, did you get it from HS Electronics?

In general what was your experience like ordering from AliExpress? Did they require copies of your identification, etc.? (Long story short, AE asked for a LOT of rather strange info when I tried to order something simple a while back.)

Gave it another go. I had the connector/breakout supplied attached the wrong way around to the PMS7003 :confused:

Anway’s it is now working! Receiving frames of data through serial as per your code, Marty.

Any tips on how I can quickly convert these frames to something human readable to sense check readings?

As for AliExpress, did you get it from HS Electronics?

In general what was your experience like ordering from AliExpress? Did they require copies of your identification, etc.? (Long story short, AE asked for a LOT of rather strange info when I tried to order something simple a while back.)

Can’t recall the vendor, and info isn’t in the email. I didn’t need to provide much info - just postal address, payment info. I didn’t register an AliExpress account - I just went through checkout process as a guest.

Hi to all,

This is my first post here.
I’m starting to test the PMS7003 sensor with an Arduino. I have tried with at least 3 different softwares, and with all of them I’m getting consistent values, however looking at the readings and comparing them to the readings obtained by other Sharp dust sensors (just pm2.5), the readings from the PMS7003 appeared as multiplied by ten. Is this possible?

Here is an example from the PMS7003

PM1.0cf: 369 ug/m3
PM2.5cf: 557 ug/m3
PM1 0cf: 601 ug/m3
PM1.0am: 245 ug/m3
PM2.5am: 371 ug/m3
PM1 0am: 400 ug/m3

From the Sharp sensor PM2.5 reading is now 39.8 ug/m3

If I increase the particles in the air by burning some incense near the sensors, both increase the readings, but the PMS7003 readings always seems 10 times the value of the Sharp sensor. Does anyone have already noted this, or I’m doing anything wrong.

Which Sharp sensors are you using ? If it is a reference instrument then it would be more believable.
The PM2.5 numbers you measured with the 7003 are really high. If you were regularly breathing this air you would be in big trouble. So without knowing anything more like seeing your code, it is possible that your 7003 readings are off by a factor of 10.

OTOH if you are in Beijing or Delhi the readings are probably ok!

it is best to check with aqicn.org - where is the nearest station that reports PM 2.5/pm10 readings and compare with it.
40 ug/m3 is generally clear air… you shouldn’t smell anything in it.
400 ug/m3 usually smells quite a lot on smoke, fire… you shouldn’t also be able to see more than 100m around you

Thank you guys.
All is working now, and the readings from my PMS7003 usually are inline with the values from the nearest (40Km away) aquicn.org station.
Nice sensor.

Thank your code share, current i sent code with PMS5003, but get PM2.5 PM1.0 and PM10 all value is 0.Any suggest?

Is there any reason you couldn’t split the data lines from a sensor (any of the PMS sensors) to feed two devices (an electron and another custom board)?

I have a custom device that already has a PMS7003 in it but I want to datalog the PM values (something the custom device cannot do).

An alternate idea I had was to feed the sensor serial lines to the Photon and then repeat them back to the custom device.

Thoughts? Improvements to my initial ideas?

Hey Neo any chance you worked out the reading zero problem? I’ve got the same issue here

HI ilak2k~ I run PMS5003 with the code you shared. However, I always get “zero” outcome.
After I tried to debug, I found here: if( receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))
because the equation never achieve, so it doesn’t make the flag=1.
Is there any solution about this problem?

i have dust sensor SDS011 + USB adapter
I connect the sensor to raspberry pi, basic to read a sensor I use command:

od --endian=big -x -N10 < /dev/ttyUSB0

so it is giving me for example:
0000000 aac0 8c00 9400 bcf9 d5ab

every packet of data begins “aac0” and rest of the data are converted to useful values (in bash script), basically everything work ok (for graphic representation of data I use RRDtool). But I want compare data from SDS011 with PMS7003. I don’t have any USB adapter so I connect PMS703 to raspberry pi pins.
In PMS7003 datasheet I see that start of the packet of data should be “424d”. First I tryed this command:

sudo od –endian=big -x -N10 < /dev/serial0

but this give me that kind of data:
3500 8200 0a54 008c 000a (first try)
8100 9f00 0a78 0094 000a (second try)
2900 6400 2900 6400 2900 (third try)
I don’t see beginning the data packet “424d”

I tried Python script:

import serial
from time import gmtime, strftime
port = serial.Serial("/dev/serial0", baudrate=9600, timeout=1.5)
data = port.read(32);
PM01 = str(ord(data[5])*256+ord(data[6]))
PM25 = str(ord(data[7])*256+ord(data[8]))
PM10 = str(ord(data[9])*256+ord(data[10]))

but this also give me strange no real value. Why data packet never start from “424d”?

I ordered a PMS7003 and already wrote some software for it.

The approach in the code is that it’s purely a state machine for interpreting the incoming serial bytes. So it will automatically sync to the start of a frame with measurement data, even if you start receiving data halfway inside a frame. It should be buffer-overflow-proof. The parsing code is also stand-alone, with no Arduino dependencies. This makes it easier to test.

My code can be found at: https://github.com/bertrik/pms7003 in modules pms7003.cpp/.h
I haven’t received the module yet, so I haven’t been able to test it with actual hardware, but I did write some unit tests.


Hi folk, I use of Plantower pms 3003 with Teensy 3.2. It’s my code: https://github.com/AndriyHz/Teensy-3.2-and-Thingspeak/blob/master/PM2_with_S8_BME280_WiFi-For-Teensy3.ino
But I see that I receive sometimes incorrect data. For example,
PM2.5 — 50
PM10 — 65
PM2.5 — 50
PM10 — 65

PM2.5 — 170 (once)
PM10 — 500
… again
PM2.5 — 50
PM10 — 65

PM2.5 — 170 (once)
PM10 — 500

Please help me.