Simple CO₂ Monitor with Arduino, SCD30, and OLED
In this blog post, I will show you how to create a simple yet effective CO₂ monitor using an Arduino, the Sensirion SCD30 CO₂ sensor, and a small, stylish OLED display.
Wiring
Both the display and the sensor support I2C communication and can be operated with a voltage between 3 and 5 volts.
When using an ESP32, the usual pins are:
- SDA: Pin 21
- SCL: Pin 22
The pins on both the display and the sensor are labeled, so you just need to connect them correctly.
I2C is a bus system, which means:
- SDA lines of all I2C devices are connected together to pin 21
- SCL lines of all I2C devices are connected together to pin 22
I used a Wago connector, but you can also solder the connections.
Code
Make sure you have installed all necessary libraries in your Arduino IDE.
Required Libraries
Wire.h– I2C communicationSparkFun_SCD30_Arduino_Library– SCD30 sensorAdafruit_GFX– graphics libraryAdafruit_SH110X– OLED display
Arduino Sketch
#include <Wire.h>
#include "SparkFun_SCD30_Arduino_Library.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
SCD30 airSensor;
Adafruit_SH1106G display(128, 64, &Wire, -1);
unsigned long previousMillis = 0; // Timestamp of last update
const long interval = 180000; // Interval period (3 minutes)
int offsetX = 0; // Initial offset values
int offsetY = 0;
void setup() {
Wire.begin();
Serial.begin(9600);
airSensor.begin();
display.begin(0x3C, true);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SH110X_WHITE);
}
void loop() {
unsigned long currentMillis = millis();
// Check if interval has elapsed
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Slightly shift cursor position
offsetX = (offsetX + 1) % 5;
offsetY = (offsetY + 1) % 5;
}
if (airSensor.dataAvailable()) {
display.clearDisplay();
// CO2 value in ppm
display.setCursor(offsetX, offsetY);
display.print(airSensor.getCO2());
display.println(" ppm");
// Temperature in degrees Celsius
display.setCursor(offsetX, 20 + offsetY);
display.print(airSensor.getTemperature(), 1);
display.println(" C");
// Relative Humidity in percent
display.setCursor(offsetX, 40 + offsetY);
display.print(airSensor.getHumidity(), 1);
display.println(" %");
display.display();
}
delay(500);
}
Setup
First, initialize the components:
Wire.begin()starts I2C communicationSerial.begin(9600)opens the serial portairSensor.begin()initializes the SCD30 sensor- Prepare the display (address, resolution, text size, and color)
This ensures all components start correctly and display data cleanly.
Main Loop
In the loop() function, the main work happens:
- Time-controlled shift of the display position
- Query new sensor data
- Update the OLED display
Display Output
Measurements are shown with a slight positional offset. This not only creates a more dynamic image but also reliably protects the OLED from burn-in.
3D Printed Case
Printing requires no special settings.
Recommendations:
- Use support material at the front to hold the structure above the display
- Print the lid with Tree Support
3D print files will be provided separately.
Conclusion
With this project, you have built a compact and powerful CO₂ monitor. A Home Assistant integration will follow in a few days.