Connecting CO2 sensor to Arduino UNO using the I2C protocol

Hi everyone,

I have been unsuccessful in establishing any I2C communication with my Atlas Scientific EZO CO2 sensor. The sensor works fine in UART mode, but when I try to use I2C protocol I can't get past the Wire.beginTransmission function.

Having struggled with this for a few days, I have abandoned trying to get the code from the manufacturer working, and focused on simply identifying the sensor with I2C_scanner from the Arduino IDE.

Below is the i2c scanner code, I have simply added some serialprintlines to troubleshoot, and as I mentioned, I don't get anything past "address scanning" + "1" on the serial monitor. Which leads me to believe it's something with the way I'm wiring it, despite having done so exactly as depicted in the below Atlas Scientific Sample Code link. I've also tried attaching a 4.7 kohm resistors between 5V and the clock and data pins, and I've tried using the A4 (SDA) and A5(SCL) as well as the SCA and SDA pins (pins 16 and 17).

Another thing to mention is that I've tried to wire this to an MKR Wifi 1010, and anytime I connect the SCA and SCL pins to the sensor the chrg battery light starts to flicker.

Thank you in advance and please let me know what additional info I need to share.

Atlas Scientific Sample Code

EZO CO2 Data Sheet

#include <Wire.h>

void setup() {

  Wire.begin();

  Serial.begin(9600);

  while (!Serial); // Leonardo: wait for Serial Monitor

  Serial.println("\nI2C Scanner");

}

void loop() {

  int nDevices = 0;

  Serial.println("Scanning...");

  for (byte address = 1; address < 127; ++address) {

    // The i2c_scanner uses the return value of

    // the Wire.endTransmission to see if

    // a device did acknowledge to the address.

    Serial.print("address scanning    ");    //debug

    Serial.println(address);    //debug

    Wire.beginTransmission(address);

    byte error = Wire.endTransmission();

    Serial.println("if statement for that address");    //debug

    if (error == 0) {

      Serial.print("I2C device found at address 0x");

      if (address < 16) {

        Serial.print("0");

      }

      Serial.print(address, HEX);

      Serial.println("  !");

      ++nDevices;

    } else if (error == 4) {

      Serial.print("Unknown error at address 0x");

      if (address < 16) {

        Serial.print("0");

      }

      Serial.println(address, HEX);

    }

  }

  if (nDevices == 0) {

    Serial.println("No I2C devices found\n");

  } else {

    Serial.println("done\n");

  }

  delay(5000); // Wait 5 seconds for next scan

}

Most probably you have to add pullup resistors (5-10k to 5V) to SCL and SDA. Such resistors are not present on an Uno board and usually reside on sensor breakout boards.

Thank you Dr.Diettrich. I have tried to use a 4.7K ohm resistor with same results.

What's the voltage on the SCL/SDA lines when idle?

You did not accidentally swap SCL and SDA?
Also connected GND?

Have you tested your setup with another I2C module?

Did you manually switch the device to I2C mode, as clearly described in the data sheet? The data sheet also indicates the need to add 4.7K pullups.

1 Like
  • The voltage is 4.9 V on the SCL and SDA.
  • SDA is on A4 and SCL on A5, so no I don't believe I have.
  • the GND from Arduino is connected to the - side of the power bus
  • I have another probe that is very similar to this, it's a Humidity probe from Atlas Scientific as-well. Again that one worked well with UART, but when I switch it to I2C mode and connect data and clock, the probe will behave weird and tends to switch back UART mode. I will try it again with the 4.7k resistors.

I did, by shorting green and blue. When I am in UART mode I can switch it via command from serial monitor, however once in i2C I am no longer able to send or read anything it seems.

Does the LED color indicate that the operation was successful?

I believe so, the light is solid blue which means it's I2C. I say I think so because in UART mode the light blinks green when operating properly, as opposed to the solid blue that I have. However I can see the IR light source from the probe end blinking, which leads me to believe that the sensor is sending readings.

Regarding the 4.7k pullup, do you see anything wrong with how I wired it in the above pic?

Sorry, correction on the voltage. I'm reading:

  • 4.9v on SDA.
  • 0V on SCL.

Then there is something wrong with your SCL line. Check the resistor connections.

Yes, that is a problem.

Move all connections to alternative slots on the breadboard. Breadboards are for temporary experiments and are unreliable.

Given that I'm new to much of this, I'm going to elaborate on exactly what I'm doing. I've unplugged all my leads to the sensor except for power.

On the probe end:
Putting one multi-meter lead on SDA and one on ground for a reading of 0.2V, and on SDC it's 0.38V.

The Arduino pins are outputting:

  • 4.8V on pin A4
  • 0V on pin A5
  • 4.8V on SDA
  • 0 V on pin SCL

Can either of you elaborate on what you would expect here.

No idea what "SDC" is.

For I2C to work, you must measure 4.8 to 5 V from SCL to GND, with the pullups in place on the Arduino end.

Same for SDA.

By SDC I meant SCL.

Dumb question but when you say it should be around 5V, is this on the Arduino pins, or on the probe end?

I don't understand the question. You should measure the same voltage from GND to SCL, everywhere that SCL is connected, including the sensor.

Disconnect everything from the Arduino, and run the I2C scanner program, while measuring the voltages from GND to SDA (or A4) and SCL (or A5). It should be 4.8 to 5V on both. If not, the Arduino is defective.

To avoid confusion due to transient voltage changes on SDA and SCL you could try the following minimized program, which sets up the connection but does not use it.

#include <Wire.h>
void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial); // Leonardo: wait for Serial Monitor
  Serial.println("\nI2C Scanner");
}
void loop() {}

Followed your above suggestion and still 0V on SCL even with reduced code.

I hooked up my Arduino MKR Wifi 1010 and got 1.84V on both SCL and SDA.

Ok thank you so much for your help. All this time wasted and I was dealing with a defective Arduino.

So I re-did everything on the MKR board, made sure to put the resistors in this time, which was the only thing I had yet to try. It seems to be working, I'm getting multiple address including the probe I installed.

Thanks again.

Thanks for reporting back, glad it is working!