These day I tested a nice sensor, the SCD30 from Sensirion.
https://www.sensirion.com/en/environmental-sensors/carbon-dioxide-sensors/carbon-dioxide-sensors-co2/
It’s a nice small unit capable of sense very well carbon dioxide levels in the air, as well as temperature and humidity.
The average cost per unit is around 60 Euro, but I managed to find it for less than half price on an online chinese supplier, have a look on aliexpress/taobao/bangood.
I choose this sensor compared to other mainly for these characteristics:
- I2C/UART interface
- calibrated output in ppm
- high precision of +/- 30ppm
- operating voltage between 3.3v and 5.5v (therefore good with Arduino and ESP8266 board which only provides 3.3v like ESP01/ESP12).
The sensor reading seems very accurate. In the following example I closed door and windows of my bedroom before going to sleep, and then opened again once awake:
Slowly the concentration of CO2 coming from breathing saturates the room, a nice idea could be to trigger a sound or notification to ventilate the room, or starting an air extractor.
Here’s a detail of the sensor in operation, the glowing light is the infrared source necessary to analyze the air samples:
I tested the unit with my beloved NodeMCU wiring it this way:
ESP SCD30
gnd gnd
3v3 +3v
D1 SCL/tx
D2 SDA/rx
Next step is to realize some coding to read the CO2 data, and publish it as MQTT topic.
I made this little code which you can upload on any ESP/Arduino board:
// * * * * * * * * * * * * * * * * * * * * * * *
// SDC30 carbon dioxide sensor to MQTT
// by Ombra for Home Assistant Community - 2020
// * * * * * * * * * * * * * * * * * * * * * * *#include <ESP8266WiFi.h>
#include <Wire.h>
#include <PubSubClient.h>#define scd_debug 0
#include “paulvha_SCD30.h”
SCD30 airSensor;// Network and MQTT broker parameters
#define wifi_ssid “YOUR SSID”
#define wifi_password “YOUR PASSWD”
#define mqtt_server “YOUR MQTT BROKER”
#define mqtt_user “YOUR MQTT USERNAME”
#define mqtt_password “YOUR MQTT PASSWD”#define co2_topic “chemical_SCD30/CO2”
#define temp_topic “chemical_SCD30/TEMP”
#define humi_topic “chemical_SCD30/HUMI”int co2, temp, humi;
// --------------------------------
WiFiClient espClient;
PubSubClient client(espClient);void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println(“SCD30 values:”);airSensor.setDebug(scd_debug);
airSensor.begin(Wire);// ------------------------------------
setup_wifi();
client.setServer(mqtt_server, 1883);
}void setup_wifi() {
delay(10);
// Connect to WiFi network
Serial.println();
Serial.print(“Connecting to network: “);
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(”.”);
}
Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print(“Connecting to MQTT broker…”);// no user and pass use this: // if (client.connect("ESP8266Client")) { // if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) { Serial.println("Connected!"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" retry 5 in seconds"); // set a different delay if having fast connection delay(5000); }
}
}void loop() {
co2 = airSensor.getCO2();
temp = airSensor.getTemperature(), 1;
humi = airSensor.getHumidity(), 1;if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();delay(2000);
// Publish MQTT topic
Serial.print(“CO2(ppm):”);
Serial.println(String(co2).c_str());
client.publish(co2_topic, String(co2).c_str(), true);Serial.print("Temperature:"); Serial.println(String(temp).c_str()); client.publish(temp_topic, String(temp).c_str(), true); Serial.print("humidity:"); Serial.println(String(humi).c_str()); client.publish(humi_topic, String(humi).c_str(), true);
}
The script provides 3 topics with the values of CO2, temperature and humidity.
To integrate it in HA make this entry inside the configuration.yaml
sensor 3:
platform: mqtt
name: "SDC30 CO2"
state_topic: "chemical_SCD30/CO2"
qos: 0
unit_of_measurement: "PPM"
sensor 4:
platform: mqtt
name: "SDC30 temperature"
state_topic: "chemical_SCD30/TEMP"
qos: 0
unit_of_measurement: "C"
sensor 5:
platform: mqtt
name: "SDC30 humidity"
state_topic: "chemical_SCD30/HUMI"
qos: 0
unit_of_measurement: "%"
And here is the final result: