Last time I looked at prototyping a website based remote control of an LED lightbulb via web bluetooth with the PAN1780 Evaluation Kit running the Neopixel driver firmware taking center stage.


This time, I thought of an opposite scenario: instead of sending data over to the bluetooth peripheral, I would like to receive data from the bluetooth peripheral.


It so happened that I have a Honeywell Particulate Matter SensorHoneywell Particulate Matter Sensor from a project I started (but haven't finished--I'm sure you know the experience) and I figured this would be the best time to finally work on it.

I do want to let you know that (in the interest of full disclosure) the PAN1780 evaluation kit was sent to me as part of Element14’s Road Test program, and I’m very grateful to them for the opportunity to road test the product.


The other products in this review (unless otherwise noted) were purchased by me using my own funds.


All the opinions you are about to read are all my own; nobody is paying for this review, nor has anyone reviewed or approved the content before it was posted.


I will also be approaching this road test from the point of view of a hobbyist that has had some experience with similar products, but have yet to deal with them in a professional setting.

Parts and Software

Web Browser and Javascript Libraries

The setup here is mostly similar to the previous blogpost so I won't repeat it here; I would suggest going through that first since I talked about enabling the web bluetooth feature on Google Chrome.


I will be using a third party library called Chart.js for graphing values retrieved from the sensors however. As with the previous project, I aim to keep the html, javascript, and css code in a single file so it's easier to follow along (no need to compile the project and have a specialized setup just to do that; all you need is a modern browser).


Particulate Matter Sensor

Here in Malaysia we used to have annual smog and haze events that were largely blamed on illegal agricultural slash and burn practices in some parts of Indonesia. One of my friends have respiratory problems, and would be suffering from increased lung and throat irritation during those times.


While the Malaysian government science departments do track the air quality, we didn't think they were that accurate (at least in our locations) because the data would indicate "good" air quality when we can see (and for my friend's case, feel) that it wasn't. So we planned on getting one of those particulate matter sensors to try and do some citizen science and maybe create an open data repository of PM readings.


The project fizzled out this year due to the pandemic, but that doesn't mean the sensor should be junked. It's a high quality, industrial-level particulate matter sensor that uses the principle of laser light scattering for detecting and counting the particles. Here's a product overview:

The HPMA115SO-XXX from Honeywell is a HPM series PM2.5 particle sensor with UART output. The HPM series particle sensor is a laser based sensor which uses light scattering method to detect and count particles in concentration range of 0µg/m3 to 1000µg/m3 in a given environment. A laser light source illuminates particle as it is pulled through the detection chamber. As particles pass through the laser beam, the light source becomes obscured and is recorded on the photo or light detector. The light is then analysed and converted to an electrical signal providing particulate size and quantity to calculate concentrations in real time. The Honeywell particle sensor provides information on the particle concentration for given particle concentration range. It is used in potential industrial applications such as HVAC (air conditioners, air quality monitors, environmental monitoring) and consumer products (air cleaners, conditioners, purifiers, car air cleaners, handheld air quality detectors).

So instead of its original purpose, I thought of using it to monitor the particulates in my room instead (where I do my soldering work). While I do have a carbon-filter exhaust fan, I would still like to know if soldering work does increase the PM2.5 and PM10 density of my environment.


Temperature, Humidity, TVOC, and eCO2 Sensors

Since I was already tracking particulate matter, I thought why not track various other metrics as well?


I've been looking for an accurate temperature sensor, and I settled on a CCS811 HDC1080 combo breakout from a local online seller. It has the AMS CCS811 Total Volatile Organic Compounds (TVOC) and [estimated] Carbon Dioxide (eCO2) air quality sensor, together with the Texas Instruments HDC1080 Temperature and Humidity sensor.


Sparkfun and Adafruit do sell the CCS811 and the HDC1080 breakout modules separately, but in my case they are in just one combo board. They all communicate via I2C though so if you're following along and you only have the separate modules, it would still work (you'd just need to wire the I2C data and clock pins with each other).



Web Bluetooth is great and all, but I also wanted to just see the current status of the air quality without having to look at my phone (especially while I'm doing development on the project and I wanted a quick check if things are still working as expected) so I added one of those common SSD1306 oled displays that work via I2C.


PAN1780 Firmware

As before, I'm using Espruino for the firmware and writing the program in Javascript. I'm attaching the same file on this post in case you're following along.



Sourcing Power from the Board's Rails

Unlike the previous project where the addressable RGBs only required 5v the SSD1306, HDC1080, and the CCD811 works with 3v3. This meant I needed to also enable 3v3 pin headers by setting up a jumper.


I also took the opportunity to check how good of a regulator is the one included in the PAN1780. Note that I was not able to find any kind of information regarding the 3v3 regulator. I was primarily interested in the maximum current draw (in the 3v3 rail; I was also interested in the current draw in the 5v rail but, as was discovered in the previous project, the 5v rail should have been marked Vin since it was directly connected to the VUSB), but I couldn't find any mention of this.


I was impressed by the picoscope because of the roadtest by Michael Kellett so I got myself one. I couldn't afford the same picoscope, and I was only able to get the cheapest of the bunch: the Picoscope 2204aPicoscope 2204a. It's my first "real" scope (after having spent time with various "toy" DIY scopes like the DSO138) so please let me know if I'm doing something wrong; I am very much a beginner at this and most likely not know what I'm doing.


Anyway, I tried to check the ripple in the 5v rail using my 18650 powerbank (it takes a 18650 cell and boosts it up to 5v) and came up with this:


I was curious what kind of filtering the PAN1780's regulator would do even if it was given this kind of ripple.


Surprisingly, it did very well. I did multiple test points on various 3v3 locations because I initially thought that I probably wasn't making correct contact, but the signal was quite clean:


For comparison, here's the output of an 5v AMS1117 that doesn't have the correct output capacitor for filtering. I'm not sure what the down spikes evert millisecond comes from; maybe it's the LED from the jlink? In any case, these spike aren't present in the regulator built-in the PAN780:


I was encouraged by this, since I now know (with objectivity) I'm providing clean power to the sensors and would likely get stable readings, especially for temperature.


Shield and Wiring

The sensors require two serial interfaces: UART and I2C. This means I only need four GPIO for communications: two for the RX/TX bus, and two for SCL/SDA bus, plus one for the CCS811 interrupt. I just needed to connect the 5v rail to the HPMS and the 3v3 rail to the other sensors.


As usual for my oneoff prototype projects, I didn't go for etching or manufacturing my own PCB but rather just used wire wrapping for my point to point connections.


Learning from last project's issues (where the header design makes shields susceptible to reverse polarity) I opted to not center the board, but instead provide an "overhang" so that I can remind myself of its orientation. The baseboard (which protects the underside pins from short circuits) was attached in the same way for balance.


Assembling the Sensors

With the wiring done it was just a matter of placing the sensors on the shield. First is the HPMS which sits near the end of the shield. I soldered some male header pins at the end of an 8-pin molex connector so it's easy to reassemble if needed.


Next is the HDC1080/CCS811 breakout board. You'll notice that I stacked multiple risers for the sensor; this is something I found out while testing the sensor data: the regulator can radiate quite a lot of heat during operation. It affected the sensor readings by a good three to four degrees when sitting just above the PAN1780. Had I known this, I would have reorganized the position of the sensor closer towards the back, but I didn't really feel like redoing the layout so I just did what I can to make the most of the situation.


The SSD1306 also comes with a riser to raise it just above the HPMS body (so we don't block the intake vent).


Software (PAN1780)

The HPMS and the HDC1080 didn't have available libraries for Espruino at this time, so I had to implement my own (rather simplistic) routines to communicate with the sensors. I felt this was a good thing though, as it was an opportunity to show how I2C and UART communications are handled in Espruino.



You can also find it in this gist:


Here's a quick rundown of the code:

  • Lines 1-5 sets up the Bluetooth UUID I'll be using for my custom characteristic. While there are Bluetooth SIG-defined UUIDs for Temperature and Humidity, there aren't any for TVOC, eCO2, and particulate matter.
  • Lines 7-62 sets up the UART communication with the Honeywell PM Sensor. I didn't implement all of the communication protocols; only the simplest one.
    When the HPMS boots, it automatically goes into automatic measurement mode where it will send a PM2.5 and PM10 measurement every second, encoded in a 32 bytes long array.
    If the UART communication was perfect, this section wouldn't be that long but bulk of this routine was to do error correction. For example, sometimes there's less than 32 bytes that gets streamed in, so we need to wait for the next transmission to build a full message payload.
    In fact, I had to remove some code that filters out payloads that don't match the calculated checksum because even though the values seemed to be correct, the bytes within the payload are quite noisy it was rare to have a valid checksum! I should probably look into shielding my UART cables in the future.
  • Lines 64-93 sets up the I2C communication with the HDC1080. Again, not all of the protocols available in the datasheet was implemented; only the ones I'm using in this project.
    In this case, the HDC1080 boots up with its registers configured to be always measuring and the temperature and humidity data written together, so it was just a matter of reading those registers when I need a measurement.
  • The rest of the code just sets up Bluetooth services, and also displays the data on the OLED. One interesting tidbit might be lines 134-136 where an integer is converted in little endian format. Many characteristics defined by the Bluetooth SIG define numerical values to be in the little endian format, so I decided to just use those for consistency. Also take note of the notify: true settings; they cause changes to the values to send a notification to the client that they can subscribe to.


Software (Google Chrome)

As before, I'm striving to keep the html, css, and javascript code together in one file for ease of inspection and reproduceability. You can take a look at the code in this gist:

The biggest change here as opposed to the lightbulb example is on lines 137-145 that sets up the callback found on lines 163-173.


Whenever we are notified of a change (because of how we set it up in the program above) we run the handleCharacteristicChanged callback and update the graph.



Here's a small video of the whole thing in action:


You can see how the values change as I breath into the sensors.


Here's a screenshot of the graphs:

As before you can take a look at the page that was running in the video here:



  • The 3v3 regulator built-in the PAN1780 is quite good at filtering noise from the VUSB supply. However there are no mentions of the current capabilities or links to a datasheet. Upon looking further at the schematic, this seems to be the regulator: It would have been nice to mention this in a text-searchable format in the manual, rather than embed it in the schematic image.
  • The regulator can run quite hot during continued operation, which can affect sensors depending on where you place them.
  • As was mentioned previously (and now confirmed) the VUSB power does not filter out ripple as it seems to be a direct connection to the pin header labeled 5v.
  • The relatively small size of the eval kit made for a compact and portable prototype.



The PAN1780 Eval kit's size (compared to the nRF52840DK for example) made everything portable and compact so I didn't require a large work area for prototyping. Perhaps this isn't a big issue for engineering teams, but for a hobbyist like me that lives in a small apartment, every bit of space saved in a crowded desk is appreciated.



Using Web Bluetooth, we are not limited to sending commands to peripherals, but we're also able to receive data as well. If we set up a notification for characteristic value changes, we can subscribe to them and have a monitoring station all without having to write our own native iOS or Android app. This opens up the possibility of attaching something like the PAN1780 to a remote sensor and have it "BLEfied" with its data being available wirelessly instead of having to ask the sensor to connect via wifi (which might not be available especially on remote locations).