Code: Select all
#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 co2_value_1;
int co2_value_2;
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;
String Date,Time,Temperature, Pressure, Altitude, Humidity, Data;
void setup() {//============================================================= SETUP===============
//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), Altitude(m), Humidity(%) \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_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
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
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
//-------------------- data_logging() no values returned just save in sd card ----
void data_logging() {
String Temperature = String(bme.readTemperature(), 2);
String Pressure = String(bme.readPressure()/ 100.0F, 2);
String Altitude = String(bme.readAltitude(SEALEVELPRESSURE_HPA), 2);
String Humidity = String(bme.readHumidity(), 2);
Data = Temperature + "," + Pressure + "," + Altitude + "," + Humidity ;
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.print(co2_value_1);
myFile.print(",");
myFile.print(co2_value_2);
myFile.print(",");
myFile.println(Data);//ln adds carriage return
myFile.close();
Serial.println("done.");
} else {
Serial.println("error opening data.txt");
}
Serial.println();
}
//----------------------------------------------------End Subroutines-----------------------------------
void loop() {//##################################################### LOOP###############################
//once for sensor1 ADDRESS0x69//********
// int co2Value = readCO2();// orig
co2_value_1 = readCO2_1()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.
if (co2_value_1 > 0)
{
Serial.print("CO2 Value1: ");
Serial.println(co2_value_1);
}
else
{
Serial.println("Checksum failed / Communication failure");
}
delay(1000);
//************************************
//once for sensor2 ADDRESS0x56//********
// orig location of dataloging but if placed here then it would dataloge before it had values of Co2 moved it to end
//
co2_value_2 = readCO2_2()*10;// what i was told to do. this gives half of what the dev kit prewired one reads.
if (co2_value_2 > 0)
{
Serial.print("CO2 Value2: ");
Serial.println(co2_value_2);
}
else
{
Serial.println("Checksum failed / Communication failure");
}
delay(1000);
//************************************
// make a string for assembling the data to log:
data_logging();
delay(300000);//time between writting to sd card: delay(ms) 1000=1sec ; 900,000=15 min use this for final use 300,000 (5 min) for testing
}//##############################################################################CLOSE LOOP#########################[attachment=0]output file.png[/attachment]