Jared Wolff
Published © CC BY-SA

The Canary: A Portable Air Quality Monitor

Air quality on the job is overlooked. Respirators are uncomfortable. But do you know what you're breathing in? Learn how to build your own.
  • Difficulty: Intermediate
  • Type: tutorial
  • Duration: 24 hours
  • Views: 3339
The Canary: A Portable Air Quality Monitor

Things used in this project

Hardware components

Jumper wires (generic) Jumper wires (generic) × 1
FeatherWing Tripler Mini Kit - Prototyping Add-on For Feathers × 1
HPMA115S0 Dust Sensor × 1
Lithium Ion Battery Pack - 3.7V 4400mAh × 1
Panasonic EKMB Series PIR Sensor × 1
Optically Clear Foam Mounting Tape × 1
Wire, Wrapping Wire Wire, Wrapping Wire × 1
Particle Squared: a Particle Powered Air Quality Sensor × 1
Boron Boron × 1
Adafruit Ultimate GPS FeatherWing × 1
SWI3-5-N-P5 × 1
PJ-005A × 1

Software apps and online services

Fusion 360 Fusion 360 × 1
SORACOM Air IoT Connectivity Platform SORACOM Air IoT Connectivity Platform × 1

Hand tools and fabrication machines

IPS Weld-On 3 Acrylic Plastic Cement × 1
Wire Stripper × 1
Hot Air Station, Industrial Hot Air Station, Industrial × 1
Hand Unwrapping Tool, Left/Right Hand Hand Unwrapping Tool, Left/Right Hand × 1
Soldering iron (generic) Soldering iron (generic) × 1
Wire Wrap Tool, Gun Wire Wrap Tool, Gun × 1


There are a lot of things out there that can get you.

The boogie man for instance.

Arbiter of doom right here.

But there are some things you can't see. Like what's flying around air the air. Which may lead you to think: "What the heck am I breathing?!"

Not too long ago, I had the same question.It was obvious that this could be used in many applications. But one had stuck out over the others: construction& renovation.

You can only imagine what type of dust and particulates a carpenter breathes in during the day. And when you do it all day almost every day it could cause health problems or even death. (and you thought smoking cigarettes was bad!)

The solution?

Ta da!

A portable air quality meter with real-time updates. Anyone can bring it onto a job site, hang up on the wall and forget about it. But, like a canary in a coal mine, it'll be there to chirp in when things are getting out of hand (though canaries did the opposite 😬).

The idea of the project was to piece together readily available components into a usable and robust form factor. It should withstand use and abuse by carpenters and workers who may not treat things so delicately.

How it works

The Canary consists of a few separate distinct parts. The brains are powered by an nRF52840 hiding inside a Particle Boron. The Boron is connected to an air quality sensor board (The Air Quality Wing by yours truly), a dust sensor from Honeywell, and a GPS breakout board (Ultimate GPS Feather by Adafruit). There's also some extra bits in there like a 4400mAH battery, piezo for producing cheerful melodies, and an all-in-one PIR sensor for detecting motion.On regular intervals, the Boron checks the air quality and then upload it to the web. I decided to evaluate SORACOM's services, so everything got sent directly via the TCP client on the Boron.Airflow path. (The hole above that compartment would be filled by the PIR sensor)The Boron then evaluates the data from the dust sensor on board. If the readings are no bueno, it sounds a polite but constant alarm that something is wrong. It also changes the LED color consistent with some well known indoor air quality scales. (More on that in the Play by Play) The LED only activates when there is motion near the device.When sending the data to the cloud, the device starts in an unconnected state. So the modem needs to power on, connect to the cell towers, open a socket to SORACOM, send the data and power off. All of this takes about 25 seconds. If you can imagine, this saves a significant amount of power compared to havingLTE on the whole time.Oh, and let's not forget about the GPS. The device checks location every hour and on startup. That way you know what job site it's at.Dashboard

On the web, there's a dashboard that the boss can log into and understand what's going on at his/her job site. The dashboard can be configured with alerts so when something goes wrong they can take immediate action. So not only will the workers know when the air is dangerous but the boss will too!

The device designed to shut down and save battery. That way it lasts a long time. But, when it does need a charge,plug it into the wall to top it up.

Cost breakdown

Here's a breakdown of all the components and costs. The only thing not factored in is the TLC this project got from my delicate engineering hands. 🥰

Cost breakdown

Here's the McMaster breakdown too..

McMaster Breakdown(Note: for the most part I did not include shipping and tax)

Connecting all the bits

The electrical assembly part is fairly straight forward. Here's a picture of the Fritzing "breadboard" design.

Finalized schematic.

To make the connections I used mostly wire wrap. Check out the play by play below to learn more if you're curious how I did that.

Getting The Code & Files

To get the full working code, Ponoko files (for laser cutting), Fritzing schematic and mechanical files, sign up here!

The play-by-play

Interested in how I put this together? Here's my journal from beginning to end.

Sunday 5/12 - Research phase

Tired. Oh so tired.

I spent a good chunk of the night looking for inspiration. (It's now... 2am) I'm imagining how I could make this project a reality with what I already have. I'm asking questions like: "What can I leverage?" "What do I have to do from scratch?"

I missed out on the Soracom free goodies but that's ok. I ordered one on Amazon and it should be here by Tuesday or Wednesday. (Woo!) Boron should arrive Tuesday. Much of the code for the particle sensor itself has been a work in progress since releasing the Air Quality Wing a few weeks ago.

Let's see if I can make this come together..


Tuesday 5/14 - Starting out with mechanical

I'm starting to put together the mechanical bits. For the circuit boards, I'm simply exporting them right into Fusion360.

EagleAD Export to Fusion360

I went ahead and started manipulating the parts until I found a happy configuration. Check out the evolution below:

Mocking everything up.Creating the base.Putting up the walls.More dividers inside to keep things in place.

This is the first time for me modeling something in Fusion360. I typically use it for PCB exports only (for double checking my work among other things!).

There's a big laundry list of things to do but I think I'll get there eventually.


Wednesday 5/15 - Ticking items off my list

Going to try and attack some more of this CAD work. Here's my todos from my notebook:

My to do list using my engineering scribble.I think I'll tinker around a bit more and learn the interface. Also watching some online videos here that have been very helpful!


Thursday 5/16 - finessing mechanical bits and buying them all!

More time on the mechanical design. I had to go back and re-design some things. Man, being a Fusion noob sucks sometimes!

The trickiest parts were getting all the holes that are necessary for screws, LEDs, etc.

Screws the right length. They fit too!

Here's what things look like closer to "finished."

I could play more with it but I've already tinkering for more than 6 hours. Someone who eats, sleeps and breathes Fusion360 can probably get this done in less than two.

By the way, because of the time constraints, this design will be fabricated from laser cut parts. 3d printing will be cost and time prohibitive. I'll be using 4.5mm black acrylic and white (for the LED area).

I have some mechanical parts lined up in my McMaster cart. Geesh this stuff can get expensive quick!

Screws and standoffs galore.

Next stop, Ponoko!

Quoting process

The process of getting CAD to something that is useful for Ponoko is a process. It requires that you create a sketch from individual faces in Fusion. Then, you export that sketch to DXF. Import the DXFs into InkScape and modify as needed. For instance, I had to remove a line from each of the rectangles above otherwise Ponoko's software barfs.

The total damage for plastics? $31.54 + shipping.

The only post processing that will be needed is the screw head recesses on the top and bottom. More on that when we get there!

By the way, my final materials were all sized 'P1'. I used "Acrylic - White" for the LED window and "Acrylic - Black" for the rest of the assembly.


Friday 5/17 - SIM cards, prototyping, and code!I got my Soracom SIM!Soracom SIM in the flesh.SORACOM has a great quick start here.Install was easy!

Now to get it up and running with my Particle Boron...

Particle has documentation here. They do reference an older version of Particle OS. The latest is here. I'm having a bit of trouble getting this Boron to connect to SORACOM. I think there's a bug in the firmware. (The SIM works fine in my phone!)

But first I had to attach some male and female headers. That required breaking out the ol' soldering iron.

Soldering headers on the Triple Wing

Once the soldering was done, I hit it with the wire wrap. Then I realized I sodlered the headers in the wrong place. Soooo more headers. Finally, here's what everything ended up looking like after soldering:

Headers on Feather Ultimate GPS. Turns out I did not need the two RX/TX pins brought out.Headers on the Triple FeatherI also spent a chunk of time assembling together the electronic bits. I used wire-wrap to connect everything. It's one of my favorite prototyping techniques. So much so that I wrote a step-by-step how-to on how to best use it.Beginnings of wire wrapping connections to the GPS board

Next stop is getting the GPS functionality working. Stay tuned..


Monday 5/20 - TheHardware Is In!

Today is another day for progress! The hardware from McMaster is in. Along with the SCIGRIP acrylic cement.

Acrylic cementHardware

I also got an email from Ponoko that things are on their way!

Ponoko cutting my order.

Now if I only got to working on more of the firmware bits! I'm excited to get that going ASAP!


Wednesday 5/22 - Code and Considerations

One of the criteria for this project is to discuss cost, production implications, etc. So let's break this down:

Cost: as it stands right now the cost of the prototype unit is > $225. That's definitely high for this type of device. By integrating all the electronics into one PCB and by using a plastic injected enclosure the cost could be 1/3 the price in small run production. (100's of units) There's lots of moving pieces to get there like tooling, compliance and lots of testing but it's definitely within the realm of possibility.Now the big question is: does the cost of the device >$100 and reoccuring cost of service be worth it?

