jw01二氧化碳CO2传感器(三合一v2.2)使用方法:esp8266 nodemcu CH340与arduino配合使用

〇、先看一下硬件方面吧~

1.JW01传感器

注意该型号的版本,当前使用版本只能测试CO2浓度,结尾附了三合一jw01-co2-v2.2的示例代码供参考

2.ESP8266 nodemcu(CH340)


我们用到的就是nodemcu(CH340)

接口引脚图

首先,看看这个传感器的接口参数和各指标的数据算法:

1.接口
G:电源负极
+5:电源正极
A:RXD接口(接开发板TX,开发板发送,传感器接收)
B:TXD接口(接开发板RX,传感器发送,开发板接收)

波特率:9600bps
数据位:8位
停止位:1位
检验位:无

2.串口数据格式:
B1 模块地址 2Ch
B2 CO2高 0XXh
B3 CO2低 0XXh
B4 满量程高 0XXh
B5 满量程低 0XXh
B6 校验和 0XXh

说明:
1.B1的2Ch是模块固定地址;
2.校验和B6=unit_8(B1+B2+B3+B4+B5);
3.二氧化碳浓度(PPM)=CO2高(B2))*256+CO2低(B3)

例如读到的值是:

2Ch,01h,90h,03h,0FFh,BFh

则得出如下结果:

1.校验和:BFh=2Ch+01h+90h+03h+0FFh,
2.二氧化碳CO2数值:B2256+B3=01h256+90h=400PPM

根据以上的接口参数和数据格式,以下是基于ESP8266的Arduino代码示例,用于读取并计算TCO2的浓度值:
接线图如下:
jw01:

ESP8266 MCU:


一、主动上传数据

运行代码

#include <SoftwareSerial.h>

// 定义软件串口的RX和TX引脚
const int rxPin = 14; // 这个引脚需要连接到传感器的TX
const int txPin = 2; // 这个引脚需要连接到传感器的RX

// 设置软件串口
SoftwareSerial co2Sensor(rxPin, txPin);

void setup() {
  // 初始化串口
  Serial.begin(9600);
  while (!Serial) {
    ; // 等待串口连接。只对 Leonardo/Micro 或其他基于 ATmega32U4 的板子必须
  }

  // 启动传感器串口
  co2Sensor.begin(9600);
  Serial.println("CO2 Sensor started");
}

void loop() {
  // 传感器的数据包大小
  const int packetSize = 6;
  byte packet[packetSize];

  // 读取数据
  if (co2Sensor.available()) {
    for (int i = 0; i < packetSize; i++) {
      // 读取传感器数据
      packet[i] = co2Sensor.read();
    }

    // 校验和检验,就是检验发送时的数据总和和接收时的数据总和是否一致,以此判断数据是否丢失
    if (packet[5] == (byte)(packet[0] + packet[1] + packet[2] + packet[3] + packet[4]) % 256) {
      // 计算CO2浓度
      int co2 = (packet[1] * 256) + packet[2];
      Serial.print("CO2 Concentration: ");
      Serial.print(co2);
      Serial.println(" PPM");
    } else {
      Serial.println("Checksum error");
    }
  }

  // 传感器数据读取间隔
  delay(2000);
}

运行结果:

可以看出,校验和不同,数据发生了丢失。 但有时候也是能校验成功的,直接输出了真实值,有点不稳定

原因:可能是连接问题,也可能是板子或者jw01的问题,会产生传输误差
解决办法:删除校验和的数据检验过程(我们暂且不需要很精准的,运行数据丢失一丢丢)

说明一下:
在这个示例代码中,使用了ESP8266的软件串口(SoftwareSerial)库来模拟串口通信。我们使用GPIO14来接收数据信号,GPIO02虽然插上了,其实没有用到,因为我们并没有发送读取数据的指令,你可以测试一下将GPIO2拔掉,不影响接收。

删除校验和检验部分后:

#include <SoftwareSerial.h>

// 定义软件串口的RX和TX引脚
const int rxPin = 14; // 这个引脚需要连接到传感器的TX
const int txPin = 2; // 这个引脚需要连接到传感器的RX

// 设置软件串口
SoftwareSerial co2Sensor(rxPin, txPin);

void setup() {
  // 初始化串口
  Serial.begin(9600);
  while (!Serial) {
    ; // 等待串口连接。只对 Leonardo/Micro 或其他基于 ATmega32U4 的板子必须
  }

  // 启动传感器串口
  co2Sensor.begin(9600);
  Serial.println("CO2 Sensor started without checksum verification");
}

void loop() {
  // 传感器的数据包大小
  const int packetSize = 6;
  byte packet[packetSize];

  // 读取数据
  if (co2Sensor.available() >= packetSize) {
    for (int i = 0; i < packetSize; i++) {
      // 读取传感器数据
      packet[i] = co2Sensor.read();
    }

    // 直接计算CO2浓度,不进行校验和检验
    int co2 = (packet[1] * 256) + packet[2];
    Serial.print("CO2 Concentration: ");
    Serial.print(co2);
    Serial.println(" PPM");
  }

  // 传感器数据读取间隔
  delay(2000);
}

运行结果
刚开机时:

开机约5分钟后

数据开始恢复正常了

二、问答获取数据(测试可行)

