I am trying to build an incubator that can control CO2 concentration at 5% by volume. Detailed instructions are available here:
https://www.pellinglab.net/single-post/diy/DIY-CO2-Incubator-Bioreactor-for-Mammalian-Cell-Culture
Project specification:
MCU: Arduino Mega 2560 R3
CO2 sensor: COZIR SprintIR-WX-20 0-20% CO2 sensor (Data sheet attached in the attachment and HERE)
I tried to test the sensor with the test code provided by the author:
#include "cozir.h"
#include "SoftwareSerial.h"
#define RxPin 15
#define TxPin 14
SoftwareSerial nss(RxPin, TxPin); // Tx, Rx from the sensor to Pins 15, 14 on Arduino
COZIR czr(nss);
float c, reading = 0;
float multiplier = 10;
void setup()
{
Serial.begin(9600);
czr.SetOperatingMode(CZR_POLLING);
delay(100);
}
void loop()
{
c = czr.CO2(); // read the sensor, values output as ppm/10
reading = c*multiplier; // convert ppm reading to ppm
Serial.print("CO2 Content: ");
Serial.print(reading);
Serial.println("ppm");
Serial.println();
delay(50);
}
This code is using this library:
Here is the circuit:
You may not be able to see it clearly, there are only 4 connections:
Sensor Arduino
GND-------->GND
Vcc--------->3v3
Rx---------->14 (TX3)
Tx---------->15 (RX3)
The problem is that when I tried out the sensor, no matter how much CO2 I was blowing on its face (from a gas tank), it only reads 20ppm. I thought there may be some problem with the Cozir library, so I went online and found another test code which doesn't use the library
#include <SoftwareSerial.h>
#define Rx 15
#define Tx 14
SoftwareSerial mySerial(Rx, Tx); // RX, TX pins on Ardunio
int co2 = 0;
double multiplier = 10;// 1 for 2% =20000 PPM, 10 for 20% = 200,000 PPM
uint8_t buffer[25];
uint8_t ind = 0;
uint8_t index = 0;
int fill_buffer(); // function prototypes here
int format_output();
void setup() {
Serial.begin(9600);
Serial.print("\n\n");
Serial.println(" AN128 Ardunio to Cozir CO2 Sensor - Demonstration code 11/29/2017\n\n");
pinMode(Rx, INPUT);
pinMode(Tx, OUTPUT);
mySerial.begin(9600); // Start serial communications with sensor
//mySerial.println("K 0\r\n"); // Set Command mode
mySerial.print("M 6\r\n"); // send Mode for Z and z outputs
// "Z xxxxx z xxxxx" (CO2 filtered and unfiltered)
mySerial.print("K 1\r\n"); // set streaming mode
}
void loop() {
fill_buffer(); // function call that reacds CO2 sensor and fills buffer
Serial.print("Buffer contains: ");
for (int j = 0; j < ind; j++)Serial.print(buffer[j], HEX);
index = 0;
format_output();
Serial.print(" Raw PPM ");
index = 8; // In ASCII buffer, filtered value is offset from raw by 8 bytes
format_output();
Serial.println(" Filtered PPM\n\n");
}
int fill_buffer(void) {
// Fill buffer with sensor ascii data
ind = 0;
while (buffer[ind - 1] != 0x0A) { // Read sensor and fill buffer up to 0XA = CR
Serial.println(mySerial.available());
if (mySerial.available()) {
buffer[ind] = mySerial.read();
ind++;
Serial.print(ind);
}
}
// buffer() now filled with sensor ascii data
// ind contains the number of characters loaded into buffer up to 0xA = CR
ind = ind - 2; // decrement buffer to exactly match last numerical character
}
int format_output(void) { // read buffer, extract 6 ASCII chars, convert to PPM and print
co2 = buffer[15 - index] - 0x30;
co2 = co2 + ((buffer[14 - index] - 0x30) * 10);
co2 += (buffer[13 - index] - 0x30) * 100;
co2 += (buffer[12 - index] - 0x30) * 1000;
co2 += (buffer[11 - index] - 0x30) * 10000;
Serial.print("\n CO2 = ");
Serial.print(co2 * multiplier, 0);
// Serial.print(" PPM,");
// Serial.print("\n");
delay(200);
}
I still didn't get it to work, so I inserted the line "Serial.println(ind);" in the function fill_buffer(). On the serial monitor, ind is ALWAYS 0. That means NOTHING is in the serial receive buffer. I read in other threads that declaring the pinMode of Rx and Tx as OUTPUT and INPUT respectively may solve the problem, I tried it and it didn't work, now I am running out of idea. Could someone give me some advice on this issue?
SprintIR_-Apollo.PDF (789 KB)
