Sniffing Trinket

A room climate monitor

Similar projects worth following
Ever worked for hours in a badly ventilated room and got a bad headache - Sniffing Trinket will watch over the temperature, humidity and air quality in your rooms and tell you when its time to open those windows. A great EDC tool for teachers and about everybody else working and living indoors...

Please see the project logs for extensive documentation! The code and all schematic/design files are available on GitHub (see link on the left side). Please also watch the demo video!

  • 1 × Adafruit Trinket Pro
  • 1 × MQ135 Air quality sensor
  • 1 × DHT11 humidity/temperature sensor
  • 3 × WS2812b RGB LED
  • 1 × Logic level Fet, eg. BSS138

View all 13 components

  • Final Thoughts and Video

    Georg Krocker01/02/2015 at 16:40 0 comments

    Before we start, go watch the video that summarizes this whole project.

    Some thoughts I want to share with you before the end of the contest. Working on the project for the passing weeks was a great experience and I'm very pleased with the results. Looking back at my original list of things I wanted to achieve with the project (go, read it yourself), I see that I can check all the boxes. While there are still some things to improve I feel that the project stands on solid grounds.

    The contest has also been a great learning experience for me. Despite the fact that I have already done a couple of projects I encountered a couple of firsts, including that I

    • learned how to do PCBs in KiCad and get them produced (something I will profit from immensely in the future)
    • learned to do project photos
    • learned to shoot and process video (ok, I can still improve on that ;)

    I also immensely enjoyed the documentation and I will clearly revive my website in the next weeks and continue documenting my projects there and here on

    As for the next steps, I will work a bit more on the software and on understanding the gas sensor. When this is done I will do a redesign of the board and build a custom case for the SniffingTrinket.

    If anything at all I hope that people will use this project and the documentation to learn and start building their own cool stuff.

  • SniffingTrinket sketch

    Georg Krocker01/02/2015 at 15:52 0 comments

    Just a very short post concerning the main firmware. You can find the sketch in my GitHub. There are two sketches, CalibrateSniffingTrinket.ino for the calibration of the MQ135 sensor (see last post) and SniffingTrinket.ino as the general purpose sketch. You need a couple of libraries to get the sketches running:

    • Adafruit NeoPixel Library
    • Adafruit DHT11 Library
    • A patched version of the Adafruit Trinket USB library (for the USB keyboard functionality)
    • My MQ135 Library

    Just install the libraries, compile the code and upload it to the trinket. I won't go much into details of the code, as the code itself is heavily commented and you should be pretty easily able to understand it. I will just give quick overview of the main loop of the SniffingTrinket.ino

    At the beginning of the loop the sensor values are read out.

    // Reading temperature or humidity takes about 250 milliseconds!
      // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
      float h = dht.readHumidity();
      // Read temperature as Celsius
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit - in case you still don't use the SI
      //float f = dht.readTemperature(true);
      // Check if any reads failed and exit early (to try again).
      if (isnan(h) || isnan(t)) {
        Serial.println("Failed to read from DHT sensor!");
      // Read out the Gas Sensor
      float ppm = gasSensor.getPPM();

    The next step is setting the LEDs to the correct color value. This is done by calling a dedicated function for each LED.

      // Set the LEDs accordingly
      setLedOutput(t, TEMPLED);
      setLedOutput(h, HUMLED);
      setLedOutput(ppm, AIRLED);
    Check if we have to sound the alarm
     // Check if the alarm level has been reached
      if(t > TEMPALARM ||
        h > HUMALARM ||
        ppm > CO2ALARM)
        tone(ALARMPIN, 5000, 1000);
    or if the button has been pressed.
    // Read if the button was pressed
      buttonState = digitalRead(BUTTONPIN);
      if(!buttonState) setMode();
    Thats about it. Now we just output some text to the serial/USB keyboard interface and redo this, forever (or till the batteries run out).

    Have a look at the code and let me know if there is something that needs to be qualified. I have still some things in mind I want to change on the code, so have a look at the repository now and then!

  • MQ135 Arduino library

    Georg Krocker01/01/2015 at 14:57 21 comments

    This is the first of two logs about the software needed for the SniffingTrinket project. Because I guess that a general Arduino library for the MQ135 might be of use for other projects, I decided to split the software in a dedicated library and a sketch specifically for the SniffingTrinket. So, this is solely about the MQ135 lib, which, btw. you can find in my GitHub.

    First, some theory: My interest in those cheap gas sensors was sparked by a video from Ben Krasnow who takes a look at a cheap breathalyzer with a very similar sensor. He links a paper in his blog post that goes into the theory of the operation of these sensors. In short, they consist of a heated piece of tin dioxide (doped with other stuff) that changes resistance as it reacts with the ambient gas (the heat accelerates the chemical reaction). There are several versions of these sensor, sensitive to several gas types. However, no sensor material is sensitive to a single gas only! I did some more research and found in principle two sensor of immediate interest to me: The MQ135 for "air quality" and the MQ811 for CO2. The MQ811 is much more expensive (30$ compared to 3$).

    The datasheet claims that the MQ135 is sensitive for CO2, Alkohol, Benzene, NOx, NH3 and the Fig 3 shows the change in resistance depending on the concentration of these gases in the ambient air in ppm (of the total gas volume). It turns out the the general sensitivity is the roughly same for all the gases. This is where you think: Wait a minute! CO2 is the 4th most abundant trace gas in the earths atmosphere with about 400ppm concentration (N2, O2, and Ar are on place 1-3). All of the other gases the sensor detects are much less common than CO2 and luckily so, as they are harmful. This means, in a normal atmosphere the sensor mostly detects CO2 and with the right calibration we can use it as a cheap replacement for the MQ811 (which by the way is also sensitive to other gases). Turns out, somebody already hat a go at this: I will leave you with great explanation of David Gironi for the details, but mostly he just extracts data from the figures in the datasheet, throws some math at the problem and cross-checks the results with a different kind of sensor for CO2.

    The Library I have written basically just implements his approach for the Arduino. It's pretty easy to use. Copy it to your Arduino library folder and put

    #include "MQ135.h"
    MQ135 gasSensor = MQ135(ANALOGPIN);

    to your sketch. ANALOGPIN is the ADC input for the sensor readings (refer to the post with the SniffingTrinket schematic for explanation).

    Before you can use the sensor, it has to be calibrated. For this, connect the sensor to your circuit and leave it powered on for 12-24 h to burn it in. Then put it into outside air, preferably at 20°C/35% rel. hum. (humidity is not so crucial). Read out the calibration value as such

    float rzero = gasSensor.getRZero();

    Wait until the value has somewhat settled (30min-1h). Remember, this is an ADC measurement so you might not want to wait some time between reading the sensor and also do some averaging. Once you have determined your RZero, put it into the MQ135.h. Note: Different sensors will likely have different RZero!

    #define RZERO 76.63

    Congrats, you have calibrated the sensor and can now read the CO2 ppm value in your sketch

    float ppm = gasSensor.getPPM();
    The library also provides functions to apply the temperature/humidity correction that is shown in Fig 4 of the datasheet, but I do not trust the datasheet there, so this should not be used for the moment.

    If you want to know more, look at the code. I tried to make it very readable and self explaining and provided lots of comments. If you do not understand something, ask: I will happily explain it.

  • Power Supply

    Georg Krocker01/01/2015 at 13:52 0 comments

    The contest comes to an end and I am tying up some loose ends - one of them the power supply.

    The Sniffing Trinket is intended for indoor air quality monitoring and with this in mind as well as the knowledge that USB plugs are a common sight everywhere these days, a USB port or wall plug is probably the first choice for the power supply (come on, even most cars now have a USB power supply).

    However, as this is not truly EDC and there might be situations where you want to monitor the air quality and you don't have a USB power supply, there is also an alternative battery power option.

    Instead of designing my own solution I decided to go with a module you can buy pretty cheap: Just put "5V USB step up" into ebay or alibaba or any other site and you get those modules for about 1 Euro (1.5$) in single quantity delivered. You can't build something like that cheaper yourself. These modules take anywhere from 1V to 5V input and put out 5V with up to 600mA - perfect to power your little gadget. I haven't tested them properly but I suspect (from my own painfull experience with step-up converters) that they are not that efficient - but they should be good enough to power the SniffingTrinket for a couple of hours from 2 AA batteries. Additionally, the modules are small, about the size of a USB connector. So here is how to build one:

    You need

    • A cheap chinese USB 5V step up converter module
    • A battery holder for 2 AA cells (+batteries, obviously)
    • As I used a holder that conveniently outputs to a 9V clip I needed a matching clip for connection, otherwise some wire

    Construction is pretty simple. Just solder the red wire from the battery clip to the + pad on the step up converter board and the black wire to the - pad (if you just use wires, connect them to the battery holder with the correct polarity). Connect the clip to the battery holder. Put in the batteries. I additionally glued down the step up converter board to the battery holder.

    You can now connect the SniffingTrinket via a USB cable. I only have very long and stiff ones (therefore you can't see the whole cable), but you can get a smaller, more flexible one.

    Alternatively, you can also desolder the bulky full size USB connector from the converter board, cut the board a little bit and run you own wires to the Trinket.

    Congratulations, you can now monitor the air quality in the mines of Moria!

  • PCB Giveaway

    Georg Krocker12/29/2014 at 08:06 0 comments

    Hey all,

    a couple of small updates from me. I have been heavily working on the project for the past couple of days and fighting with some annoyances. Good news is, I have them mainly fixed and at the moment I am preparing a "first (stable) version" of the project to be ready for the end of the contest. However, development will go on after that (although maybe somewhat slower).

    I uploaded the first bunch of files containing all the hardware files (schematic, Gerbers) needed for KiCad and the MQ135 arduino library I created (more on that later) to github. The source code for the trinket will follow soon. The links to the repository are on the main project page on the left side.

    As sort of a late christmas present to people interested in the project I decided to give away some of the Rev 0 PCBs I ordered . I got 10 PCBs made of which I won't need all for prototyping, so I decided that 5 of them are up for grab on a first come - first serve basis. There are some caveats, read them carefully:

    • The Rev0 PCBs have a couple of issues that I already discusses as well as a some I haven't discussed yet. They can be made to work but are not representing what I intend for the "final version" of the project (may this ever happen). Those PCBs are intended for people wanting to experiment with the project and (hopefully) giving some input.
    • It is understood that they come without any Warranty, Liability and so on...
    • The PCBs are free of charge but I will collect postage costs upfront from you via Paypal. I will send them as normal letter and charge you whatever the German postal service is charging me. I am not responsible if they get lost or anything else: If they arrive, fine, if not, bad luck. UPDATE: I looked up the shipping costs and it seems that the German postal service charges about 1.20 US$ for a standard international letter to pretty much any country. Shipping times vary (they quote 2-5 days to the US but I doubt that).
    • SMD soldering skills are required.
    • You just get the naked PCB (no components!).

    Should you wish to get one PCB under those circumstances, write me a PM with your address and I will send you a quote with the shipping costs and my PayPal account. Once I get the money, I will post your letter.

    Meanwhile have all fun with the remainder of the contest!

  • Schematics Documentation

    Georg Krocker12/24/2014 at 11:43 0 comments

    A quick follow up on the schematic of the project. I thought I do some documentation so that people can follow what I have been doing. I will quickly go through the different parts of the schematic step by step and add comments where necessary.

    • The gas sensor:For the current version I use a MQ135 sensor. This sensor is sensible to various gases (Benzene, Alkohol, NH3, CO2) and marketed as an air quality sensor but in a normal environment it is in principle only sensing CO2 (more on that in a later post). The sensor has an internal heating element connected to the H+ and H- pins. The heating of the sensor draws about 130mA of current, which is quite a lot and the sensor has to be continuously heated during operation. This might not be necessary or desirable in some applications, therefore Q1 acts as a switch for the heating of the gas sensor. Q1 can be controlled by the trinkets D4 pin and a pulldown resistor (R3) ensures proper operation. Q1 is a standard logic level FET, other types should work as well if they can handle at least 200mA switching current and have a low on resistance. The gas sensor changes its internal resistance between the pins A and B depending on the amount of eg. CO2 in the air. Together with R4 it constitutes a simple resistor divider, that is read out via the trinkets A3 input. There are other gas sensors with the same pinout and footprint for various gases, Depending on your application you may switch to a different sensor, they should all work but you may have to adjust R4 accordingly.
    • The temperature/humidity sensor:The DHT11 sensor has a digital output, so the schematic is simple: Hook it up to power and ground and the data pin to the trinkets D5 GPIO and you are fine. R6 is a necessary pull up resistor for the data pin and C4 a bypass cap for the power supply.
    • The RGB Led output:The main output of the project are three WS2812b RGB Leds, one each for Temperature, Humidity and CO2. The user can give lower and upper limits for these measurements, the leds are green if they are within range or blue/red if below/above the limit. The color output is continuous (ie. there is a smooth transition from blue->green->red depending on the actual measurement). The WS2812b variant has four pins, supply voltage and Gnd, Data in and Data out. The data is fed to the Leds by the D6 GPIO of the trinket, R5 is for protection and proper operation an C1-C3 are bypass caps.
    • Additional IO ports:Four additional IO options are available. The pushbutton will be used to switch between different modes of the software. The buzzer output can be used for a piezo or to switch something depending on an alarm that can be preset in software (eg. open a window if air is bad). The serial interface/I2C interface can be used to connect to a PC, display, ESP8266 wifi module or whatever you have in mind.
    • Connection to the trinket:This represents the headers going to/coming from the trinket. Just collects all the signals. The MQ135 heater draws to much current for the trinkets LDO regulator, hence it is connected directly to the BUS pin of the trinket (ie. the USB connector).

    The whole hardware layout is done in KiCad and licensed under the CERN open hardware license v1.2. I will upload the files on github in the upcoming days so they can be accessed by everybody.

  • Good News

    Georg Krocker12/23/2014 at 21:09 0 comments

    This is just a quick update: The boards have arrived yesterday and I had a first quick look. So far I have spotted just two small problems that can be fixed:

    • The footprint for the MQ135 is a bit small. It's a tight fit but the sensor can be soldered to the board. I will fix this in a future version of the board.
    • The ground pin is not connected directly to the ground plane but only via a small trace - too small for the current of the gas sensor. The good news is that this can be fixed with 2cm of wire and I will also change this in Rev 1 of the board. No idea why I have not spotted that during the layout ;)

    I have checked most of the other connections and not found an other problems but so far I have not tested the boards with all of the components. That will have to wait for another day or two.

    Anyhow, I'm very happy with the result, considering that this is my first PCB. I also want to mention that I'm very pleased with the quick service of ITEAD for the manufacturing (not so with DHL who delivered the boards, but that is another story).

    In the meantime I have some more work to do and wish you all a merry Christmas! As a present I will leave you with two photos of the actual boards.

  • Boards

    Georg Krocker12/15/2014 at 16:08 0 comments

    So, last week I spend my time finishing the board layout and ordering the boards. The boards are currently manufactured and if all goes well I will have them before Christmas. Just that you can see how the boards will look like

    For some reason, KiCad only renders the boards rectangular, but thy have rounded edges and a little cutout on one side.

    Some comments on the design choices I made during the layout and how they affect the project:

    • Regarding the sensors, I decided to go with the DHT11. The other members of the DHT family (e.g. DHT22) are larger and will not fit in the position I intend them to go on the board, i.e. the bottom sie between the pin headers of the trinket. However, they can still be used but have to be mounted standing on the top side.
    • For space constraints I decided to leave an additional temperature sensor out for the moment. There is a pin header on the board where a DS18S20 can be mounted if this is wished by the user but for the default, the temp sensor in the DHT11 will be used.
    • There are two pin headers on the board, one for I2C, where an optional I2C display can be mounted and one for a serial connection to either the PC or to a wifi serial module (ESP8266) if wished. Those are the additional output devices I promised. However, software wise they might not make it to the first version I intend to have ready for the end of the contest.
    • I scaled down the resistors and caps to 0805 for space constraints.

    Some lessons I learned for the next rev of the board:

    • The switch will be surface mount in some future version, I just did not have time to look for/order an SMD version - through hole just takes to much space on a tiny board like this.
    • Same goes for the humidity/temp sensor. Maybe I will search for an SMD version of that as well.

    Thats all for now. Let's cross our fingers that everything goes well and I will have the boards soon and did not make any terrible mistakes. Meanwhile I will work on the software part.

  • Schematic and KiCad fun

    Georg Krocker12/08/2014 at 16:47 0 comments

    Hey there, I'm back and still living ...

    The last couple of days I was finishing off with the schematic and starting out with board layout. Here is the (almost) finished schematic:

    Small details might still change as I'm finishing up the board layout if I run out of board space or have tons of board space left. A couple of comments are in order:

    • I added a transistor to the heating element of the gas sensor to switch of the heater if necessary because it draws quite some amount of current.
    • Some little bypass caps got added here and there.
    • I added an external port for the serial interface and an I2C port for additional output possibilities (Hint: Think I2C display).

    Concerning the board layout, I have so far finished all the footprints and the basic outline of the board. Next up is placing of the components and routing. I have not yet decided on the size of the caps and resistors, I will try 0812 for easy hand soldering but might need to get down if space is rare (as it is, it seems). More on that soon - I plan to send off the board to be manufactured latest end of the week. So far I stick to my initial plan, yeah!

    Some note before I part: KiCad suck. Honestly, it provided me with the worst user experience EVER over the weekend. Once it runs its fine, but finding a version that has everything running is a major pain. I'm no noob when it comes to compiling your own software, but it took me five hours using three operating systems (and two flavors of linux) to find a somewhat stable version. Really KiCad - this is the best you can do?

  • (Almost) A rats nest

    Georg Krocker12/03/2014 at 20:07 0 comments

    Just some small update: I have build up the circuit on a breadboard and tested all the components in software. So far I'm pretty satisfied with the results and think I will go on with this. A schematic will follow soon, so far just a pretty picture of the board all wired up and with blinking LEDs...

    BTW, I had some thoughts about the power supply for the project and came up with some very nice idea ... more about that will also come soon.

View all 11 project logs

  • 1
    Step 1

    Get together all your parts (see BOM). You also need a PCB: Download the Gerbers and get them produced yourself (at least for the moment). Note that the PCBs have as of now (Christmas 2014) a couple of (fixable) bugs. Alternatively, you can build the project on a breadboard or perfboard - use through-hole-components then. If you use a PCB, make sure to read an SMD soldering tutorial and use the right tools.

  • 2
    Step 2

    Start by soldering the three 100nF caps on the topside of the board (C1,C2,C3).

  • 3
    Step 3

    Solder R5, this is a 270 Ohm resistor (you may also use another value between 150 Ohm and 300 Ohm).

View all 14 instructions

Enjoy this project?



Fidel wrote 03/24/2017 at 09:41 point

I think you should use a Bosch bme280 for more accuracy,great project by the way

  Are you sure? yes | no

wostem wrote 11/07/2016 at 20:17 point

very interesting ... can you send the complete code of the project  ???


  Are you sure? yes | no

sachlj36 wrote 08/14/2016 at 08:42 point

I used your library. It is the result of 0.04 ppm okay? I use MQ-135 for Arduino UNO.

  Are you sure? yes | no

UnreliableMongoose wrote 12/02/2014 at 23:33 point
How about Radon too?

  Are you sure? yes | no

Georg Krocker wrote 12/03/2014 at 20:15 point
In principle yeah, not a bad idea. I also have some ideas how to detect the alphas from radon efficiently but this clearly is beyond the basic scope for the project. Once I finished the first version of the board however I will look into that.

  Are you sure? yes | no

Adam Fabio wrote 11/30/2014 at 07:39 point
This is a great idea! Your own personal air quality monitor. Detecting poisons like carbon monoxide could be a lifesaver while driving!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates