SD output of 2 K33 CO2 sensors read 0, 0

//2CO2_to_I2Cv4_logger

// CO2 Meter K-series Example Interface
// Revised by Marv Kausch, 7/2016 at CO2 Meter <co2meter.com>
// Talks via I2C to K30/K22/K33/Logger sensors and displays CO2 values
// 12/31/09

//03/21/2023 will attempt 2 read 2 K33 CO2 sensors by modifying Arduino_to_I2C code
//provided by vendor in explicit manner 

#include <Wire.h>
#include <SD.h>//sd card
#include <SPI.h>
#include <RTClib.h>// clock

// 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 please see the I2C Comm guide.
*/
//int co2Addr =0;
int co2Addr1 = 0x69;// CO2 sensor 1
int co2Addr2 = 0x56;// CO2 sensor 2

int co2Value_1;
int co2Value_2;

// This is the default address:0x68 of the CO2 sensor, 7bits shifted left.  for sensor board 2 changed to 0X6A

RTC_PCF8523 rtc;// clock on datalogger

// create file
File myFile;
String Date,Time,CO2_1,CO2_2 ,Data;



void setup() {//=============================================================

  //start clock
    rtc.begin();
    
  //serial
  Serial.begin(9600);
  delay(2000);

   //clock 
 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }
    if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }  // close clock

  // SD card initialize

  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  myFile = SD.open("data.txt", FILE_WRITE); 
  if (myFile) {
    myFile.println( "Date, Time, CO2_1(ppm), CO2_2(ppm)) \r\n");
    myFile.close();
  } 
  else {
    Serial.println("error opening data.txt");
  }

  
  
  Wire.begin ();
  pinMode(13, OUTPUT); // address of the Arduino LED indicator
  Serial.println("Application Note AN-102: Interface Arduino to two  K-333");

  
}//==================================================== close setup Loop


///////////////////////////////////////////////////////////////////
// Function : int readCO2_1()
// 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_1()
{//+++++++++++++++++++++++++++++++++++++++++++++++++  read CO2()function definition
  int co2_value_1 = 0;  // We will 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(0x69);
 // Wire.beginTransmission(co2Addr1);
  Wire.write(0x22);
  Wire.write(0x00);
  Wire.write(0x08);
  Wire.write(0x2A);

  Wire.endTransmission();

  /////////////////////////
  /* End Write Sequence. */
  /////////////////////////

  /*
    We wait 10ms for the sensor to process our command.
    The sensors's primary duties are to accurately
    measure CO2 values. Waiting 10ms will ensure 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(0x69, 4);

  byte i = 0;
  byte buffer[4] = {0, 0, 0, 0};

  /*
    Wire.available() is not nessessary. 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_1 = 0;
  co2_value_1 |= buffer[1] & 0xFF;
  co2_value_1 = co2_value_1 << 8;
  co2_value_1 |= 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_1;
  }
  else
  {
    // Failure!
    /*
      Checksum failure can be due to a number of factors,
      fuzzy electrons, sensor busy, etc.
    */

    digitalWrite(13, LOW);
    return 0;
  }
}//++++++++++++++++++++++++++++++++++++++++++ close the read CO2 function definition

///////////////////////////////////////////////////////////////////
// Function : int readCO2_2()
// 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_2()
{//+++++++++++++++++++++++++++++++++++++++++++++++++  read CO2()function definition
  int co2_value_2 = 0;  // We will 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(0x56);
  Wire.write(0x22);
  Wire.write(0x00);
  Wire.write(0x08);
  Wire.write(0x2A);

  Wire.endTransmission();

  /////////////////////////
  /* End Write Sequence. */
  /////////////////////////

  /*
    We wait 10ms for the sensor to process our command.
    The sensors's primary duties are to accurately
    measure CO2 values. Waiting 10ms will ensure 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(0x56, 4);

  byte i = 0;
  byte buffer[4] = {0, 0, 0, 0};

  /*
    Wire.available() is not nessessary. 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_2 = 0;
  co2_value_2 |= buffer[1] & 0xFF;
  co2_value_2 = co2_value_2 << 8;
  co2_value_2 |= 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_2;
  }
  else
  {
    // Failure!
    /*
      Checksum failure can be due to a number of factors,
      fuzzy electrons, sensor busy, etc.
    */

    digitalWrite(13, LOW);
    return 0;
  }
}//++++++++++++++++++++++++++++++++++++++++++ close the read CO2 function definition




void loop() {//#####################################################void loop

   // make a string for assembling the data to log:
     data_logging();
     
     delay(10000);//time between writting to sd card: delay(ms) 1000=1sec ; 900,000=15 min use this for final use 20,000 for testing


 //once for sensor1 ADDRESS0x69//****************************************************************

 // int co2Value = readCO2();// orig
 int co2Value_1 = readCO2_1()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.

  
  if (co2Value_1 > 0)
  {
    Serial.print("CO2 Value1: ");
    Serial.println(co2Value_1);
  }
  else
  {
    Serial.println("Checksum failed / Communication failure");
  }
  delay(2000);
  //********************************************************************done with CO2value1

  
//once for sensor2 ADDRESS0x56//****************************************************************

 // int co2Value = readCO2();// orig
 int co2Value_2 = readCO2_2()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.

  
  if (co2Value_2 > 0)
  {
    Serial.print("CO2 Value2: ");
    Serial.println(co2Value_2);
  }
  else
  {
    Serial.println("Checksum failed / Communication failure");
  }
  delay(2000);
  
}//##############################################################################close loop

//--------------------subroutines------------------------------------

void data_logging() {
  String CO2_1 = String(co2Value_1);
  String CO2_2 = String(co2Value_2);
 
  Data = CO2_1 + "," + CO2_2  ;
//  

  Serial.print("Save data: ");
  Serial.println(Data);

  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    Serial.print("Writing to data.txt...");
    
    //time stamp
    DateTime now = rtc.now();
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(",");
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(",");//delimeter between time and data
    //
    myFile.println(Data);//ln adds carriage return
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening data.txt");
  }  
  Serial.println();
}

//--------------------------

output file read:

Avoid using Strings with Arduino. They cause memory problems and program crashes, and are never necessary.

You can get rid of this

  String CO2_1 = String(co2Value_1);
  String CO2_2 = String(co2Value_2);
 
  Data = CO2_1 + "," + CO2_2  ;
...

myFile.println(Data);//ln adds carriage return

and replace that last line with something like this:

    myFile.print(co2Value_1);
    myFile.print(",");
    myFile.println(co2Value_2); //ln adds carriage return

Thanks for the suggestion i did as you mentioned but i still get 0,0 for the sensor output.

the weired thing is that i do get the correct ouput on serial output:
image

But the actual output text file shows 0,0

image

//2CO2_to_I2Cv4_logger

// CO2 Meter K-series Example Interface
// Revised by Marv Kausch, 7/2016 at CO2 Meter <co2meter.com>
// Talks via I2C to K30/K22/K33/Logger sensors and displays CO2 values
// 12/31/09

//03/21/2023 will attempt 2 read 2 K33 CO2 sensors by modifying Arduino_to_I2C code
//provided by vendor in explicit manner 

#include <Wire.h>
#include <SD.h>//sd card
#include <SPI.h>
#include <RTClib.h>// clock

// 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 please see the I2C Comm guide.
*/
//int co2Addr =0;
int co2Addr1 = 0x69;// CO2 sensor 1
int co2Addr2 = 0x56;// CO2 sensor 2

int co2Value_1;
int co2Value_2;

// This is the default address:0x68 of the CO2 sensor, 7bits shifted left.  for sensor board 2 changed to 0X6A

RTC_PCF8523 rtc;// clock on datalogger

// create file
File myFile;
String Date,Time,CO2_1,CO2_2 ,Data;



void setup() {//=============================================================

  //start clock
    rtc.begin();
    
  //serial
  Serial.begin(9600);
  delay(2000);

   //clock 
 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }
    if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }  // close clock

  // SD card initialize

  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  myFile = SD.open("data.txt", FILE_WRITE); 
  if (myFile) {
    myFile.println( "Date, Time, CO2_1(ppm), CO2_2(ppm)) \r\n");
    myFile.close();
  } 
  else {
    Serial.println("error opening data.txt");
  }

  
  
  Wire.begin ();
  pinMode(13, OUTPUT); // address of the Arduino LED indicator
  Serial.println("Application Note AN-102: Interface Arduino to two  K-333");

  
}//==================================================== close setup Loop


///////////////////////////////////////////////////////////////////
// Function : int readCO2_1()
// 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_1()
{//+++++++++++++++++++++++++++++++++++++++++++++++++  read CO2()function definition
  int co2_value_1 = 0;  // We will 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(0x69);
 // Wire.beginTransmission(co2Addr1);
  Wire.write(0x22);
  Wire.write(0x00);
  Wire.write(0x08);
  Wire.write(0x2A);

  Wire.endTransmission();

  /////////////////////////
  /* End Write Sequence. */
  /////////////////////////

  /*
    We wait 10ms for the sensor to process our command.
    The sensors's primary duties are to accurately
    measure CO2 values. Waiting 10ms will ensure 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(0x69, 4);

  byte i = 0;
  byte buffer[4] = {0, 0, 0, 0};

  /*
    Wire.available() is not nessessary. 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_1 = 0;
  co2_value_1 |= buffer[1] & 0xFF;
  co2_value_1 = co2_value_1 << 8;
  co2_value_1 |= 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_1;
  }
  else
  {
    // Failure!
    /*
      Checksum failure can be due to a number of factors,
      fuzzy electrons, sensor busy, etc.
    */

    digitalWrite(13, LOW);
    return 0;
  }
}//++++++++++++++++++++++++++++++++++++++++++ close the read CO2 function definition

///////////////////////////////////////////////////////////////////
// Function : int readCO2_2()
// 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_2()
{//+++++++++++++++++++++++++++++++++++++++++++++++++  read CO2()function definition
  int co2_value_2 = 0;  // We will 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(0x56);
  Wire.write(0x22);
  Wire.write(0x00);
  Wire.write(0x08);
  Wire.write(0x2A);

  Wire.endTransmission();

  /////////////////////////
  /* End Write Sequence. */
  /////////////////////////

  /*
    We wait 10ms for the sensor to process our command.
    The sensors's primary duties are to accurately
    measure CO2 values. Waiting 10ms will ensure 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(0x56, 4);

  byte i = 0;
  byte buffer[4] = {0, 0, 0, 0};

  /*
    Wire.available() is not nessessary. 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_2 = 0;
  co2_value_2 |= buffer[1] & 0xFF;
  co2_value_2 = co2_value_2 << 8;
  co2_value_2 |= 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_2;
  }
  else
  {
    // Failure!
    /*
      Checksum failure can be due to a number of factors,
      fuzzy electrons, sensor busy, etc.
    */

    digitalWrite(13, LOW);
    return 0;
  }
}//++++++++++++++++++++++++++++++++++++++++++ close the read CO2 function definition




void loop() {//#####################################################void loop

   // make a string for assembling the data to log:
     data_logging();
     
     delay(10000);//time between writting to sd card: delay(ms) 1000=1sec ; 900,000=15 min use this for final use 20,000 for testing


 //once for sensor1 ADDRESS0x69//****************************************************************

 // int co2Value = readCO2();// orig
 int co2Value_1 = readCO2_1()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.

  
  if (co2Value_1 > 0)
  {
    Serial.print("CO2 Value1: ");
    Serial.println(co2Value_1);
  }
  else
  {
    Serial.println("Checksum failed / Communication failure");
  }
  delay(2000);
  //********************************************************************done with CO2value1

  
//once for sensor2 ADDRESS0x56//****************************************************************

 // int co2Value = readCO2();// orig
 int co2Value_2 = readCO2_2()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.

  
  if (co2Value_2 > 0)
  {
    Serial.print("CO2 Value2: ");
    Serial.println(co2Value_2);
  }
  else
  {
    Serial.println("Checksum failed / Communication failure");
  }
  delay(2000);
  
}//##############################################################################close loop

//--------------------subroutines------------------------------------

void data_logging() {
//  String CO2_1 = String(co2Value_1);
//  String CO2_2 = String(co2Value_2);
// 
//  Data = CO2_1 + "," + CO2_2  ;
//  

  Serial.print("Save data: ");
  Serial.println(Data);

  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    Serial.print("Writing to data.txt...");
    
    //time stamp
    DateTime now = rtc.now();
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(",");
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(",");//delimeter between time and data
    //
   // myFile.println(Data);//ln adds carriage return
   myFile.print(co2Value_1);
   myFile.print(" , ");
   myFile.println(co2Value_2);
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening data.txt");
  }  
  Serial.println();
}

//--------------------------

This is a local "co2Value_1" and disappears when the loop function exits. Look up "scope in C/C++".

You also have a global variable named co2Value_1, which is never modified. That is what the SD logging routine is accessing.

Your program structure is very poor, very redundant, with lots of pointless delays and is very difficult to follow.

I agree. about the redundancy. I did not know how to pass two different addresses to read CO2 function if you know how to do that I would love the input.

Currently working on the removing the serial prints and using echo to serial console.

I am doing the best i can... sorry to make two I2C sensors output with my limited knowledge and little help from the manufacturer.

Functions take arguments, like addresses, device numbers, etc.. And since the results are global, you don't need to return a value.

I am doing the best i can

Probably not. It would help a great deal to study the language basics.

Suggestions:

In loop:

readCO2_value(1);
readCO2_value(2);

The combined function:

void readCO2_value(byte device_number) {

byte address;

if(device_number == 1)  address = 0x69;
else address = 0x56;

Wire.beginTransmission(address);
...

if (device_number == 1)  co2Value_1 = result; // update correct global value
else 
// etc.

thank you. Sorry to be doing so poorly i have studied the language but dont use it often enough to keep all the nuances fresh.

Hardly "nuances".

The POINT of a function is that it takes arguments, so that multiple services can be condensed into a single block of code, avoiding repetition.

when i explicitly put the value rather than use the variable address it worked but dont undestand why it wont work when i use the variable address which was globally defined as byte.

error:

F:\telework transfer files\Stuhl projects\Outside CO2 controlled Hives\K30I2C\2CO2_BME280_I2Cv4_loggervs8\2CO2_BME280_I2Cv4_loggervs8.ino: In function 'int readCO2(int)':
F:\telework transfer files\Stuhl projects\Outside CO2 controlled Hives\K30I2C\2CO2_BME280_I2Cv4_loggervs8\2CO2_BME280_I2Cv4_loggervs8.ino:163:30: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   Wire.requestFrom(address, 4);
                              ^
In file included from F:\telework transfer files\Stuhl projects\Outside CO2 controlled Hives\K30I2C\2CO2_BME280_I2Cv4_loggervs8\2CO2_BME280_I2Cv4_loggervs8.ino:14:0:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
     uint8_t requestFrom(int, int);
             ^~~~~~~~~~~
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
     uint8_t requestFrom(uint8_t, uint8_t);

this is my program:

#include <Wire.h>
#include <SD.h>//sd card
#include <SPI.h>
#include <RTClib.h>// clock
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1017)// orig 1013.25 the local is 1017


//Global variable declaration
int pinOut=8; // pin 8 on(high)/off(low) of the Normally closed wired relay
int sensor; //CO2 sensor number
int co2_value_1, co2_value_2;
byte address;


RTC_PCF8523 rtc;// clock on datalogger
Adafruit_BME280 bme; // I2C for T, RH, altitude, atm press

// create file
File myFile;
//String Date,Time,CO2_1,CO2_2;
int Temperature, Pressure, Humidity, RelayState;
String Date,Time;

void setup() {//============================================================= SETUP===============

  //relay control pin 8
  pinMode(8,OUTPUT);
  
  //start clock
  
  //serial
  Serial.begin(9600);
  delay(2000);

   //clock 
 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while (1) delay(10);
  }
     if (! rtc.initialized() || rtc.lostPower()) {
     Serial.println("RTC is NOT running, let's set the time!");
     
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 
  }  
  
  rtc.start();// added 4/4/2023 from pcf8523 code

  //bme280 sensor
  unsigned status;
  status = bme.begin();
  
   if (!status) {
    Serial.println("BME280 not connected properly. Check circuit!");
    while (1); 
  }
  
  // SD card initialize

  Serial.print("Initializing SD card...");
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  myFile = SD.open("data.txt", FILE_WRITE); 
  if (myFile) {
    myFile.println( "Date, Time, CO2_1(ppm), CO2_2(ppm),Temperature(°C), Pressure(hPa), Humidity(%), RelayState(1(on)or 0(off)) \r\n");
    myFile.close();
  } 
  else {
    Serial.println("error opening data.txt");
  }

  Wire.begin ();
  pinMode(13, OUTPUT); // address of the Arduino LED indicator
 // Serial.println("Application Note AN-102: Interface Arduino to two  K-333");

  
}//==================================================== close SETUP==========

