测量二氧化碳浓度:揭秘“困倦倍增器”
元件与物料
| 元件 | 数量 |
|---|---|
| Andium Anduino WiFi 扩展板 | 1 |
| Arduino Due 开发板 | 1 |
| CO2 传感器 (Cozir NDIR 型) | 1 |
应用与在线服务
- Arduino IDE
- Adafruit IO 云平台
项目简介
动机
你是否曾在下午的会议中昏昏欲睡?或是三小时的讲座中不断打哈欠?这不一定是你睡眠不足的错!通风不良导致的二氧化碳浓度升高,可能正是让你犯困的隐形推手。
本项目采用 NDIR(非分散红外)CO2 传感器,通过简单的 UART 串口接口即可精准读取 CO2 浓度。传统 CO2 传感器功耗大、预热慢,而这款 3.3V 供电、平均电流不足 1.5mA 的传感器,利用 LED 与红外探测器即可实现精准气体测量,原理基于光学色散技术,详情请参阅 Cozir 数据手册。

快速上手
开始测量你工位的“困倦指数”需要以下硬件:
- Arduino Due 或 Zero
- AnduinoWiFi 扩展板
- Cozir CO2 传感器
- 几根杜邦线用于连接供电与通信
传感器虽有 10 引脚,实际只需接 4 根线:

使用 Due 时接线如下:3.3V 接 3V3,GND 接地,Rx(DIO19) 接传感器 Tx,Tx(DIO18) 接传感器 Rx。注意必须“交叉”连接 UART 线。示例代码使用 Serial1 与传感器通信,保留 Serial 用于串口监视器调试。
提示:若想绕过 Arduino 直接测试传感器,可使用 PuTTY 等串口工具,波特率 9600,8 数据位,无校验,1 停止位,发送 ASCII 时需带回车换行(\r\n)。本传感器为 3.3V TTL 电平,若主控为 5V 必须加电平转换电路。
传感器校准
校准主要有两种方式:
- 纯氮气零点校准:将传感器置于无 CO2 的氮气环境中,获得绝对零点。
- 新鲜空气校准:将装置带到室外通风良好处,运行示例代码中
calibrateFreshAir()函数(发送 'G' 指令),以约 450 ppm 作为基准。虽然室外 CO2 浓度可能略高于夏威夷基准值,但考虑到人体感知阈值在 1000+ ppm 量级,此校准精度已足够满足会议室、教室等场景监测需求。



核心代码示例
char buffer[20] = {0}; int c = 0;
void setup() {
Serial.begin(9600); while(!Serial){};
Serial1.begin(9600); while(!Serial1){};
Serial.println("Begin reading CO2 Levels");
// setOperatingMode(CZR_STREAMING);
// setOperatingMode(CZR_POLLING);
// calibrateFreshAir(); // 首次使用时取消注释进行校准
}
void loop() {
delay(10000);
c = Request("Z"); // 请求 CO2 读数
Serial.print("CO2 : "); Serial.println(c);
Serial.println("");
}
int Request(char* s) {
buffer[0] = '\0'; int idx = 0;
Command(s); delay(250);
while(Serial1.available()) { buffer[idx++] = Serial1.read(); }
buffer[idx] = '\0';
uint16_t rv = 0;
switch(buffer[1]) {
case 'T' : rv = atoi(&buffer[5]); if (buffer[4] == 1) rv += 1000; break;
default : rv = atoi(&buffer[2]); break;
}
return rv;
}
void Command(char* s) { Serial1.print(s); Serial1.print("\r\n"); }
uint16_t calibrateFreshAir() { return Request("G"); }
void setOperatingMode(uint8_t mode) { sprintf(buffer, "K %u", mode); Command(buffer); }
代码顶部的两个 #define 用于设置工作模式(流式/轮询)。首次使用需取消注释 setOperatingMode() 和 calibrateFreshAir() 进行初始化。确认能在串口监视器读到 CO2 数值后,即可进阶将数据发布到云端。
将 CO2 数据发布至 Adafruit IO 云平台
若尚未配置 AnduinoWiFi 连接 Adafruit IO,请先参考官方教程。以下代码实现每分钟上传一次 CO2 浓度,并在板载 LCD 显示:
#include
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "AnduinoLCD.h"
// WiFi 参数
#define WLAN_SSID "YOUR_SSID"
#define WLAN_PASS "YOUR_PASSWD"
// Adafruit IO 参数
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "YOUR_AIO_USERNAME"
#define AIO_KEY "YOUR_AIO_KEY"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
// CO2 数据流
Adafruit_MQTT_Publish carbonDioxide = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/co2");
AnduinoLCD LCD = AnduinoLCD(ST7735_CS_PIN, ST7735_DC_PIN, 13);
static int co2 = 0, co2Prev = 0;
#define CZR_STREAMING 0x01
#define CZR_POLLING 0x02
char buffer[20] = {0};
void setup() {
Serial.begin(115200); delay(3000);
Serial1.begin(9600);
connectToWiFi(); connectToAdafruit();
LCD.begin(); LCDinit();
// setOperatingMode(CZR_STREAMING);
// setOperatingMode(CZR_POLLING);
// calibrateFreshAir();
}
void loop() {
if(! mqtt.ping(3)) { if(! mqtt.connected()) connect(); }
co2 = Request("Z");
char b[20]; String str = String(co2);
for(int i=0; i
完成!
这套装置灵敏度极高,甚至能根据 CO2 浓度变化推算房间人数。下次开会犯困时,你可以理直气壮地告诉教授:“不是微积分太难,是通风太差!”——甚至可以提议把课堂搬到海边上。

代码仓库
Anduino 库:Arduino 通用库,将 Arduino 转变为 Andium 节点。
https://github.com/andium/Anduino
制造工艺
- 树莓派传感器数据融合实战:GPS 与 MPU‑9150 IMU 的 I²C 与 UART 接入
- LEGO Mindstorms EV3 自制物体传感器:基于光影的“眼睛” DIY
- 直接将乐高 Mindstorms NXT 超声波传感器连接到树莓派
- 树莓派连接 HC-SR04 超声波传感器实战指南
- 将 Acconeer A111 脉冲雷达与树莓派集成:实用指南
- 货架上的客户服务升级:可视化与效率的进阶策略
- 工业维护:五大等级详解
- BME680 环境传感器深度解析:四合一气体/温湿度/气压监测
- CO₂与Nd激光切割:关键技术差异深度解析
- Sensirion发布SCD40超微型CO₂与温湿度传感器 仅1立方厘米
- 射频无线供电驱动通用传感器网络规模化落地
- RapidPlex传感器:SARS-CoV-2居家检测五大关键问题