Arduino: measuring PM2.5 and PM10 with Honeywell HPMA115S0

33

An essential aspect of measuring air quality is to determine the number of small particles. That is, things smaller than 10µm and 2.5µm. Such tiny particles are roughly the size of a microbe and can penetrate the lungs,  causing many health issues.

But how we can measure such small things? Most often, this is done via laser scattering: a laser light source illuminates small particles as they are pulled through the detection chamber. As these particles pass through the laser beam, the variations in light intensity are recorded by a photodetector. Those variations can be further analyzed to determine number and size of particles.

Amongst other sensors that use this technology lies the Honeywell HPMA115S0-XXX, a calibrated sensor with digital output via UART protocol. The sensor can determine PM2.5 and PM10 in concentrations up to 1000µg/m3, with an accuracy of ±15%.

When measuring, the fan draws the air in through the air inlet. Particles in the air go through the detection chamber, where they pass through the laser beam. The light reflected off the particles is captured and analyzed by a proprietary algorithm, and the amount of particles in the air is determined. The sensor is internally calibrated, so all we have to do is read the results on the UART interface,

The sensor can operate in the -10°C to 50°C interval, with humidity up to 95%RH, non-condensing, Its lifespan is about 20,000 hr in continuous mode.

The sensor has a very small connector. The datasheet specifies the mating connector as Molex 51021-0800. Be warned, that part no. is only for the plastic housing, it comes without pins.

Honeywell HPMA115S0-XXX particle sensor

Honeywell HPMA115S0-XXX particle sensor

I deeply hate crimping such smaller connectors, so I tried to find an easier alternative. And I have found some pre-crimped PicoBlade, Molex 06-66-0015 cables.

Molex ready made cable

Molex ready made cable

You might notice I haven’t populated the whole connector as some pins are not connected internally.

[Update May 18. 2018]: As correctly stated by Lloyd in the comments section, there was a mistake in the original blog post. I have inadvertently used a picture from the making of the project which showed incorrect wiring. This has been corrected and replaced with the picture below:

HPM Series HPMA115s0 pinout

HPM Series HPMA115s0 pinout

Wiring of the sensor requires only four pins:

Pin 2 (Vcc) goes to the 5V pin on the Arduino board.
Pin 6 (UART TX) goes to the RX pin of the Arduino board. This pin uses 3.3V logic level.
Pin 7 (UART RX) goes to the TX pin of the Arduino board. This pin uses 3.3V logic level.
PIN 8 (GND) goes to GND pin of the Arduino Board.

Pin 1 (3.3V output) is left unused.  The wire is in not connected, as the Arduino board provides its own 3.3V power supply.

Please observe the pin numbering, with the rightmost pin being pin #1 (close to the fan), and the leftmost pin being pin #8.

Now, the sensor is ready to be used. What about communicating with an Arduino?

1 2 3
Share.

33 Comments

  1. I was not able to get this to work at all. It looks like you are using softserial in order to declare Serial3 but you never do that. Is your code incomplete?

    • Hi Jon,
      The Flip & Click board I used is an Arduino Due clone. It has 3.3v logic levels, so it matches the requirements of the Honeywell sensor. Also, the board has four hardware serial ports, so there’s no need to use software serial.

  2. Lloyd Brown on

    It appears the photo of the HPMA and connector wiring is incorrect. The connectors are numbered from right to left. 1-3.3V; 2-5V; 3-N/A; 4-N/A; 5-Test; 6-TX output; 7-RX input; 8-GND. As per the Honeywell Data Sheet.

    It appears from the wiring from the HPMA to the Flip and Click this was discovered and an additional wire was put in to cover the numbering being from right to left.

    That might be why Jon’s circuit did not work assuming he wired it like the HPMA and connector photo and assumed the numbering was left to right. Luckily I noticed before I hooked power to it. Still have to hook it up but think that would have been a problem had I assumed left to right numbering.

    • Teodor Costachioiu on

      Hello Lloyd,

      I’ll check this first thing tomorrow morning, and I will make the required updates if needed.

      Thank you very much for your comment, it helps a lot to receive such feedback on my blog posts.

  3. debajyoti dash on

    Hi TEODOR COSTACHIOIU,
    I am a student working on atmospheric sciences at University of Hyderabad, India. Currently I am working on collecting atmospheric data using unmanned platforms. Since nobody in my team is from electronics background we are finding it difficult to use HPMA115S0-XXX air quality monitoring sensor with Arduino uno microprocessor. We strictly want to stick to Arduino uno because we have already built our unmanned platform and have been acquiring other atmospheric parameters using various sensors using Arduino uno. It would be difficult on our part to shift to other microprocessors. We came across your blog and really found it interesting. It would really be a great help if you can provide us with detailed schematics and a working code on Arduino IDE for UNO. We promise you to credit you by acknowledging your contribution to our project in any paper we publish (It would basically be an atmospheric science paper).Please feel free to contact me via email and help us at the earliest.

    • Teodor Costachioiu on

      Hi,

      The code I have posted should work fine on the Uno. The problem lies in the fact that the sensor uses 3.3V logic, and is powered from 5V. The Uno can provide 5V power, but it also uses 5V logic.

      My suggestion is to use some level translators on the serial (TX and RX) lines, so the sensor couls still work on 3.3V logic. Like this one https://www.sparkfun.com/products/12009.

      • debajyoti dash on

        I tried as you suggested but I am getting an error message saying “serial3 was not declared in this scope”can you help me with this.

        • Teodor Costachioiu on

          Hi,

          Hi,

          Serial3 is available only on Arduino Mega/Due. Arduino Uno has only Serial.

          You can sacrifice PC serial debugging and connect the particle sensor on pins 0 and 1 of Arduino Uno, and change from Serial3 to Serial in the code.
          Or you can use software serial – https://www.arduino.cc/en/Reference/softwareSerial – and use any spare pins of Arduino Uno.

          • debajyoti dash on

            I finally decided to go for arduino mega. But the problem is now I am getting both pm 2.5 and pm10 reading as zero continuously. Can you think of any possible errors?

  4. debajyoti dash on

    Hi TEODOR
    Could you please help us sort out the issue as mentioned Earle we used arduino mega but now the code is still returning 0

    • Teodor Costachioiu on

      Hi,

      It’s extremely difficult to debug a project from a distance, especially if all you tell me is that it doesn’t work. Please be more specific: how did you connect the sensor to your Arduino mega, dis you use the level translator, how did you connect it, which serial port are you using, etc.

      • debajyoti dash on

        Hi TEODORE!

        Thanks for responding and sorry I am late. I am sorry to have given you incomplete details. Actually we went for Arduino Mega and used the level shifter as given in the link-

        https://www.amazon.in/4-Channel-Converter-Bi-Directional-Shifter-3-3V-5V/dp/B074N1NCVX?tag=googinhydr18418-21&tag=googinkenshoo-21&ascsubtag=f29e6219-ba00-43af-b183-f0fd27838624

        We connected 5V and 3V from Mega to HV and LV of level shifter respectively. We connected Ground from Mega to the respective Ground of Level shifter present on HV side and the Ground from the sensor to the respective ground of level shifter on LV side. The TX pin (TX3, 14) and RX pin (RX3, 15) from Mega was connected to HV2 and HV3 on HV side of level shifter respectively. The RX and TX from sensor was connected to LV2 and LV3 on LV side of level shifter respectively. We powered the sensor from a parallel taken from a constant 5V output from Mega (the other end of the parallel goes to HV on level shifter). We used the exact code provided by you and we got output displayed on Serial monitor as follows-

        Stop autosend status is 0

        Start measurement status is 0

        Checksum fail

        Read measurement status is 0

        PM2.5 value is 0

        PM10 value is 0

        Checksum fail

        Read measurement status is 0

        PM2.5 value is 0

        PM10 value is 0

        ……………………………………………………… (Same thing kept showing on screen)

        On the board, we could find only the TX pin blinking and not the RX pin however. Can you suggest something as to what might be going wrong here?

        • Teodor Costachioiu on

          Hi,

          I know I have one of those level translators somewhere in my office. I’ll search for it and try to recreate your connections. I’ll try to write a follow-up in the next few days.

          • Teodor Costachioiu on

            Hi,

            I have done some testing today, I can confirm the level translator does its job fine. But you need to do a small change in the code:
            everywhere in the initial code you have

            you need to change to

            This is because Arduino Mega has an 8 bit processor, while Arduino Due has a 32 bit processor.

            If still doesn’t work, try swapping TX3 and RX3 lines.

  5. debajyoti dash on

    Hi TEODOR
    We tried changing char to byte and we are getting the following output on serial monitor,

    Stop autosend status is 1

    Start measurement status is 1

    Checksum fail

    Read measurement status is 0

    PM2.5 value is 0

    PM10 value is 0

    Happy to see a non zero value at last but still it is not giving any helpful output. We tried swapping Tx and Rx as well. Do you think there is any issue with the sensor itself?

    Thanks for being so cooperative and helpful as always.

    • Teodor Costachioiu on

      1. Is the sensor working (fan on)?
      2. Try to use the SerialPassthrough sketch in Arduino IDE, see what the sensor tries to send.

  6. debajyoti dash on

    Hi TEODOR
    1.The fan is working fine
    2.I tried to use SerialPassthrough sketch and got output as follows:-
    BM⸮BMQ??xqBM???BM and so on…
    I saw again the RX led was not blinking.Could this be some error with the sensor?

  7. Teodor:

    Thanks to your code I was able to use a Sparkfun RedBoard Arduino UNO clone and altSoftSerial plus a level shifter to get my HPMA working. I also have a DS3231 real time clock and a sainsmart LCD2004 display to make it portable.

    It was a struggle. I got the thing working hooked up to the PC but when I powered it from a RavPower Powerbank it read 0. Hook it up to a PC and it worked. Didn’t matter if the IDE was running or not. Bizarre. Finally added some more code to tell what was going on via the LCD and it started to work if the stop_autosend came back OK which is once in a while.

    Changed the code so it had to come back good from stop_autosend before it went on. Usually that takes 2 calls to the stop_autosend function. Sometimes it will hang up and never get out of the loop to stop auto send in which case I have just hit the reset button until it does work. But it does work from a portable RavPower power bank. Tried the plug connection but I don’t have a 9-12V source, only a 7.5V 300 ma which does not work on my setup.

    So thank you for posting your code. It helped tremendously to get a leg up on it.

  8. Jesper Nielsen on

    Would it be possible to post an instruction on how to make this work with an Arduino UNO? From the above comments I get the impression that it should be possible, but I don’t have the skills to figure out how to do it.

  9. Jesper Nielsen on

    Thank you, that would be much appreciated. Don’t know if this is helpful at all, but somebody posted a youtube video of an Arduino Uno connected to a HPMA115S0 at https://www.youtube.com/watch?v=FbOXwPFTYms
    There is a link to the sketch in the description under the video, but unfortunately no description of how to connect the wiring. It looks like some sort of level translator is used, but I can’t really tell from the video.

  10. Jesper Nielsen on

    One more question: If I use an Arduino Pro Mini 3.3V version, then I guess I won’t need the level translator. Is that correct?

    • Jesper Nielsen on

      So the idea is to connect like this:

      Pin 2 (Vcc) goes to the RAW pin on the Arduino board (which is at 5V, since the Arduino is powered via USB).
      Pin 6 (UART TX) goes to the RX pin of the Arduino board. This pin uses 3.3V logic level (since this is the Arduino Pro Mini 3.3V version).
      Pin 7 (UART RX) goes to the TX pin of the Arduino board.
      PIN 8 (GND) goes to GND pin of the Arduino Board.
      Does this look like it might work?

      • Teodor Costachioiu on

        See the above comment regarding 5V power. Also, be careful that RX and TX pins of Arduino Mini are also used for serial debugging and programming (via FTDI adapter). Software serial might work, in a simmilar way I did in my last blog post on H2S sensing.

    • Teodor Costachioiu on

      It won’t work! The HPMA115S0 sensor needs 5v power (but it has 3.3v logic levels). At the same time, the Ardiono mini can deliver only 3.3v. As such, it cannot power the sensor.

  11. Jesper Nielsen on

    Line 9 in example.ino is “#include ”
    But the name of the library is hpma115S0.h
    For this reason the sketch wouldn’t compile, but after changing the name it works flawlessly on my Arduino UNO.

  12. Jesper Nielsen on

    Sorry about the above mess, it should have said
    Line 9 in example.ino is #include ‘HPMA115S0.h’,
    but for some reason ‘HPMA115S0.h’ got cut out every time I posted.

Leave A Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.