I was clearing out my toolbox of gubbins the other day and discovered an inexpensive CCS811 air quality sensor I’d bought ages ago and never done anything with. These are small sensors that measure Volatile Organic Compounds (VOCs) and can be used to give an approximation of CO2 levels in the air. They connect to microcontrollers using an I2C interface. You can read the data sheet here.
There are libraries to run them with Arduinos, of course, and here’s a port to MicroPython: https://github.com/Notthemarsian/CCS811. So should be easy to get it working with a BBC micro:bit, no? Well I had to do a bit of tweaking, but I think I have it working.
The micro:bit’s version of MicroPython lacks the readfrom_mem and writeto_mem instructions that this code relies on. Luckily I found this excellent blog post which explains some ways round this.
The other difference is that on the micro:bit, the I2C clock and data pins are fixed on pins 19 and 20, so there’s no need to pass the pins to the supporting module.
I’ve also assumed that the I2C address of the sensor is 90. I discovered this address by just running a program like this on the micro:bit with the sensor connected.
i2c.init() print(i2c.scan())
I’ve probably committed some hideous crimes against Python, but by modifying the Notthemarsian code, I seem to have it working.
Here’s what I used:
- a CCS811 sensor with some pins soldered on
- a BBC micro:bit (V1 or V2) and a micro USB lead to connect to a computer
- a breakout board that exposes the I2C pins – I used a Monk Makes one, but you could also use ones by Adafruit, Kitronik or Pimoroni, just make sure they have the I2C pins broken out as not all do.
- jumper leads to attach the sensor to the breakout board – I used 4 female to female jumpers
- a way of attaching the sensor’s WAK (wake) pin the GND on the micro:bit – I used a female to male jumper wire and a crocodile clip lead, but there will be far more elegant ways than this
- A computer with the micro:bit Python editor in a Chrome or Edge browser window, like https://python.microbit.org/ or https://python.microbit.org/v/alpha
Connect the pins like this:
sensor micro:bit ----------------- VCC 3v GND GND SCL SCL (pin 19) SDA SDA (pin 20) WAK GND INT not connected RST not connected ADD not connected
Then flash this hex file on to your micro:bit (right-click and save link or save target). If you want to examine the contents, you can just drag the HEX file into an online micro:bit Python editor. You’ll see two files, main.py and the module CCS811.py. You can also add those files separately, but it’s easier just to use the HEX which you can flash straight onto a micro:bit, or drop onto the online Python editors.
Then you need to open a serial console. Make sure you’re using Chrome or Edge. In the current regular Python editor, click on Connect and then Open Serial. In the Alpha editor, which has a serial console in the same screen as the code editor, click Connect and Show serial. You could actually use any serial console to read the data, such at the Chromelabs online one.
You should see data from the sensor scrolling in the screen, once per second. Huff and puff on it, and you’ll see the CO2 number rise. I waved a bottle of hand sanitiser at it, and it went crazy!
Let me know if you find this useful and get it to work. What would you use it for? How could you make use of the data?
Add an OLED display
This version of the project adds an OLED display, which makes the micro:bit air quality sensor self-contained. I left it running all day and found the eCO2 levels rose from around 1400ppm at lunchtime to over 5000 by 6pm. Opening a door to the outside had an immediate effect, the levels dropping very rapidly back to around 1500ppm, which does suggest simple ventilation like opening a door or window to the outside has a dramatic effect on air quality.
In addition to the micro:bit, breakout board and CCS811 sensor, I used a standard cheap 128×64 I2C OLED display, a tiny breadboard and a few jumper wires. The display and sensor should be available for just a few pounds or dollars from the usual suppliers. I just daisy-chained the OLED onto the same I2C pins as the air quality sensor.
This version of the project also shows how it’s possible to attach more than one I2C peripheral to a micro:bit. The code assumes the OLED display has an I2C address of 60 (0x3C) which luckily doesn’t clash with my air quality sensor’s address of 90 (0x5A). If you make this and have problems, do check the I2C addresses of your devices and tweak the Python code accordingly.
You can download the HEX file from here (right click and save link or target). The HEX contains all the Python modules needed to make the OLED display and air quality sensor work. Plug your micro:bit into your computer and drag and drop the HEX direct on to the MICROBIT drive. You can also drag and drop the HEX file on to the regular or alpha Python editors so you can examine and edit the Python code.
Like the previous project, this one also prints data to a serial console over USB, so you can monitor it on a computer as well. It might be neat to make this also send data by radio to another micro:bit which can log data, work out averages over longer time periods, maximums and minimums etc.
Simple air quality data logging
If you want to log the data in a really easy way, you can be a bit sneaky and use this microPython program with the MakeCode data graphing tool. Flash either version of the program, with or without the OLED display, to your micro:bit and modify the serial print lines so they look like this:
print('eCO2:%d' % (s.eCO2)) print('TVOC:%d' % (s.tVOC))
You can then connect the micro:bit to a computer, open a new MakeCode project and click on ‘show console Device’ under the simulator when it appears. You can then view data in real time, and also download it as a CSV file you can import into a spreadsheet like Excel:
Buy a ready made air quality sensor
If you don’t want to mess around with soldering, breadboards, jumper wires and fiddling with software, there are several ready-made micro:bit accessories that you can just attach to a micro:bit.
The Monk Makes Air Quality Kit has an eCO2 sensor and comes with everything you need to get going including a loudspeaker, and an excellent book of instructions and sample projects. This also lets you write code for it in MakeCode blocks as well as Python, making it accessible for younger students. This is a well-designed and tested product with great attention to detail in its packaging and documentation.
The Kitronik Air Quality and Environmental Board for micro:bit also includes a built-in OLED display and a real time clock for data logging. I’ve not tested this product but it can be programmed using an extension for MakeCode blocks and as well as eCO2 it measures temperature, pressure, and humidity. The MakeCode extension for their OLED display is excellent, so I have high hopes that the software that supports this very full-featured accessory is as good.
Hello,
thanks a lot for your post. I am trying to reproduce your work (I have the same things), but it doesn’t work. Your CCS811.py is not the module. Is it?
Thanks a lot. I am getting desperate with this sensor.
Best wishes,
Araceli
Hi Araceli!
Have you tried downloading the first HEX file I mention and loading that in the micro:bit editor, eg the new beta editor https://python.microbit.org/v/beta ? (It’s at https://raw.githubusercontent.com/blogmywiki/microbit-CCS811/main/CCS811_air_quality.hex ) Then you should see the main.py and the CCS811.py file listed under ‘project’.
Or you can find the files I mention here: https://github.com/blogmywiki/microbit-CCS811
Hope that helps and good luck!
Hi!
Thanks a lot for your answer. It looks at I have problem with the address and later with hardware_id. When I run i2c.scan the number I get is 88. I change 90 for 88 and the file 37 doesn’t work and I don’t know the problem.
Thanks a lot for your help.
Araceli
I will try the new tips you have said to me.
Hi Araceli, yes there are lots of ‘variables’ here with different hardware types and addresses. Good luck!
Thanks a lot.