Well, companies want to know that their employees are safe. Not only that but it reduces the liability they have and its verifiable truth that the air their employees are breathing is A-OK. Healthy employees and less risk for the employer. And when I say risk, I talk about thousands of dollars in workers compensation for injury, lawyer compensation, dealing with expensive lawsuits etc.

Sounds like a win-win to me!

Remote debugging: remote hardware deployments are not easy. Things go wrong. The cleaning crew unplugs your device from the wall and now your customer is wondering why there's no data in their dashboard.


One of the main methods for being proactive about monitoring the device server side. When we don't hear from a device in a while it could trigger an alert. Also, most deployable IoT devices these days have the ability for OTA updates. If things go wrong, the default fallback is usually always to try and download the latest and greatest firmware. In the case of this project, I would implement both before ever shipping devices to real customers. It's company suicide otherwise!

SORACOM does have an API for device management and OTA updates. I'd likely dig more into it to see how it could fit within my project.

Security: security is not thought about enough in IoT applications. There's some built in stuff around OTA updates and having matching certificates but that only gets so far.The cool thing that SORACOM has is what they call Gate. It's a virtual tunnel that gets put up between your device and your servers. That way nothing on the outside can get in and, if you chose to do so, nothing can get out.

I would, with no doubt in my mind, use a Virtual L2 connection like SORACOM Gate to protect my IoT devices and the network itself. Even if someone got inside of the device and popped the SIM card in their iPad it wouldn't be able to connect to the internet.

SORACOM has really thought about all the aspects of device security. I'm definitely not an expert but they have some interesting services around provisioning not only over LTE/2G/3G/etc. but over Wifi as well. It's based on the SIM information when a device is entered into inventory.

Of course, let's not forget physical security.

I want to make sure that if anyone wants physical access to my device they're going to have to work for it. One way is to design the mechanical structure to make it hard if not impossible to take apart without causing destruction. Many companies use heat stake or even ultrasonic welding to close everything together. It may be tons of glue. In the V2 of the plastics (designed for plastic injection molding) I would definitely design that in. (Oh, and the device has GPS so until someone get's inside, we know where it is. 👮‍♀️!)


Because this would be an LTE CAT M1 only device, everything can be provisioned based on the SIM + serial/IEMI. That way, the only thing that needs to be done is associate the customer with the SIM in their device. In my case, all my customer would have to do is make sure it's charged and then deploy it for field use. The hardest part at that point is making sure the workers put it in the right place. (or that they bring it to the job site in the first place!)

There's tons more to think about here. Bringing any type of hardware product to market is tough stuff!

While I'm thinking about this more, here are some other updates:

Schematic in progress.

Here's a Fritzing schematic in process. It is the equivalent of what is inside this device for the exception of the processor board. I've substituted the Particle Boron with an Adafruit Bluetooth Feather. They are the same pinout so you should be able to wire everything up just the way I have shown. I'm still working on creating a Fritzing symbol for the Air Quality Wing. Stay tuned on that!

Sidenote: this isn't exactly the way I would design a production product. I'd generally go right to designing a custom board using Eagle, OrCAD or Altium. Those schematics tend to be more complex compared to a Fritzing one. Fritzing though is much easier to show connections for prototyping.


Thursday 5/23 - Plastic has arrived!

The plastics have arrived and it's time to do some final modifications.

First, countersink!

After countersinking all the holes on this piece.

I popped the bit into the drill press and started boring out some countersink holes for hte screw heads. I tweaked the stop until I got a good depth that would bury the screws but not cause issues on the other side.

By the way this is what the countersink bit looks like up close:

Countersink Bits!

The size of your screw head will determine which one you should use. You can also play with depth to determine the size of your countersink hole.

I did the same for the top cover as well.

Here's a close up up from me doing a fit test. This is with the top and bottom assembled.

Countersunk machine screws!Turns out, after the fit test, the sides did not sit flush with the top. So I ran the countersink bit on the other side to also the top to get closer.

Similarly, I also had to make some modifications for the PIR sensor. (The hole was not big enough) So I drilled it out and then countersunk the other side. That way it sits nice and flush! (The sides of the PIR sensor are tapered thus the extra step!)

PIR sensor assembled.

Once everything checked out, it was back to my office for final assembly. I was trying to figure out the best way to clamp things together when I realized I already had a pretty good clamp.

One side in!

The top and bottom! So I got the first side in between the two and then clamped it down. I sifted it slightly until the acrylic was flush with the outside edges of the top and bottom. Once locked in place, I took the handy applicator and applied it to where the bottom and the side met. I repeated as necessary.

Second side in.

Once al the sides were on. It was time to test fit of the electronics.

Test fit electronics

Here's everything a little more.. situated.

I did secure the battery and particle sensor down with some doubled sided VHB. It's handy to always have a roll. You never know what you may need it for!


Here's an action shot with the LED glowing.

Glowing LEDs!

Today has been a great accomplishment. The list of things to do is shorter but there's not much more time to waste. I plan on cleaning up some wires and then getting back to coding. More updates on that soon!

Saturday 5/25 - Firmware work continues

My main goal for the day was to get the GPS up and running. Then, once that was working, how to share the single USART between the GPS and HPMA dust sensor.

For the sake of time, I opted to use the Adafruit_GPS library for the GPS. I added it as a submodule to my project and then made the necessary changes to get it to compile. I attempted to add it using the particle command line but it wasn't compiling. 😭

For the sharing bit, I settled on sharing a struct between the two classes. When one would take "ownership" it would change the struct as used by that class. When done, it would simply release it back for use by the system.

Here's some code to illustrate what I'm talking about:

// Return busy error if( this->serial_lock->owner != serial_lock_none ){ return HPMA115_SERIAL_BUSY; }

This is the first bit of the HPMA enable function. It's ensuring that the serial bus is available and there's no lock. If there is, we'll have to try later.

Conversely, here's the beginning of the disable function:// Return busy error if( this->serial_lock->owner != serial_lock_hpma ){ return HPMA115_SERIAL_BUSY; }

This time I check for ownership to make sure I'm not changing the lock when someone else may be using it.

At the end of the enable and disable functions I would set this->serial_lock->owner. It's a pointer to a struct in the main context so what's updated here will update there too! (i.e. I made a semaphore to share between the two drivers)

I'm sure there's better ways of handling this. This was my solution and it seems to work well.

I also hooked up the all-in-one PIR sensor. It's the white circular bit next to the LED window. I'll use it to turn the device LED on so someone in the same room can look at the current air quality level. The closer to red, the worse it is!

Sunday 5/26 - UploadingGPS, Getting SORACOM SIM to work with Boron

