Example Code for Arduino-Read CO2 Value

This project demonstrates how to read CO2 concentration values from the RS485 Infrared CO2 Sensor (400-5000ppm) using an Arduino board. Users will learn to interface with the sensor via the RS485 protocol, implement Modbus-RTU communication, and process raw sensor data into readable CO2 values.

Hardware Preparation

Software Preparation

Wiring Diagram

If the power of the RS485 device is small and the required current is less than 12V-160mA, the RS485 to UART signal conversion module does not require a 12V external power supply, making wiring more convenient.

Other Preparation Work

Note: The CO2 concentration value output during the preheating time will gradually stabilize. Please ignore the CO2 concentration value within 5 minutes of preheating.

Sample Code

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3);
uint8_t Com[8] = { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A }; 
int CO2;
void setup() {
  Serial.begin(9600);  
  mySerial.begin(9600); 
}
void loop() {
  readCO2();
  Serial.print("CO2 = ");
  Serial.print(CO2);
  Serial.println(" ppm");
  delay(4000);
}
void readCO2(void) {
  uint8_t Data[10] = { 0 };
  uint8_t ch = 0;
  bool flag = 1;
  while (flag) {
    delay(100);
    mySerial.write(Com, 8);
    delay(10);
    if (readN(&ch, 1) == 1) {
      if (ch == 0x01) {
        Data[0] = ch;
        if (readN(&ch, 1) == 1) {
          if (ch == 0x03) {
            Data[1] = ch;
            if (readN(&ch, 1) == 1) {
              if (ch == 0x02) {
                Data[2] = ch;
                if (readN(&Data[3], 4) == 4) {
                 if (CRC16_2(Data, 5) == (Data[5] * 256 + Data[6])) {
                    CO2 = Data[3] * 256 + Data[4];
                    flag = 0;
                  }
                }
              }
            }
          }
        }
      }
    }
     mySerial.flush();
  }
}

uint8_t readN(uint8_t *buf, size_t len) {
  size_t offset = 0, left = len;
  int16_t Tineout = 500;
  uint8_t *buffer = buf;
  long curr = millis();
  while (left) {
    if (mySerial.available()) {
      buffer[offset] = mySerial.read();
      offset++;
      left--;
    }
    if (millis() - curr > Tineout) {
      break;
    }
  }
  return offset;
}

unsigned int CRC16_2(unsigned char *buf, int len) {
  unsigned int crc = 0xFFFF;
  for (int pos = 0; pos < len; pos++) {
    crc ^= (unsigned int)buf[pos];
    for (int i = 8; i != 0; i--) {
      if ((crc & 0x0001) != 0) {
        crc >>= 1;
        crc ^= 0xA001;
      } else {
        crc >>= 1;
      }
    }
  }

  crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8);
  return crc;
}

Result

Print the collected CO2 value.

Was this article helpful?

TOP