I spent too much time in too small, too busy meeting rooms, discussing about who knows what and too many times I felt the oxygen was letting me down. Was there too little oxygen? Or too much carbon dioxide? Or still something else? Time to find out and build my own CO₂-meter.
On Sparkfun I found a CCS811 air quality sensor on a breakout board. It can not only measure the carbon dioxide (CO2) level in the air but also the level of so-called total volatile organic compounds (TVOC). It has an I2C interface, so you must use it in conjunction with a microcontroller. But the CCS811 is a wonder on its own, because it contains a microcontroller in itself to pre-process the data. The catch is, that the CCS811 can only tell the CO₂ and TVOC by any accuracy when you tell it the temperature and humidity.
So we need a second sensor in order to find out temperature and humidity and Sparkfun has a solution for that too: the BME280, which not only measures temperature and humidity, but also air pressure. This one is also available on a breakout board and also uses a I2C interface. As a matter of fact, the wires of the two sensors can be connected in parallel on the I2C interface. The can be distinguished because they use a different address on the bus!
What else to throw in? An ATMEGA328 microcontroller, a 36 mm, 128×128 TFT display based on the ST7735 and a project box! The display was lying around in one of my drawers and Adafruit supplies drivers for it.
In the next steppenplan I will describe how I started this project with an Arduino Uno, then got rid of all the unnecessary stuff on an Arduino and moved to just the ATMEGA on a pcb.
Step 1: Use an Arduino, connect the CCS811, the BME280 and the TFT display
The tricky bit here is that the Arduino runs on 5 V, whereas the sensors just need 3.3V. This means not only that the supply voltage is different, but we must also take care of the signal wires. So we need and 78L33 for the 3.3V supply voltage and two level shifters based on 2N7000 for the I2C wires SCL and SDA. And this is what the schematic looks like, when it’s hand-drawn:
My CCS811 breakout board has a WAKE connection (shown as Reset in the drawing) which should be grounded. The BME280 on the other hand has two pins that must be connected to Vdd (+3.3V).
An Arduino sketch, based on the sketches or Sparkfun & Adafruit combined, and we have the first working prototype on a breadboard (forgot to take a picture of that, sorry!)
Step 2: Get rid of the Arduino, use a bare ATMEGA328
One of the nice things of the Arduino Uno is that its ATMEGA328 is in a socket. So we can just take out after programming and use it on a breadboard pcb. The only thing we need to add is a 16MHz crystal and a few capacitors:
Step 3: Everyone on reduced diet!
We can run the ATMEGA328 on 3.3V, it doesn’t require 5V! And as it turns out, also the TFT display runs perfectly well on 3.3V. Even more so: even on 3V all the components are within specs, so we can run the whole thing on two 1.5V batteries.
Step 4: The fall of the crystal (and a few resistors)
There’s two more things we can improve. The resistors on SCL and SDA can be removed if we enable the pull up resistors in software. This can be done in the Arduino sketch. The other thing is the crystal. Because this application is not timing critical, we can run the ATMEGA from its internal RC oscillator at 8MHz. It makes is slower, true, but that doesn’t really matter here. The way to do this, is program a “fuse”. Connect a programmer to the MISO, MOSI, SCK and Reset pins of the ATMEGA. I use a cheap USBASP programmer (less than €2 on Ali) and give the following command:
avrdude -p m328p -c usbasp -B 8 -U lfuse:w:"0xE2":m
Now the ATMEGA is programmed to use its internal oscillator at 8MHz and we can remove the crystal and its caps:
Step 5: Soldering!
I though about designing a pcb and having it produced, but it turned out a be such a simple diagram, that I found I might just as well build it on a prototype pcb. The photo below shows what it looks like (already in the enclosure that I made in step 7). Note the two beak-out boards for the two sensors (the purple and black things on the left), they are stacked together on top of each other. The purple breakout board contains the CCS811 and is a little bit larger than the breakout board for the BME280. Most of the pins line up perfectly, so it’s very easy to interconnect them in this way. And it is important that the two sensors are as close as possible to each other, because the temperature and humidity readings of one are used to compensate the measurement of the other.
By the way, these aren’t the original breakout boards from Sparkfun, they are cheap clones with slightly different pinouts. But they still contain the original sensor chips, at least that’s what I assume…
I wanted to make a tidy drawing for this blog, so as an experiment I installed Microsoft’s DrawingBoard Pro. It is supposed to be a circuit drawing/editing program especially for prototype boards and can be downloaded from Microsoft’s store. I have no idea why they put the word PRO behind this ***ware, because what does PRO mean? “PROduced in a few hours”? “PRObably the dullest tool in the shed”? Anyway, this was the first and last time I used DrawingBoard and this is what I drew:
Note that we’re looking at the bottom of the components, so pin 1 of the ATMEGA is top left. Nevertheless, I was confused myself and put the sensors on the opposite side of what I designed and now the pcb lies at an angle. Ugly, my fault.
Step 6: Design an enclosure
I decided to re-use an old enclosure, because it already had a battery compartment for 2 AA cells, which would come in handy. It’s the grey thing on the photos. But then the top lid contained so many holes in the wrong places, that I decided to 3d-print an enclosure of my own design. That’s the bright blue thing. I used Google sketchup, Cura and an Anet A6 3D-printer. Great exercise in 3D-design.
The tricky bits were the pillars for screw holes, the vent holes, the notches for the power switch and the general sizing of everything so that it would fit exactly on the existing underside. Well, I had to redo it several times before it fitted nicely…
And there is the final product: the CO2 meter-in-a-box. It shows temperature, air pressure, relative humidity in %, CO2 level (in parts per million) and the TVOC level. A CO2-level of 400 is normal for outside air (it used to be lower, a hundred years ago and before the industrial revolution, but that’s a different story) and is the minimum the CCS811 can measure. When I held the meter over an open can of soda, the value quickly rises to 4000 or so. The maximum is 8192ppm.
Then it shows the Total Volatile Organic Compounds (in parts per 1 000 000 000). Alcohol is a VOC, so when I held the meter near an open can of beer, it rose quickly towards its maximum value of 1187ppb.
I hoped you liked this process, starting with an Arduino Uno and a few break-outboards and ending with a showable prototype. There is still some room for improvement. I didn’t do the last step: get rid of the breakout boards and design a pcb. Also the way the display sits in the enclosure could be improved.