# HomeyDuino CO2 sensor

**URL:** <https://community.homey.app/t/homeyduino-co2-sensor/20410>\
**Category:** Devices\
**Created:** [November 8, 2019, 4:27pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410 "2019-11-08T16:27:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [November 8, 2019, 4:27pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/1 "2019-11-08T16:27:45Z")

</div>

Just for who might be interested.

I was already looking for a long time for a good CO2 meter but either they were too expensive or too unreliable. So finally I decided to create one myself with the help of Homeyduino. The sensor itself is from Senseair (S8, auto calibrating), a reliable company when it concerns these type of sensors. The sensor is connected (via UART) to a TTGO ESP32 with display so the CO2 value can also be read directly. When the CO2 value exceeds 1000 parts per million I will be notified by my Google Home.

I must admit the enclosure looks horrible but by the lack of some good tools and patience it became what it is. At least it works perfectly well.

 ![HomeyCO2](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/8/f/8fbb7cad0b8eb3363f54db06af41aa8e1204ad86.jpeg)

---

<div class="post-metadata">

**Author:** ![Wilfred\_Greven](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/wilfred_greven/32/13070_2.png) [@Wilfred\_Greven](https://community.homey.app/u/Wilfred_Greven)\
**Post date:** [November 9, 2019, 11:49am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/2 "2019-11-09T11:49:02Z")

</div>

Hey Lars,

Nice one! Could you give a little more information how you did this?

Thanks in advance,  
Wilfred

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [November 9, 2019, 12:45pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/3 "2019-11-09T12:45:32Z")

</div>

Cool! I also planned to go that way, bought a senseair s8 sensor, but never put it together. Have now three Netatmo healthy home coaches as CO2-sensors which is connected through Homey to control my roof fan.

But now I can just copy your code, hehe?

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [November 9, 2019, 12:56pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/4 "2019-11-09T12:56:58Z")

</div>

Hi Wilfred,

The device was constructed with:

- TTGO-T-Display ( [https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/README.MD](https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/README.MD) +/- [https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/README.MD](https://github.com/Xinyuan-LilyGO/TTGO-T-Display/blob/master/README.MD) 6 Euro).
- [https://senseair.com/products/size-counts/s8-residential/](https://senseair.com/products/size-counts/s8-residential/) (40 Euro bought on Ebay/MP)
- Enclosure (3 Euro)
- Beeper (1 Euro)
- Switch (0,25 Euro)

The code was flashed to the ESP32 with the Arduino IDE. The libraries used are: TFT\_eSPI and HomeyDuino. The TTGO communicates via UART/Serial2 to the Senseair sensor. If you’re handy with Arduino programming and soldering you can easily do it yourself. Most of the code I just borrowed from some samples and adapted it for my own purpose.

The total costs were about 50 Euro which is not much compared to what is available on the market. The sensor was most expensive but I wouldn’t recommand cheap Chinese rubbisch. They are not very accurate, brake easily or are not auto calibrating. Maybe there are some good ones but I haven’t seen any.

With Homey Insights every measurement is logged which can be seen in some nice graphics. When the CO2 values become too high the ventilation system is switched on automatically which prevents me from hallucinating (only when I am not on other stimulants of course) and other nasty things.

If you want I can send you the C++ code.

---

<div class="post-metadata">

**Author:** ![Wilfred\_Greven](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/wilfred_greven/32/13070_2.png) [@Wilfred\_Greven](https://community.homey.app/u/Wilfred_Greven)\
**Post date:** [November 11, 2019, 5:17pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/5 "2019-11-11T17:17:51Z")

</div>

Hi Lars,

This is unfortunately a little too complex for me.

Greetings,  
Wilfred

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [November 11, 2019, 7:28pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/6 "2019-11-11T19:28:51Z")

</div>

You don’t feel like experimenting with the VOC-sensor BME680. Seems to be the best VOC sensor, but the issue seems to convert the resistance value you get to ppm.[https://www.bosch-sensortec.com/bst/products/all\_products/bme680](https://www.bosch-sensortec.com/bst/products/all_products/bme680)

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 1, 2020, 10:00pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/7 "2020-01-01T22:00:34Z")

</div>

With some help (thanks to maxxie01 on Slack) I did a Homeyduino CO2 sensor myself. Also a Senseair S8-sensor, connected to a wemos like described here [https://www.letscontrolit.com/wiki/index.php/S8](https://www.letscontrolit.com/wiki/index.php/S8).

Here’s the Arduino code if anyone is interested. This is just the code for the board (wemos) and the sensor, no fancy display.

```
/*
    Basic Arduino example for K-Series sensor
    Created by Jason Berger
    Co2meter.com

    Adjusted to Homeyduino by maxxie01/rindlerblabla
*/

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <SoftwareSerial.h>
#include <Homey.h>

SoftwareSerial S8_Serial(13,15); //Sets up a virtual serial port
                                  //Using pin 13 for Tx and pin 15 for Rx
                                    
unsigned long prevReadTime = 0;
unsigned int ReadTimeInterval = 300000; //Update interval in ms
unsigned long valCO2 = 0;
byte readCO2[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25}; 
byte response[] = {0,0,0,0,0,0,0};  

int valMultiplier = 1;
void wifi() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin("SSID", "PASSWORD");
    uint8_t timeout = 30;
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
      if (timeout<1) break;
    }
    if (WiFi.status() == WL_CONNECTED) {
      //Print IP address
      Serial.print("Connected to WiFi! (");
      Serial.print(WiFi.localIP());
      Serial.println(")");
    }
  }
}

void setup()
{
  Serial.begin(115200);       
  S8_Serial.begin(9600);    
  Homey.begin("senseair-s8");
  Homey.setClass("sensor");
  Homey.addCapability("measure_co2");
}
void loop()
{
  wifi();
  Homey.loop();
  //to check not every loop use this interval method
  if(millis() - prevReadTime > ReadTimeInterval){
    prevReadTime = millis();
    sendRequest(readCO2);
    unsigned long tmpValCO2 = getValue(response);
    if(tmpValCO2 != valCO2){
      valCO2 = tmpValCO2;
      Serial.print("CO2 ppm = ");
      Serial.println(valCO2);
      Homey.setCapabilityValue("measure_co2", (int) valCO2 );
    }
  }
}

void sendRequest(byte packet[])
{
  while(!S8_Serial.available()) //keep sending request until we start to get a response
  {
    S8_Serial.write(readCO2,7);
    delay(50);
  }

  int timeout=0; //set a timeoute counter
  while(S8_Serial.available() < 7 ) //Wait to get a 7 byte response
  {
    timeout++;
    if(timeout > 10) //if it takes to long there was probably an error
      {
        while(S8_Serial.available()) //flush whatever we have
          S8_Serial.read();

          break; //exit and try again
      }
      delay(50);
  }

  for (int i=0; i < 7; i++)
  {
    response[i] = S8_Serial.read();
  }
}

unsigned long getValue(byte packet[])
{
    int high = packet[3]; //high byte for value is 4th byte in packet in the packet
    int low = packet[4]; //low byte for value is 5th byte in the packet

    unsigned long val = high*256 + low; //Combine high byte and low byte with this formula to get value
    return val* valMultiplier;
}
```

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 2, 2020, 7:29am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/8 "2020-01-02T07:29:32Z")

</div>

![DSC_3354](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/6/1/61947f2ae74be9e63199576fd8c507ce672d2855.jpeg)  
Just finished my second version. This time in a 3D printed enclosure and a Bosch BME680 (with official Bosch library). So now I can read CO2/Temp/Humidity/Pressure/VOC/IAQ. The BME680 can also act as a smoke detector. I tried it with setting a piece of paper on fire. The IAQ readings immediately went up to over 400 (range 0-500),

 ![DSC_3375](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/7/f/7fd18cfaa3d85d02cdcba85e864d5e832fa05592.jpeg)  
One can do the (WiFi) setup via a WiFi access point to fill in the parameters for WiFi/Homey and a MQTT client. Still need to calibrate the CO2 sensor by the way.

 ![DSC_3369](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/6/2/62746823f46e58c09807f6235a0caa034c628468.jpeg) !  
[2020\_01\_02\_08.10.22|237x500](https://community.homey.app/uploads/short-url/13642jUx4SAw2mM2YHH4hJyTRe6.jpeg)  
 ![2020_01_02_08.10.22](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/0/7/075bd1d8ae37682ee5c1d0b2248f0558f54e5a46.jpeg)  
 ![image](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/7/1/719b2ad6300fcf1b321d19c23b0fd305ef8bffd7.png)

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 2, 2020, 8:15am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/9 "2020-01-02T08:15:04Z")

</div>

If you use the official Bosch library the IAQ index (based on VOC) is calculated for you.

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 2, 2020, 8:42am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/10 "2020-01-02T08:42:25Z")

</div>

Did you have to do all steps described here? Do you also got the ppb-value? [https://github.com/BoschSensortec/BSEC-Arduino-library/blob/master/README.md#installation-and-getting-started](https://github.com/BoschSensortec/BSEC-Arduino-library/blob/master/README.md#installation-and-getting-started)

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 2, 2020, 8:46am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/11 "2020-01-02T08:46:21Z")

</div>

The VOC sensor also works just fine as a smell detector if you control your ventilation in the bathroom and so on.

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 2, 2020, 10:13am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/12 "2020-01-02T10:13:46Z")

</div>

If you want to use the Bosch library you indeed need to go through the steps as described. Including a library for the ESP32 is slightly different. To include it it was little bit tricky but it can be done. Once you edit the Arduino files for the ESP32 the library is added for all projects so keep the originals.  
I just use the IAQ (indoor air quality) index, I don’t think there is PPB value. There is a VOC resistence value though.

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 2, 2020, 10:19am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/13 "2020-01-02T10:19:12Z")

</div>

Using it in the WC is one of the main functions of this sensor.

---

<div class="post-metadata">

**Author:** ![Robin\_van\_Kekem](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robin_van_kekem/32/8187_2.png) [@Robin\_van\_Kekem](https://community.homey.app/u/Robin_van_Kekem)\
**Post date:** [January 3, 2020, 6:54am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/14 "2020-01-03T06:54:39Z")

</div>

Wow, really nice, wel done!  
Any estimates for how much it cost, including the 3D printed enclosure?

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 3, 2020, 7:30am UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/15 "2020-01-03T07:30:06Z")

</div>

Thanks. I would charge € 100,00 which is a bargain compared to what’s on the market.

> **[CO2 meters](https://www.co2-meters.com/c-2853462/co2-meters/)**
>
> Mensen ademen zuurstof (O2) in en kooldioxide (CO2) uit. De CO2-concentratie hangt samen met door het menselijk lichaam afgegeven verontreinigingen en ziektekiemen en is daarom een goede indicator voor de binnenluchtkwaliteit en de mate van...

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 27, 2020, 1:10pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/17 "2020-01-27T13:10:50Z")

</div>

Okey, solved most of my questions. I just wonder if you can share the code snippet that triggers the smoke alarm out of the IAQ values?

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 27, 2020, 1:45pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/18 "2020-01-27T13:45:17Z")

</div>

Hi Rindler,

SETUP

> Blockquote  
> // BME680 setup  
> Wire.begin();  
> iaqSensor.begin(BME680\_I2C\_ADDR\_SECONDARY, Wire);  
> output = "\nBSEC library version " + String(iaqSensor.version.major) + “.” + String(iaqSensor.version.minor) + “.” + String(iaqSensor.version.major\_bugfix) + “.” + String(iaqSensor.version.minor\_bugfix);  
> Serial.println(output);  
> checkIaqSensorStatus();  
> bsec\_virtual\_sensor\_t sensorList[10] = {  
> BSEC\_OUTPUT\_RAW\_TEMPERATURE,  
> BSEC\_OUTPUT\_RAW\_PRESSURE,  
> BSEC\_OUTPUT\_RAW\_HUMIDITY,  
> BSEC\_OUTPUT\_RAW\_GAS,  
> BSEC\_OUTPUT\_IAQ,  
> BSEC\_OUTPUT\_STATIC\_IAQ,  
> BSEC\_OUTPUT\_CO2\_EQUIVALENT,  
> BSEC\_OUTPUT\_BREATH\_VOC\_EQUIVALENT,  
> BSEC\_OUTPUT\_SENSOR\_HEAT\_COMPENSATED\_TEMPERATURE,  
> BSEC\_OUTPUT\_SENSOR\_HEAT\_COMPENSATED\_HUMIDITY,  
> };  
> iaqSensor.updateSubscription(sensorList, 10, BSEC\_SAMPLE\_RATE\_LP);  
> checkIaqSensorStatus();  
> iaqSensor.setTemperatureOffset( tempOffset );

LOOP

```
bme680loop(); // sensor values will automatically update only every 3 seconds, no matter how many times it is called

```

Serial.println( " Raw temp. " + String(iaqSensor.rawTemperature) );  
Serial.println( " Raw press. " + String(iaqSensor.pressure) );  
Serial.println( " Raw hum. " + String(iaqSensor.rawHumidity) );  
Serial.println( " Gas resis. " + String(iaqSensor.gasResistance));  
Serial.println( " IAQ " + String(iaqSensor.iaq));  
Serial.println( " IAQ accuracy " + String(iaqSensor.iaqAccuracy));  
Serial.println( " Comp. temp. " + String(iaqSensor.temperature));  
Serial.println( " Comp. hum. " + String(iaqSensor.humidity));  
Serial.println( " StaticIAQ " + String(iaqSensor.staticIaq));  
Serial.println( " eCO2 " + String(iaqSensor.co2Equivalent));  
Serial.println( " BreathVocEq. " + String(iaqSensor.breathVocEquivalent));

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 27, 2020, 1:51pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/19 "2020-01-27T13:51:29Z")

</div>

Thanks. And the code for the smoke alarm? 🙂

---

<div class="post-metadata">

**Author:** ![Lars\_Machiels](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/lars_machiels/32/10295_2.png) [@Lars\_Machiels](https://community.homey.app/u/Lars_Machiels)\
**Post date:** [January 27, 2020, 1:53pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/20 "2020-01-27T13:53:45Z")

</div>

```
if ( iaqVal >= 250 ) {
  Serial.println("High pollution detected!");
  alarm_smoke = true;
}
else {
  //Serial.println("No pollution detected");
  alarm_smoke = false;
}

```

Homey.setCapabilityValue(“alarm\_smoke”, (bool) alarm\_smoke );

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [February 19, 2020, 7:47pm UTC](https://community.homey.app/t/homeyduino-co2-sensor/20410/21 "2020-02-19T19:47:53Z")

</div>

Maybe I did something wrong, but the code above just spammed my Homey with several alerts every second that there were no fire, ha! For sure it depends on were you put the `setCapabilityValue-`code. Anyhow, the code below solved it for me.

```
   if ((iaqSensor.staticIaq >= 250) && (alarm_smoke == false)) {
      Serial.println("High pollution detected!");
      alarm_smoke = true;
      Homey.setCapabilityValue("alarm_smoke", (bool) alarm_smoke );
    }
    else if ((iaqSensor.staticIaq <= 250) && (alarm_smoke == true)){
      Serial.println("No pollution detected");
      alarm_smoke = false;
      Homey.setCapabilityValue("alarm_smoke", (bool) alarm_smoke );
    }
```

[Next page](https://community.homey.app/t/homeyduino-co2-sensor/20410.md?page=2)
