English

Motivation

Recently I have been wondering why we get drowsy when we work for a while in enclosed rooms. I always assumed it’s due to a lack of oxygen and searched for a method to measure the oxygen concentration in the air. After reading a few pages about people with similar ideas, I quickly learned that it is not the lack of oxygen, but rather the build-up of carbon dioxide (CO2) that creates a lack of focus, drowsiness and at some point even health issues.

The CO2 concentration in the air is measured in “parts per million” (ppm), which is something like the average number of carbon-dioxide molecules per million molecules. The limits of CO2 concentrations and their effects on humans differ slightly depending on the source, but negative effects are expected at about 1000 ppm. Health issues arise at about 2000-2500 ppm. Just as a quick reminder: The “air” is mostly nitrogen (N2, ca. 78%), oxygen (O2, ca. 21%) and carbon dioxide (CO2, ca. 0.04% = 400 ppm), plus some gases in even smaller concentrations [see Wikipedia]. Having 400 ppm as a permanent CO2 concentration in the “outside air” is actually quite alarming and was announced in 2016. No open window will help us get below this value anymore – climate change is real, at this magnitude man-made and extreeemly dangerous, so we have to deel with eet.

Measuring

Getting a sensor to measure CO2 in the air is a little on the pricey side. The sensors should be self-calibrating to be able to give accurate readings (unless you are able to calibrate them yourself). A lot of the cheaper sensors are not calibrated and can only give estimations or relative changes in CO2 concentration. Self-calibrating sensors are available from about 60-80 EUR, depending on the vendor. Examples are the Senseair K30 Sensor (just the sensor) and the TFA Dostman “AIRCO2NTROL MINI” (ready-to-go standalone device with a display).

Since the price is rather high for a personal side project born out of curiosity, I decided to go with the latter device, which I could also use in other environments (e.g. my office or our lecture hall, since it really gets stiffy in there at times). The device is powered by a micro-USB cable, which also transfers the data.

Setup

My hardware setup is basically just a Raspberry Pi connected to a router (It doesn’t matter if it’s connect via network cable or WiFi) and the CO2 Monitor connected on one of the Raspberry Pi’s USB ports. In the following picture you can see my setup:

Raspberry Pi + CO2 Monitor setup

Software / Installation

Getting the data is a little tricky, there is a software tool for Windows, but I wanted to get the data on my Raspberry Pi.

I will spare you the description of my trial and error process – what I found was this “co2mon” GitHub repository. Using the following commands worked flawlessly on Raspbian Pi (the Debian based Raspberry Pi OS).

Please note: Depending on your user permissions you may have to run these commands as root/super-user, therefore run them as “sudo”.

apt-get install cmake g++ pkg-config libhidapi-dev
git clone https://github.com/dmage/co2mon
cd co2mon
cmake .
make

For convenience I also moved the binary to the proper folder:

mv ./co2mond/co2mond /bin/co2mond

In order to get the values you simply run the command:

co2mond -u

This basically returns the data the sensor is sending via the USB cable:

CntR    839
0x4f    7240
0x52    10183
0x41    0
0x43    3411
Tamb    23.5375
0x6d    1925
0x6e    25103
0x71    840

One of these values is the CO2 concentration in ppm (CntR) and another is the temperature in degrees Celsius (Tamb).

To have a more Linux-y and, hence, easy access to those values, we can run the co2mond tool as a daemon and “store values from the sensor in datadir” (to quote the co2mond –help output).

co2mond -d -u -D /var/co2

This will continuously offer the sensor values in 3 files:

  • /var/co2/CntR = CO2 concentration in ppm (Integer number)
  • /var/co2/Tamb = Ambient temperature in °C (Decimal number / Float)
  • /var/co2/heartbeat = The Unix timestamp of the last sensor reading (Integer number)

And there we go. These files can be simply read out using your favorite programming language, or simply use cat:

cat /var/co2/CntR /var/co2/Tamb /var/co2/heartbeat

Next Steps:

In the next post I’m planning to describe how to use Python 3 with Flask and Bokeh to have an interactive plot of your ambient data, accessible via browser from anywhere in your network. It looks something like this (I also have a DHT22 temperature and humidity sensor, as you saw on the picture above):

Rasbperri Pi Ambient Sensor Plot (v1)

Legend:

  • Green = CO2 concentration in ppm (most right scale)
  • Red/Orange = Two different temperature sensors in °C (left scale)
  • Blue = Humidity in % (first right scale)

 

Finally, I have a little thing to write about.

As I am learning Turkish I have to regularly write letters (or characters) that are part of the Turkish alphabet, but are not present in my preferred keyboard layout (in my case German).

In Turkish these letters are:  ş Ş ğ Ğ ç Ç ı İ

So I was looking for convenient solutions to easily and fluently write these letters and stumbled upon AutoHotkey, which is a quite extensive tool which lets you do a lot of stuff. Among other things you can create new key mappings, or overwrite your current keys. You can even say: “Every time I write ‘hlelo’ auto correct to ‘hello’.”.

As I said, it’s quite extensive, but that’s not the reason we’re here.

In my case I wanted to map the Turkish characters on [ALT GR] + <Letter>, for example:

[ALT GR] + [G] will turn to ğ

[ALT GR]+ [I] will turn to ı

[ALT GR] + [SHIFT] + [I] will turn to İ

You get the idea.

In order to do this, we will create an AutoHotkey file (*.ahk), which we can access when we run AutoHotkey, right click on the tray icon (in the lower left corner in Windows), and select “Edit This Script“. Here we can use some code to do our bidding.

In this particular case we can use the following code, where the + stands for [SHIFT], the <^> stands for [ALT GR], and the s for… well, [S]. We then tell the program to send the letter Ş if this particular combination occurs and let it return to its usual duties.

+<^>!s::
{
  Send {Ş}
  return
}

If we want to do the same for the smaller case character, we simply remove the +, as you can see here:

<^>!i::
{
  Send {ı}
  return
}

It is important to note that the configuration file has to be saved using a Unicode compliant encoding, for example UTF-8. The Windows Notepad is able to do that, if you select “Encoding: UTF-8” in the “Save As” dialog.

After saving the file, you might have to select “Reload This Script” in AutoHotkey, to make it uses the new version.

You can find the whole file with Turkish characters and Scandinavian characters (with bindings a-å, ä-æ and ö-ø) here: http://pastebin.com/s8u21Ftt

Please note that the bindings might make more sense on different keys, depending on your default keyboard layout.

I hope this helps someone at some point.

PS: I don’t do April Fools’ Day!