I'm trying to accomplish the simplest reading of a CO2 sensor via I2C and an Arduino Uno.
I have checked and rechecked my circuit. The current setup is as follows:
External power supply connected to CO2 sensor (have tried all sorts of different voltages from 5 to 12). One of the application notes states to power from an external 6 to 9V supply while the website states it can handle from 5.5 to 14 Volts. CO2 sensor lights up and blinks regularly with any voltage applied.
Arduino powered through my laptop.
I have two 4.7K pullup resistors on I2C lines (one on each line), connected to the 5V arduino rail on my breadboard.
I have created a common ground between the power supply and the Arduino.
I have used both these application notes (which are almost identical) with no success.
Application Note 1
Application Note 2
Troubleshooting steps were as follows:
-
I have tried multiple different voltages between 5 and 12 (with no success).
-
I have tried swapping the SCL and SDA in case I had confused them (with no success).
-
I have tried not using a common ground (with no success).
-
I have tried removing the pullup resistors (with no success).
-
I have tried powering the sensor from the Arduino 5V pin even though this is not recommended (with no success).
The exact code I'm using is shown below (copied verbatim from the company's application note). When trying to receive readings, the serial monitor only prints out "Checksum Failed/Communication Failure." Is anything obvious in the code on why this might not be working? Such as outdated code format? I can't for the life of me find the error and I don't have an Oscilliscope or logic analyzer.
// CO2 Meter K-series Example Interface
// Revised by Marv Kausch, 7/2016 at CO2 Meter <co2meter.com>
// Talks via I2C to K30/K33 Sensors and displays CO2 values
#include <Wire.h>
// We will be using the I2C hardware interface on the Arduino in
// combination with the built-in Wire library to interface.
// Arduino analog input 5 - I2C SCL
// Arduino analog input 4 - I2C SDA
/*
In this example we will do a basic read of the CO2 value and checksum
verification. For more advanced applications see the I2C Comm guide.
*/
int co2Addr = 0x68;
// This is the default address of the CO2 sensor, 7bits shifted left.
void setup() {
Serial.begin(9600);
Wire.begin ();
pinMode(13, OUTPUT); // address of the Arduino LED indicator
Serial.println("Application Note AN-102: Interface Arduino to K-30");
}
///////////////////////////////////////////////////////////////////
// Function : int readCO2()
// Returns : CO2 Value upon success, 0 upon checksum failure
// Assumes : - Wire library has been imported successfully.
// - LED is connected to IO pin 13
// - CO2 sensor address is defined in co2_addr
///////////////////////////////////////////////////////////////////
int readCO2()
{
int co2_value = 0; // Store the CO2 value inside this variable.
digitalWrite(13, HIGH); // turn on LED
// On most Arduino platforms this pin is used as an indicator light.
//////////////////////////
/* Begin Write Sequence */
//////////////////////////
Wire.beginTransmission(co2Addr);
Wire.write(0x22);
Wire.write(0x00);
Wire.write(0x08);
Wire.write(0x2A);
Wire.endTransmission();
/////////////////////////
/* End Write Sequence. */
/////////////////////////
/*
Wait 10ms for the sensor to process our command. The sensors's
primary duties are to accurately measure CO2 values. Waiting 10ms
ensures the data is properly written to RAM
*/
delay(10);
/////////////////////////
/* Begin Read Sequence */
/////////////////////////
/*
Since we requested 2 bytes from the sensor we must read in 4 bytes.
This includes the payload, checksum, and command status byte.
*/
Wire.requestFrom(co2Addr, 4);
byte i = 0;
byte buffer[4] = {0, 0, 0, 0};
/*
Wire.available() is not necessary. Implementation is obscure but we
leave it in here for portability and to future proof our code
*/
while (Wire.available())
{
buffer[i] = Wire.read();
i++;
}
///////////////////////
/* End Read Sequence */
///////////////////////
/*
Using some bitwise manipulation we will shift our buffer
into an integer for general consumption
*/
co2_value = 0;
co2_value |= buffer[1] & 0xFF;
co2_value = co2_value << 8;
co2_value |= buffer[2] & 0xFF;
byte sum = 0; //Checksum Byte
sum = buffer[0] + buffer[1] + buffer[2]; //Byte addition utilizes overflow
if (sum == buffer[3])
{
// Success!
digitalWrite(13, LOW);
return co2_value;
}
else
{
// Failure!
/*
Checksum failure can be due to a number of factors,
fuzzy electrons, sensor busy, etc.
*/
digitalWrite(13, LOW);
return 0;
}
}
void loop() {
int co2Value = readCO2();
if (co2Value > 0)
{
Serial.print("CO2 Value: ");
Serial.println(co2Value);
}
else
{
Serial.println("Checksum failed / Communication failure");
}
delay(2000);
}
Thanks in advance for your help. I really appreciate you taking the time.
Respectfully,
Chase