Another day for coding. Here are major items on my list:

  • Getting the piezo working
  • Uploading GPS data to the cloud
  • Handling PIR events and controlling LED
  • Audible alarm
  • Disconnecting from cellular
  • I did have to hook up the piezo for the alarm. After that though, it was allllll software.

    Piezo all wired up.

    After some uneventful coding, I hung it on a nail in the office to see how it looked (and sounded) in alert mode.

    Hang it on the wall for a test.

    I did hard code the alarm levels:

    // Hazard levels#define PM25_LOW 15#define PM25_MED 30#define PM25_HIGH 55#define PM25_HAZARDOUS 110It was based on some EU standards. Unfortunately everyone has their own ideas so these numbers vary by country and region.The major thing that I've noticed playing with the GPS module is that it takes along time to get a fix on a fresh start. Eventually it may be a good idea to put a CR1220 in the battery holder. In the mean time though, I wired that connection directly to the device's li-poly pack.Unexpectedly, I felt a rush of inspiration to tackle one of the main problems with this project.. I couldn't use my SORACOM SIM. I was using the correct call in the Particle software but it wasn't connecting. Additionally, I had no feedback as to why.


    So I spent a few hours getting to know the Particle Device OS codebase. Learning how to compile. Figuring out what flags did what. Most importantly which flags turned on logging in the place I wanted it!I put breakdown of my research and conclusions on Particle's forum. Turns out it just needed a few commands before the modem was fully set up. If you're trying to set your Boron up with SORACOM here's what to do:

    1. Clear your credentials and set the external SIM (if you haven't already)


    2. Then, when you wan to connect run these few commands.


    Make sure that the device is in SEMI_AUTOMATIC mode.


    If you have a SIM with credentials this *should* also work for you.

    It was a glorious occasion to see the system logs come across my screen with success messages. Be aware it's a bit of a hack and hopefully we'll have a fix for it soon. For example, safe mode *will not work* with this "fix."


    I ran the device over night and checked my data usage in the morning.


    It shot up from about 30kB to where it is now. So for about 12 hours of running ~240kB is ok. Say that's about 500kB per day. That's $1.095 per month in data usage and $1.8 in basic fees. And that's at the entry level!

    I'm going to take a break from staring at a screen. But this week will be filled of cloud infrastructure work. The goal is to have a dashboard and notifications up and running by the end of the week!

    Tuesday5/28-Harvesting DataBesides putting in a pull request to get the Particle Device OS fixed, my main goal for the day is to get up and running with some of SORACOM's web portal services.

    My first stop?


    I first started off by following the instructions here. It was so easy to set up I had data immediately!Data on SORACOM HarvestI'm also jazzed about the next "level" portal they have because it's uses Grafana. I'm a big fan of Grafana and have written about it in the past. If you prefer to run your own rather than use SORACOM's learn how to make your own amazing looking dashboard here.

    Nevertheless, I still wanted to get my data into Lagoon. It will help me visualize device location and the data in real-time. Plus it has notifications built in which is one of the most important features of this project!

    After some more finagling and debugging in firmware, I finally got it to the point where all my data was coming across. Along with some handy GPS coordinates!

    Hello from the northeast!

    Next stop: getting Grafana set up!

    I enabled the free version of Lagoon by going to the console and then clicking on SORACOM Lagoon. For my purposes, free was ok with me. Then, I logged into my Lagoon instance using the same credentials as the SORACOM Console.

    I went ahead and started making a dashboard similar to one's I've made in the past. In the case of this Grafana instance, all the piping of data has been done for me. There was no database connection to obtain, etc.

    Starting a new workspace.I created added a Soracom Map Panel,Graph and AlertList to my main dashboard. It's so easy to use Grafana that I had everything within 5 minutes.Final Dashboard

    The only thing I had to add from the outside was the connection to Pushover which I used for notifications.

    Adding Pushover.

    I gave it a quick test and bingo. Instant alerts!

    Alerts from Grafana using Pushover

    For an end user I wouldn't want to make it more complex than necessary. If we're solely concerned about air quality, one or two metrics will do fine! (Specifically PM2.5 and TVOC)

    As I discussed earlier, once I had a few units up and running I'd set up a Virtual L2 connection so all my unencrypted data would be protected. Not only that but there's less of a chance for someone from the outside to hack into my devices or run up my data bill. A telecom company rep told me not too long ago that a police department decided not to implement a tunnel (the equivalent of Soracom Gate) and had to pay thousands of dollars in usage fees because some kid in India had gained access to an MDT (Mobile Dispatch/Data Terminal) in a police cruiser.


    All the successful IoT companies I know of use this tech. So you should definitely think about it once you start to scale!

    Finally, some finishingtouches fresh from the vinyl cutter.Vinyl cutter finishes

    Oh yea. Now we're styling.

    Final thoughts

    I didn't get a full chance to dive into web technology as much as I wanted to. Using something like Funnel and Beam would be great for a custom application running on AWS. Once this turned into a much more optimized device, there'd be a great opportunity to use Lambda for OTA checks and updates. I've worked on projects in the past that have used AWS IoT but haven't had a chanced to dive more into capabilities there. I think it'd be a great opportunity once past the POC phase to spend more time playing! 😎


    A big shout out to you, a fearless explorer making it to the end of this endless post!

    Kudos, high fives and all that jazz. 🖐🍫🎷

    If you have questions, should should let me know down below. If you want to learn more about me and what I do check out my site. And if you're giddy with excitement and want all the detailed source and files, you can download it here.