红外二氧化碳传感器

简介

DFRobot最新推出高精度红外二氧化碳传感器,有效量程可达400~5000ppm。传感器利用非色散红外(NDIR)原理对空气中存在的CO2进行探测,具有很好的选择性和无氧气依赖性,使用寿命可达5年。并且内置温度补偿,支持DAC输出,仅需要一个数字口,就可读取当前CO2气体浓度,使用非常简单,兼容各类单片机和传感器。
DFRobot红外激光传感器是将成熟的红外吸收气体检测技术与精密光路设计、精良电路设计紧密结合而制作出的高性能传感器,具有高灵敏度、高分辨率、低功耗,响应快、抗水汽干扰、不中毒、稳定性高、使用寿命长等特点。外置Gravity接口使得传感器能够直接兼容DFRobot Arduino IO扩展板,即插即用,无需额外接线。可广泛应用于暖通制冷与室内空气质量监控、工业过程及安全防护监控、农业及畜牧业生产过程监控等。

特性

  • 气室采用镀金处理,防水防腐蚀
  • 高灵敏度、低功耗
  • 优异的稳定性
  • 温度补偿,卓越的线性输出
  • 使用寿命长
  • 抗水汽干扰、不中毒

产品参数

  • 检测气体:二氧化碳
  • 供电电压:DC(5.0±0.1)V
  • 平均电流:<40mA(@5V供电)
  • 峰值电流:<125(@5V供电)
  • 输出信号:PWM
  • 预热时间:1min
  • 响应时间:T90 < 120s
  • 工作温度:--10℃~50℃
  • 工作湿度:0~95%RH(无凝结)
  • 量程:400~5000 ppm
  • 分辨率:1ppm
  • 精度:±(50ppm+5%读数值)
  • 尺寸:69×37mm

引脚说明

标号 名称 功能描述
1 Signal 信号输出(0.4~2V)
2 VCC 电源+
3 GND 电源-

校零方法

  • 方法1:手动校零

手动校准零点是将传感器的HD与GND短接进行校准零点,低电平需持续7 秒以上。校准零点前请确保传感器在400ppm 浓度下稳定运行20 分钟以上。

  • 方法2:自动校零

自动校准功能是指传感器在连续运行一段时间后,根据环境浓度智能判断零点并自行校准。校准周期为上电运行起,每24 小时,自动校准一次。自动校准的零点是400ppm。自动校零功能适合用于办公环境,家庭环境。

快速上手

本次教程意在让您在5分钟内,学会如何使用红外二氧化碳传感器去测量当前空气中的二氧化碳浓度

兼容

MCU Work Well Work Wrong Untested Remarks
Arduino Uno
FireBeetle-ESP8266
FireBeetle-ESP32
FireBeetle-M0
Micro:bit

注意:3.3V主板也需5V供电

样例代码

/*!
 * @file  CO2SensorPWMInterface.ino
 * @brief  This example The sensors detect CO2
 * @details  Infrared CO2 Sensor range : 400-4980ppm
 * @copyright  Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @license  The MIT License (MIT)
 * @author  [qsjhyy](yihuan.huang@dfrobot.com)
 * @version  V2.0
 * @date  2023-01-15
 */

#if defined(ESP32) || defined(ESP8266)
  // D7 pin is used as interrupt pin by default, other non-conflicting pins can also be selected as external interrupt pins.
  #define SENSOR_DATA_PIN   (D7)   // Sensor PWM interface
  #define INTERRUPT_NUMBER   digitalPinToInterrupt(SENSOR_DATA_PIN)   // interrupt number
#elif defined(ARDUINO_SAM_ZERO)
  // Pin 5 is used as interrupt pin by default, other non-conflicting pins can also be selected as external interrupt pins
  #define SENSOR_DATA_PIN   (5)   // Sensor PWM interface
  #define INTERRUPT_NUMBER   digitalPinToInterrupt(SENSOR_DATA_PIN)   // interrupt number