//====================SUBROUTINES==================================
///////////////////////////////////////////////////////////////////
// Function : int readCO2(int sensor)
// 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 sensor)
{//+++++++++++++++++++++++++++++++++++++++++++++++++  read CO2()function definition
 // byte address=0;
  
  if(sensor == 1) {
       address=0x69;
       
  }else { 
      address=0x56; }
  

  
  digitalWrite(13, HIGH);  // turn on LED
  // On most Arduino platforms this pin is used as an indicator light.

  //////////////////////////
  /* Begin Write Sequence */
  //////////////////////////
  
  Wire.beginTransmission(address);
  Wire.write(0x22);
  Wire.write(0x00);
  Wire.write(0x08);
  Wire.write(0x2A);

  Wire.endTransmission();

  /////////////////////////
  /* End Write Sequence. */
  /////////////////////////

  /*
    We wait 10ms for the sensor to process our command.
    The sensors's primary duties are to accurately
    measure CO2 values. Waiting 10ms will ensure 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(address, 4);

  byte i = 0;
  byte buffer[4] = {0, 0, 0, 0};

  /*
    Wire.available() is not nessessary. 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
  */

  if ( sensor ==1) {  
      int co2_value_1 = 0;
      co2_value_1 |= buffer[1] & 0xFF;
      co2_value_1 = co2_value_1 << 8;
      co2_value_1 |= 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_1;
    } else {
          // Failure!
          /*
            Checksum failure can be due to a number of factors,
            fuzzy electrons, sensor busy, etc.
          */
      
          digitalWrite(13, LOW);
          return 0;
    }
  }else{
      int co2_value_2 = 0;
      co2_value_2 |= buffer[1] & 0xFF;
      co2_value_2 = co2_value_1 << 8;
      co2_value_2 |= 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_2;
    }else {
      // Failure!
      /*
        Checksum failure can be due to a number of factors,
        fuzzy electrons, sensor busy, etc.
      */
  
      digitalWrite(13, LOW);
      return 0; 
  }
  }
}//++++++++++++++++++++++++++++++++++++++++++ close the read CO2 function definition


//-------------------- data_logging() no values returned just save in sd card ----

void data_logging(int co2_value_1, int co2_value_2) {

  myFile = SD.open("data.txt", FILE_WRITE);
  if (myFile) {
    Serial.print("Writing to data.txt...");
    
    //time stamp
    DateTime now = rtc.now();
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(",");
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(",");//delimeter between time and data
    myFile.print(co2_value_1);
    myFile.print(",");
    myFile.print(co2_value_2);
    myFile.print(",");
    myFile.print(bme.readTemperature());
    myFile.print(",");
    myFile.print(bme.readPressure()/100.0F);
    myFile.print(",");
    myFile.print(bme.readHumidity());
    myFile.print(",");
    myFile.print(digitalRead(8));
    myFile.println( );//ln adds carriage return
    myFile.close();
    Serial.println("done.");
  } else {
    Serial.println("error opening data.txt");
  }  
  Serial.println();
}

//----------------------------------------------------End Subroutines-----------------------------------


void loop() {//##################################################### LOOP###############################

   int co2_value_1 = readCO2(1)*10;// what i was told to do. this gives half of what the dev kit prewired one reads.
   int co2_value_2 = readCO2(2)*10;// what i was told to do. this gives half of what the dev kit prewired one reads.

  delay(1000);
//************************************

  // test if  the CO2 tank need valve turned on to maintain SetCO2(ppm) will turn on if 50ppm below and off if 50ppm above SetCO2
  
  int SetCO2=1000;// CO2 level you want to maintain
  
  if(co2_value_1 >= SetCO2+50){
      digitalWrite(pinOut, LOW); //off
  }else {
      digitalWrite(pinOut, HIGH);}
  delay(500);


//***********************************

     // send data to SD card:
     data_logging(co2_value_1, co2_value_2);
     
     delay(120000);//time between writting to sd card: delay(ms) 1000=1sec ; 900,000=15 min use this for final use 120,000 (2 min) for testing
  
}//##############################################################################CLOSE LOOP#########################

The message you posted was a warning, not a fatal error. I see no obvious reason why the code should not work, but I also see no reason to make "address" global.

I changed address to local variable and it worked fine.

Is there anything i can so the error posted before is cleared?

The warning is simply a complaint about not finding an exact match between the expected types of function arguments and the "byte" declaration of address.

Declare address as int or uint8_t to eliminate the issue.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.