Hello all,
Thank you in advance for any help! I am running an Arduino Due, an EZO-CO2 sensor from Atlas Scientific, and two LED backpacks from Adafruit.
I am using i2C(SCL/SDA) to communicate between the Due and the sensor/backpacks.
I am using Atlas Scientific's base code with some minor modifications to operate the setup.
//This code will work on an Arduino Uno and Mega
//This code was written to be easy to understand.
//Modify this code as you see fit.
//This code will output data to the Arduino serial monitor.
//Type commands into the Arduino serial monitor to control the EZO Co2 sensor.
//This code was written in the Arduino 1.8.9 IDE
//This code was last tested 7/2019
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_7segment matrix = Adafruit_7segment();
#include <Wire.h> //enable I2C.
#define address 105 //default I2C ID number for EZO CO2 sensor.
char computerdata[20]; //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte received_from_computer = 0; //we need to know how many characters have been received.
byte serial_event = false; //a flag to signal when data has been received from the pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char Co2_data[20]; //we make a 20-byte character array to hold incoming data from the Co2 sensor.
byte in_char = 0; //used as a 1 byte buffer to store inbound bytes from the Co2 sensor.
byte i = 0; //counter used for Co2_data array.
int time_ = 250; //used to set the delay needed to process the command sent to the EZO Co2 sensor.
int Co2_int; //int var used to hold the value of the Co2.
int a=0;
int b=100;
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
}
void serialEvent() { //this interrupt will trigger when the data coming from the serial monitor(pc/mac/other) is received.
received_from_computer = Serial.readBytesUntil(13, computerdata, 20); //we read the data sent from the serial monitor(pc/mac/other) until we see a <CR>. We also count how many characters have been received.
computerdata[received_from_computer] = 0; //stop the buffer from transmitting leftovers or garbage.
serial_event = true; //set the serial event flag.
}
void loop() { //the main loop.
if (serial_event == true) { //if a command was sent to the EZO device.
for (i = 0; i <= received_from_computer; i++) { //set all char to lower case, this is just so this exact sample code can recognize the "sleep" command.
computerdata[i] = tolower(computerdata[i]); //"Sleep" ≠ "sleep"
}
i=0; //reset i, we will need it later
Wire.beginTransmission(address); //call the circuit by its ID number.
Wire.write(computerdata); //transmit the command that was sent through the serial port.
Wire.endTransmission(); //end the I2C data transmission.
if (strcmp(computerdata, "sleep") != 0) { //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.
//if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the Co2 sensor.
delay(time_); //wait the correct amount of time for the circuit to complete its instruction.
Wire.requestFrom(address, 20, 1); //call the circuit and request 20 bytes (this may be more than we need)
code = Wire.read(); //the first byte is the response code, we read this separately.
switch (code) { //switch case based on what the response code is.
case 1: //decimal 1.
Serial.println("Success"); //means the command was successful.
break; //exits the switch case.
case 2: //decimal 2.
Serial.println("Failed"); //means the command has failed.
break; //exits the switch case.
case 254: //decimal 254.
Serial.println("Pending"); //means the command has not yet been finished calculating.
break; //exits the switch case.
case 255: //decimal 255.
Serial.println("No Data"); //means there is no further data to send.
break; //exits the switch case.
}
while (Wire.available()) { //are there bytes to receive.
in_char = Wire.read(); //receive a byte.
Co2_data[i] = in_char; //load this byte into our array.
i += 1; //incur the counter for the array element.
if (in_char == 0) { //if we see that we have been sent a null command.
i = 0; //reset the counter i to 0.
break; //exit the while loop.
}
}
Serial.println(Co2_data); //print the data.
}
serial_event = false; //reset the serial event flag
}
//Uncomment this section if you want to take the Co2 value and convert it into integer number.
//Co2_int=atoi(Co2_data);
matrix.begin(0x71); //LED Backpack1
matrix.print(a); //LED Backpack1
matrix.writeDisplay(); //LED Backpack1
a=a+1; //LED Backpack1
delay(1000); //Wait 1 second
matrix.begin(0x72); //LED Backpack2
matrix.print(b); //LED Backpack2
matrix.writeDisplay(); //LED Backpack2
b=b-1; //LED Backpack2
delay(1000); //Wait 1 second
}
I am able to get the EZO-CO2 sensor to work on its own, and to work along with either one of the LED backpacks, but not both. I am wondering if I am pulling too much current through the Due? I am powering the three devices via the 5V on the Due, which I thought could supply 800 mA (the CO2 pulls 45mA and a single backpack pulls 40mA). I did read that only a max of 120mA is available through the pins 1-54,(pins 20 and 21 are SDA and SCL respectively) but that one pin can only have a max of 40mA. Could I be going over that limit? I contacted Atlas Scientific and they mentioned that I may be running out of current.
I have tried using various pull-up resistors on the i2C line and providing external power or just powered through the USB. I don't get any error messages when I attempt to communicate, I only receive the message "No Data", which corresponds to code 255-meaning there is no data to send. An older datasheet says "No Data – there is no pending request, so there is no data to return from the circuit". I think this means that commands I send are not reaching the sensor but the request for data is? Also, neither LED backpack lights up, but the variables do change.
One last thing to note, if I disconnect the power from one of the backpacks nothing changes (with the SCL/SDA still connected), but as soon as I remove the SCL line from one of the backpacks the other backpack and the CO2 sensor begin working.
Thanks again for any help and I apologize for any errors!