接线保持不变,当用户需要问答模式时,可以通过发送如下命令,发送一次,主动上传就自动关闭。需要重新上电,才可回恢复为自动上传。

命令如下:0XFF 0x01 0x86

我们修改代码如下:

#include <SoftwareSerial.h>

// 定义软件串口的RX和TX引脚
const int rxPin = 14; // 这个引脚需要连接到传感器的TX
const int txPin = 2; // 这个引脚需要连接到传感器的RX,设置为2号引脚

// 设置软件串口
SoftwareSerial co2Sensor(rxPin, txPin);

void setup() {
  // 初始化串口
  Serial.begin(9600);
  while (!Serial) {
    ; // 等待串口连接。
  }

  // 启动传感器串口
  co2Sensor.begin(9600);
  Serial.println("CO2 Sensor started in query mode");

  // 发送读取数据指令
  sendReadCommand();
}

void loop() {
  // 传感器的数据包大小
  const int packetSize = 6;
  byte packet[packetSize];

  // 读取数据
  while (co2Sensor.available() > 0) {
    if (co2Sensor.available() >= packetSize) {
      for (int i = 0; i < packetSize; i++) {
        // 读取传感器数据
        packet[i] = co2Sensor.read();
      }

      // 直接计算CO2浓度
      int co2 = (packet[1] * 256) + packet[2];
      Serial.print("CO2 Concentration: ");
      Serial.print(co2);
      Serial.println(" PPM");

      // 读取完成后,延时一段时间再发送新的读取指令
      delay(2000); // 延时时间可以根据实际需要调整
      sendReadCommand(); // 再次发送读取数据指令
    }
  }
}

void sendReadCommand() {
  // 发送的命令字节序列
  byte command[3] = {0xFF, 0x01, 0x86};

  co2Sensor.write(command, sizeof(command)); // 发送命令到传感器
  co2Sensor.flush(); // 确保命令发送完毕
}

运行结果:


以上是问答模式,无校验的,可以看出,其实已经开始稳定输出了

现在我们再试试校验数据的,检查数据丢失情况

三、三合一(jw01 v2.2 co2-ch2o-TVOC)

据说这款传感器可以实现三合一的检测,检测CO2二氧化碳含量,CH2O甲醛含量,TVOC总空气有机挥发气体含量,那我们来试试看看能不能检测到:

#include <SoftwareSerial.h>

// 定义软件串口的RX和TX引脚
const int rxPin = 14; // 这个引脚需要连接到传感器的TX
const int txPin = 2; // 这个引脚需要连接到传感器的RX

// 设置软件串口
SoftwareSerial mySerial(rxPin, txPin);

// 读取命令, 这需要替换成正确的指令
const byte readCommand[] = {0xFF, 0x01, 0x86}; // 读取指令

void setup() {
  // 初始化串口
  Serial.begin(9600);
  while (!Serial) {
    ; // 等待串口连接。
  }

  // 启动传感器串口
  mySerial.begin(9600);
  Serial.println("Sensor started in query mode");

  // 发送读取指令
  sendReadCommand();
}

void loop() {
  // 检查是否有足够数据可读
  if (mySerial.available() >= 9) {
    // 读取一个数据包
    uint8_t packet[9];
    for (int i = 0; i < 9; i++) {
      packet[i] = mySerial.read();
    }
    
    // 计算污染气体浓度值
    float tvoc = (packet[2] * 256 + packet[3]) * 0.01;
    float ch2o = (packet[4] * 256 + packet[5]) * 0.01;
    int co2 = packet[6] * 256 + packet[7];

    // 打印结果
    Serial.print("TVOC: ");
    Serial.print(tvoc);
    Serial.println(" mg/m3");

    Serial.print("CH2O: ");
    Serial.print(ch2o);
    Serial.println(" mg/m3");

    Serial.print("CO2: ");
    Serial.print(co2);
    Serial.println(" PPM");

    // 等待一段时间后再发送读取指令
    delay(2000);
    sendReadCommand();
  }
}

void sendReadCommand() {
  // 发送读取指令
  mySerial.write(readCommand, sizeof(readCommand));
  mySerial.flush(); // 确保指令发送完毕
}

运行结果:

刚开始十来秒,输出是为零的,需要预热,后面的值就稳定了,看得出还是很合理的一个输出值,jw01二氧化碳浓度传感器和jw01 v2.2三合一CO2,CH2O,TVOC传感器外观是一样的,购买的朋友记得看明信息,一个只能测CO2浓度,一个则可以测CO2,CH2O,TVOC(有机挥发气体)浓度,所以呢,如果要运行三合一这个代码,可以买一款jw01-co2-v2.2的传感器。

四、结论

使用问答模式结合非校验和检验,测量二氧化碳CO2浓度,是可以稳定输出的。

三和一CO2传感器可以很顺利的运行。

大家可能要根据自己的实际情况做一些调整(因为传感器和开发板的区别)

创作不易,这期教程花了蛮多时间测试,如果能帮到大家,希望大家三连,谢谢~

好了,暂时写到这里了,如果你还有疑问,欢迎留言~

物联沃分享整理
物联沃-IOTWORD物联网 » jw01二氧化碳CO2传感器(三合一v2.2)使用方法:esp8266 nodemcu CH340与arduino配合使用

发表评论