#else
  /* The Correspondence Table of AVR Series Arduino Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------
   * |                                        |  DigitalPin  | 2  | 3  |                   |
   * |    Uno, Nano, Mini, other 328-based    |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  |                   |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 2  | 3  | 21 | 20 | 19 | 18 |
   * |               Mega2560                 |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  | 5  |
   * |-------------------------------------------------------------------------------------|
   * |                                        |    Pin       | 3  | 2  | 0  | 1  | 7  |    |
   * |    Leonardo, other 32u4-based          |--------------------------------------------|
   * |                                        | Interrupt No | 0  | 1  | 2  | 3  | 4  |    |
   * |--------------------------------------------------------------------------------------
   * ---------------------------------------------------------------------------------------------------------------------------------------------
   *                      The Correspondence Table of micro:bit Interrupt Pins And Terminal Numbers
   * ---------------------------------------------------------------------------------------------------------------------------------------------
   * |             micro:bit                       | DigitalPin |P0-P20 can be used as an external interrupt                                     |
   * |  (When using as an external interrupt,      |---------------------------------------------------------------------------------------------|
   * |no need to set it to input mode with pinMode)|Interrupt No|Interrupt number is a pin digital value, such as P0 interrupt number 0, P1 is 1 |
   * |-------------------------------------------------------------------------------------------------------------------------------------------|
   */
  // Open the external interrupt 0, connect INT1/2 to the digital pin of the main control: 
  // UNO(2), Mega2560(2), Leonardo(3), microbit(P0).
  #define SENSOR_DATA_PIN   (2)   // Sensor PWM interface
  #define INTERRUPT_NUMBER   (0)   // interrupt number
#endif

// Used in interrupt, calculate pulse width variable
volatile unsigned long pwmHighStartTicks=0, pwmHighEndTicks=0;
volatile unsigned long pwmHighVal=0, pwmLowVal=0;
// interrupt flag
volatile uint8_t flag=0;

void interruptChange()
{
  if (digitalRead(SENSOR_DATA_PIN)) {
    pwmHighStartTicks = micros();    // store the current micros() value
    if(2 == flag){
      flag = 4;
      if(pwmHighStartTicks > pwmHighEndTicks) {
        pwmLowVal = pwmHighStartTicks - pwmHighEndTicks;
      }
    }else{
      flag = 1;
    }
  } else {
    pwmHighEndTicks = micros();    // store the current micros() value
    if(1 == flag){
      flag = 2;
      if(pwmHighEndTicks > pwmHighStartTicks){
        pwmHighVal = pwmHighEndTicks - pwmHighStartTicks;
      }
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("beginning...");
  pinMode(SENSOR_DATA_PIN, INPUT);
  attachInterrupt(INTERRUPT_NUMBER, interruptChange, CHANGE);
}

void loop() {
  if(flag == 4){
    flag = 1;
    float pwmHighVal_ms = (pwmHighVal * 1000.0) / (pwmLowVal + pwmHighVal);

    if (pwmHighVal_ms < 0.01){
      Serial.println("Fault");
    }
    else if (pwmHighVal_ms < 80.00){
      Serial.println("preheating");
    }
    else if (pwmHighVal_ms < 998.00){
      float concentration = (pwmHighVal_ms - 2) * 5;
      // Print pwmHighVal_ms
      Serial.print("pwmHighVal_ms:");
      Serial.print(pwmHighVal_ms);
      Serial.println("ms");
      //Print CO2 concentration
      Serial.print(concentration);
      Serial.println("ppm");
    }else{
      Serial.println("Beyond the maximum range : 398~4980ppm");
    }
    Serial.println();
  }
}

结果

请至少耐心等待3分钟(预热阶段),直到数据稳定。此时传感器即可显示CO2浓度

常见问题

还没有客户对此产品有任何问题,欢迎通过qq或者论坛联系我们!

问: 为什么这款二氧化碳传感器读数不稳定? |
答: 由于这款二氧化碳传感器灵敏度比较高,所以会造成读数起伏略大,可以通过若干数值取平均值的方式降低读数的偏差。具体可参考网址:https://www.dfrobot.com/forum/viewtopic.php?f=8&t=2691|

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多资料

V1.0 程序.pdf

DFshopping_car1.png DFRobot商城购买链接