Low memory available when using BME280

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mromero
 
Posts: 94
Joined: Fri Mar 18, 2016 12:10 pm

Low memory available when using BME280

Post by mromero »

I have a project that reads 2 CO2 sensors and one BME280 sensor. I followed the example code for the BME280 sensor. I started with one program that wrote the BME280 output to SD card based on you example and i also wrote a separate program for the 2 CO2 sensors to write to SD card. All my components are adafruit except the CO2 sensors. I kind of wrote everything out explicitly and joined the two codes into one program. I get a low memory available error and for some reason. Also for some reason even though the write to sd file worked fine in my two separate programs it did not on the combined for some reason. I did not change the code to open the file.

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]
Attachments
output file.png
output file.png (10.63 KiB) Viewed 132 times

User avatar
dastels
 
Posts: 15608
Joined: Tue Oct 20, 2015 3:22 pm

Re: Low memory available when using BME280

Post by dastels »

Let's deal with the memory issue first.
1) what are you running this on?
2) at the end of the build output, what is the line that tells how much memory your program uses?

Dave

User avatar
mromero
 
Posts: 94
Joined: Fri Mar 18, 2016 12:10 pm

Re: Low memory available when using BME280

Post by mromero »

output file.png
output file.png (8.92 KiB) Viewed 127 times
Image

User avatar
mromero
 
Posts: 94
Joined: Fri Mar 18, 2016 12:10 pm

Re: Low memory available when using BME280

Post by mromero »

was able to lower the requiremnts a bit by changing the string operations to int .
I also tried 3x ways to make ther readCO2() a function where i passed 1 ( address 0x69) or a 2 ( address 0x59) but could not get it to work correctly hence the verbose way i coded it.

Code: Select all

//2CO2_BME280_I2Cv4_loggerv6  04/05/2023

#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;
int Temperature, Pressure, Altitude, Humidity;
String Date,Time;

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() {

  int Temperature = (bme.readTemperature(), 2);
  int Pressure = (bme.readPressure()/ 100.0F, 2);
 // int Altitude = int(bme.readAltitude(SEALEVELPRESSURE_HPA), 2);
  int Humidity = (bme.readHumidity(), 2);

 // String 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.print(Temperature);
    myFile.print(",");
    myFile.print(Pressure);
    myFile.print(",");
    myFile.print(Humidity);
    myFile.print(",");
    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###############################


 //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(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#########################
Attachments
output file.png
output file.png (7.68 KiB) Viewed 127 times

User avatar
mromero
 
Posts: 94
Joined: Fri Mar 18, 2016 12:10 pm

Re: Low memory available when using BME280

Post by mromero »

the output of the code is incorrect
output file.png
output file.png (13.74 KiB) Viewed 127 times

User avatar
mromero
 
Posts: 94
Joined: Fri Mar 18, 2016 12:10 pm

Re: Low memory available when using BME280

Post by mromero »

ok got the output to work correctly but still get low memory and still need to add a relay which will have one more variable. Is there something else i can do to lower the memory usage in the Global variables

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;
int Temperature, Pressure, Altitude, Humidity;
String Date,Time;

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() {

//  int Temperature = (bme.readTemperature(), 2);
//  Serial.print(Temperature());
//  Serial.print(",");
//  Serial.print(bme.readTemperature());
//  Serial.print(",");
//  int Pressure = (bme.readPressure()/ 100.0F, 2);
//   Serial.print(bme.readPressure());
//  Serial.print(",");
// // int Altitude = int(bme.readAltitude(SEALEVELPRESSURE_HPA), 2);
//  int Humidity = (bme.readHumidity(), 2);
//     Serial.print(bme.readHumidity());
//  Serial.print(",");

 // String 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.print(bme.readTemperature());
    myFile.print(",");
    myFile.print(bme.readPressure()/100.0F);
    myFile.print(",");
    myFile.print(bme.readHumidity());
    myFile.print(",");
    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###############################


 //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(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#########################
Attachments
output file.png
output file.png (16.54 KiB) Viewed 124 times

User avatar
dastels
 
Posts: 15608
Joined: Tue Oct 20, 2015 3:22 pm

Re: Low memory available when using BME280

Post by dastels »

It looks like it will be a constant struggle. You could move to a more advanced processor with more memory. The code is unlikely to need any changes, which is an advantage of the Arduino platform.

Dave

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”