Gravity: UART Infrared CO2 Sensor (0-50000ppm) Spikes on reading

Good Day to Everyone, I have been trying to use the Gravity: UART Infrared CO2 Sensor (0-50000ppm) (link for the sensor) to measure the CO2 content of a chamber. I have connected my arduino uno to real-time clock module, UART Infrared CO2 Sensor, a relay module in which it will control 2 exhaust fans (OMNI XFW-300) (one for intake and one for exhaust)and a CO2 solenoid valve and regulator. The initial setpoint is 2000 ppm, but the final setpoin that will be used once the set-up is working well is 49500 ppm. When we start the set-up, co2 solenoid valve and regulator will be turned on due to low co2 concentration inside the room, once the co2 concentration exceeds 2000 ppm, the exhaust fans will turn on and the co2 concentration will decrease, and the co2 solenoid valve and regulator is turned on, and the cycle continues. The problem lies once when the co2 readings went below 2000 ppm for the second or third time, the co2 reading spikes to around 34000+ ppm, in which the sensor readings maintain the 34000+ ppm value.

Here is the code used in the CO2 control:

* Infrared CO2 Sensor 0-50000ppm(Wide Range)
* ****************************************************
* The follow example is used to detect CO2 concentration.

* @author lg.gang(
* @version  V1.0
* @date  2016-6-6

* GNU Lesser General Public License.
* See <> for details.
* All above must be included in any redistribution
* ****************************************************/ 

void relay_init(void);
void relay_SetStatus( unsigned char status_1,  unsigned char status_2, unsigned char status_3,unsigned char status_4);
void Software_Reset();

#include <Wire.h>
#include <SoftwareSerial.h>
#include <Adafruit_Sensor.h>

uint32_t delayMS;

//the relays connect to
int IN1 = 3;
int IN2 = 4;
int IN3 = 5;
int IN4 = 6;
#define ON   0
#define OFF  1
int TOL = 0;
int delta = 100;
int lastCO2 = 0;

#define CO2SETPOINT 2000

SoftwareSerial mySerial(10, 11); // RX, TX
unsigned char hexdata[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79}; //Read the gas density command /Don't change the order

void setup() {

relay_init();//initialize the relay

while (!Serial) {


long readCO2() 
long hi,lo,CO2;


for(int i=0,j=0;i<9;i++) {
if (mySerial.available()>0) {

  if(i==2){     hi=ch;   }   //High concentration
  if(i==3){     lo=ch;   }   //Low concentration
  if(i==8) {
    CO2=hi*256+lo;  //CO2 concentration
    Serial.print("CO2 concentration: ");
    Serial.println(" ppm");  

return CO2;  

void loop() {
long CO2 = 0 ;

CO2 = readCO2();
//CO2 = 0;

if (CO2 < CO2SETPOINT) {  // switch ON CO2
relay_SetStatus(ON, OFF, OFF, OFF); //turn OFF R1

//  while (CO2 < CO2SETPOINT + TOL) {
//    delay(1000);
//    CO2 = readCO2();
//    }
//  relay_SetStatus(OFF, OFF, ON, ON);

else if (CO2 > CO2SETPOINT + TOL) {  
relay_SetStatus(OFF, OFF, ON,ON); //turn OFF R1, turn ON R3 and R4

//  while (CO2 > CO2SETPOINT - TOL) {
//    delay(1000);
//    CO2 = readCO2();
//    }
//  relay_SetStatus(ON, OFF, OFF,OFF);

//initialize the relay
void relay_init(void)
//set all the relays OUTPUT
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
relay_SetStatus(OFF,OFF,OFF,OFF);//turn off all the relays

//set the status of relays
void relay_SetStatus( unsigned char status_1,  unsigned char status_2, unsigned char status_3,unsigned char status_4)
digitalWrite(IN1, status_1);
digitalWrite(IN2, status_2);
digitalWrite(IN3, status_3);
digitalWrite(IN4, status_4);


void Software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
asm volatile ("  jmp 0");  


Post the code that produced this! The example code DFRobot provides has another output format. Are you sure you're using the correct code for your sensor? If you use the correct code an output of 34422ppm is not possible, so your code must be wrong.

BTW, you failed to provide the necessary information, is that the sensor you're using?

Good Evening Pylon!

Sorry for the incomplete details of my forum post, I have already edited it. I hope you can help me. Thank yo

Edit your post again and insert code tags!

We still don't know which sensor your using! Provide a link to that hardware as it seems to be something completely different from what I linked to.

Good Morning Pylon!

I have already created the code tag for the code and the link for the sensor! sorry for the troubles. Thank you.

The sensor RX/TX pins are 3.3V only.
Are you using a 5V Arduino and if so, are you using 3.3-5V level shifters?

Here is the link for the microcontroller that I have used in my set-up. I am not using any 3.3V-5v level shifters

You might try using a 1K:2K resistive voltage divider for the connection Arduino TX -> sensor RX, to reduce 5V to the 3.3V tolerated by the input.

The sensor RX/TX pins are 3.3V only.
Are you using a 5V Arduino and if so, are you using 3.3-5V level shifters?

The datasheet is telling that but DFRobot's wiki page shows a direct connection to an UNO clone, so it seems to be 5V tolerant.

My guess is that you run out of sync with the device on the serial interface. One single character lost and the code will only return wrong values. I would implement at least a CRC check of the read message. And don't stop reading after 9 bytes, read as long as there are bytes in the buffer. That might resynchronize if a character got lost or if the SoftwareSerial read a ghost byte.

so it seems to be 5V tolerant.

That is a very bad assumption. The specs clearly state 0 to 3.3V and not "5V tolerant".

Applying 5V to a 3.3V input IS a problem, guaranteed to do harm, so please do not advise forum members to make such a connection.

That may not be the only problem.

I think there is a problem with regards to the connection of the arduino uno to the relay since after switching on the channel for the exhaust fans, the sensor reading spikes to 34000+ ppm. I hope this detail helps

You have power supply noise problems. Post a complete wiring diagram (hand drawn is fine, not Fritzing).

Thank you jremington! I would also like to add that I use these exhaust fans connected on two of the channels in the relay and two of these co2 solenoid valve and regulator connected to an extension and used on one channel of the relay. Spikes on the readings at 34000 ppm, occurs when the set-up and all of the fans and solenoid is plugged in, while when the set-up is running and all of the plugs for the fans and solenoid are unplugged, the sensor readings doesn't spike. I will send the schematic drawing for the set-up later

Good Day jremington! Here is the wiring schematic for my set-up, pardon for the drawings since I am not accustomed to electronics

Thanks for posting the nice drawing, but it doesn't show the fan and solenoid wiring.

If the solenoid is DC, do you have a flyback diode across the solenoid winding?

Switched power wiring radiates interference into the radio frequency range. Keep all power wiring bunched up and as far away from signal wires as possible. You may need to use shielded cable (with the shield grounded) for the signal wires. The photo from the OP suggests that wiring proximity is a problem:


Thank you. Here is a simple clip where the fans are working, the solenoid valve is connected through an extension and is outside of the chamber. I will send a proper video later

Sorry if I didn't answer your other question, the co2 solenoid valve and regulator is 220V AC.

Videos are completely uninteresting. Try to reroute and/or shield your wiring as mentioned earlier.

We tried to disconnect the fans and use only the relay for the solenoid valve, sensor readings doesn't spike, but then when we connect the relay for the fan, the sensor reading began to spike. I would also like to add that the intake and exhaust fans that I used are rated for 50W each.

If there is a separate enclosure for the relay, may I ask what material can be used to be a good enclosure. Thank you. I would like to ask specifically where in the picture is the power supply wires and signal wires. Thank you.