Connecting two BM680 sensors, RTC DS1307 via I2C on Arudino UNO

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Post Reply
User avatar
maha1998
 
Posts: 1
Joined: Fri Aug 19, 2022 6:22 am

Connecting two BM680 sensors, RTC DS1307 via I2C on Arudino UNO

Post by maha1998 »

Hello,

I wanted to add a second BME 680 sensor to a working project to measure the environmental data (including timestamp) and safe it on a SD card/ print it on the Serial Monitor. The SD card is connected SPI, the BME680 sensor and the RTC module were connected via I2C. When I added the second sensor I changed the I2C adress for one on 0x76, the default one for the first sensor is 0x77. To ensure that both sensors have different adresses, the code reads them in the beginning. But since I installed the second sensor and have them as bme_1 and bme_2 in the code, it does only deliver 0 values for all the measurement attributes. The working code for only 1 sensor delivers valid values. Does anyone know if I need to set something differently to have both sensors working?

It is my first project with Arduino and programming, so I assume there could also be some more improvements in the code.

Code: Select all

#include <Wire.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Adafruit_I2CDevice.h>
#include "RTClib.h"

#define SEALEVELPRESSURE_HPA (1022)
#define LED_RED 4 
#define LED_GREEN 2 

Adafruit_BME680 bme_1; // I2C
Adafruit_BME680 bme_2; // I2C
RTC_DS1307 rtc; //I2C
File dataFile; //MISO at 12 in purple, MOSI at 13 in white
DateTime now;
int measurement_frequency = 5000;

//Air Quality Index calculation https://github.com/G6EJD/680-Example/blob/master/ESP32_bme680_CC_demo_02.ino
float hum_weighting = 0.25; // so hum effect is 25% of the total air quality score
float gas_weighting = 0.75; // so gas effect is 75% of the total air quality score

float hum_score_1, gas_score_1,hum_score_2, gas_score_2;
float gas_reference_1 = 250000;
float hum_reference_1 = 40;
float gas_reference_2 = 250000;
float hum_reference_2 = 40;
int   getgasreference_count = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  //digitalWrite(LED_RED, HIGH)
  //digitalWrite(LED_GREEN, HIGH)

  Serial.begin(9600);
  Serial.print("test");
  digitalWrite(LED_GREEN, HIGH); //blink green that program is working
  delay(50);
  digitalWrite(LED_GREEN, LOW);

  //RTC module initialization
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    digitalWrite(LED_RED, HIGH);
    while (1);
  }
  else {
    Serial.println("Couldn't find RTC");
  }
  digitalWrite(LED_RED, LOW);

  //SC card module initialization
  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    digitalWrite(LED_RED, HIGH);
    while (1);
    digitalWrite(LED_RED, LOW);
  }
  Serial.println("initialization done.");

  //BME680 module initialization
  if (!bme_1.begin(0x77)) {
    Serial.println(F("Could not find a valid BME680_1 sensor, check wiring!"));
    digitalWrite(LED_RED, HIGH);
    // while (1);
  }
  else {
    Serial.println("Found BME_1");
    digitalWrite(LED_GREEN, HIGH);
    delay(100);
    digitalWrite(LED_GREEN, LOW);
  }
  if (!bme_2.begin(0x76)) {
    Serial.println(F("Could not find a valid BME680_2 sensor, check wiring!"));
    digitalWrite(LED_RED, HIGH);
    // while (1);
  }
  else {
    Serial.println("Found BME_2");
    digitalWrite(LED_GREEN, HIGH);
    delay(100);
    digitalWrite(LED_GREEN, LOW);
  }
  
//test 2

  //bme settings
  bme_1.setTemperatureOversampling(BME680_OS_8X);
  bme_1.setHumidityOversampling(BME680_OS_2X);
  bme_1.setPressureOversampling(BME680_OS_4X);
  bme_1.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme_1.setGasHeater(320, 150); // 320*C for 150 ms
  bme_2.setTemperatureOversampling(BME680_OS_8X);
  bme_2.setHumidityOversampling(BME680_OS_2X);
  bme_2.setPressureOversampling(BME680_OS_4X);
  bme_2.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme_2.setGasHeater(320, 150); // 320*C for 150 ms
  
  GetGasReference();
  Serial.println("Got Gas Reference");
  
  dataFile = SD.open("data.txt", FILE_WRITE);
  digitalWrite(LED_GREEN, HIGH);
  dataFile.close();
  digitalWrite(LED_GREEN, LOW);

  Serial.println(F("new measurement started"));
}

void loop() {

  // Tell BME680 to begin measurement.

  unsigned long endTime_1 = bme_1.beginReading();
  unsigned long endTime_2 = bme_2.beginReading();
  if (endTime_1 == 0) {
    Serial.println(F("Failed to begin reading BME_1:("));
    return;
  }
 
  if (endTime_2 == 0) {
    Serial.println(F("Failed to begin reading BME_2:("));
    return;
  }  //BME_1
  float current_humidity_1 = bme_1.readHumidity();
  if (current_humidity_1 >= 38 && current_humidity_1 <= 42) {
    hum_score_1 = 0.25 * 100; // Humidity +/-5% around optimum
  }
  else
  { //sub-optimal
    if (current_humidity_1 < 38)
      hum_score_1 = 0.25 / hum_reference_1 * current_humidity_1 * 100;
    else {
      hum_score_1 = ((-0.25 / (100 - hum_reference_1) * current_humidity_1) + 0.416666) * 100;
    }
  }

  //Calculate gas contribution to IAQ index
  float gas_lower_limit = 5000;   // Bad air quality limit
  float gas_upper_limit = 50000;  // Good air quality limit
  if (gas_reference_1 > gas_upper_limit) gas_reference_1 = gas_upper_limit;
  if (gas_reference_1 < gas_lower_limit) gas_reference_1 = gas_lower_limit;
  gas_score_1 = (0.75 / (gas_upper_limit - gas_lower_limit) * gas_reference_1 - (gas_lower_limit * (0.75 / (gas_upper_limit - gas_lower_limit)))) * 100;

  //Combine results for the final IAQ index value (0-100% where 100% is good quality air)
  float air_quality_score_1 = hum_score_1 + gas_score_1;

  //BME_2
  float current_humidity_2 = bme_2.readHumidity();
  if (current_humidity_2 >= 38 && current_humidity_2 <= 42) {
    hum_score_2 = 0.25 * 100; // Humidity +/-5% around optimum
  }
  else
  { //sub-optimal
    if (current_humidity_2 < 38)
      hum_score_2 = 0.25 / hum_reference_2 * current_humidity_2 * 100;
    else {
      hum_score_2 = ((-0.25 / (100 - hum_reference_2) * current_humidity_2) + 0.416666) * 100;
    }
  }

  //Calculate gas contribution to IAQ index
 
  if (gas_reference_2 > gas_upper_limit) gas_reference_2 = gas_upper_limit;
  if (gas_reference_2 < gas_lower_limit) gas_reference_2 = gas_lower_limit;
  gas_score_2 = (0.75 / (gas_upper_limit - gas_lower_limit) * gas_reference_2 - (gas_lower_limit * (0.75 / (gas_upper_limit - gas_lower_limit)))) * 100;

  //Combine results for the final IAQ index value (0-100% where 100% is good quality air)
  float air_quality_score_2 = hum_score_2 + gas_score_2;

  //create timestamp value
  now = rtc.now();

  //print on SD

  dataFile = SD.open("data.txt", FILE_WRITE);


  digitalWrite(LED_GREEN, HIGH);
  dataFile.print(now.year(), DEC); dataFile.print('/');
  dataFile.print(now.month(), DEC); dataFile.print('/');
  dataFile.print(now.day(), DEC); dataFile.print(F(","));
  dataFile.print(now.year(), DEC); dataFile.print('/');
  dataFile.print(now.month(), DEC); dataFile.print('/');
  dataFile.print(now.day(), DEC); dataFile.print(F(" "));
  dataFile.print(now.hour(), DEC); dataFile.print(':');
  dataFile.print(now.minute(), DEC); dataFile.print(':');
  dataFile.print(now.second(), DEC);  dataFile.print(F(","));
  dataFile.print(bme_1.temperature); dataFile.print(F(","));
  dataFile.print(bme_1.pressure / 100.0); dataFile.print(F(","));
  dataFile.print(bme_1.humidity); dataFile.print(F(","));
  dataFile.print(bme_1.gas_resistance / 1000.0); dataFile.print(F(","));
  dataFile.print(String(air_quality_score_1)); dataFile.print(F(","));
  dataFile.print(CalculateAQI(air_quality_score_1)); dataFile.print(F(","));
  dataFile.println(bme_1.readAltitude(SEALEVELPRESSURE_HPA));
  dataFile.print(bme_2.temperature); dataFile.print(F(","));
  dataFile.print(bme_2.pressure / 100.0); dataFile.print(F(","));
  dataFile.print(bme_2.humidity); dataFile.print(F(","));
  dataFile.print(bme_2.gas_resistance / 1000.0); dataFile.print(F(","));
  dataFile.print(String(air_quality_score_2)); dataFile.print(F(","));
  dataFile.print(CalculateAQI(air_quality_score_2)); dataFile.print(F(","));
  dataFile.println(bme_2.readAltitude(SEALEVELPRESSURE_HPA));
  dataFile.close();
  digitalWrite(LED_GREEN, LOW);

  //print on Serial Monitor
  digitalWrite(LED_RED, HIGH);
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(F(","));
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println(F(";"));
  Serial.println(F("***BME_1***"));
  Serial.print(F("Temperature = "));
  Serial.print(bme_1.temperature);
  Serial.println(F(" *C"));

  Serial.print(F("Pressure = "));
  Serial.print(bme_1.pressure / 100.0);
  Serial.println(F(" hPa"));

  Serial.print(F("Humidity = "));
  Serial.print(bme_1.humidity);
  Serial.println(F(" %"));

  Serial.print(F("Gas = "));
  Serial.print(bme_1.gas_resistance / 1000.0);
  Serial.println(F(" KOhms"));

  Serial.print(F("Air Quality = "));
  Serial.print(String(air_quality_score_1));
  Serial.print(F(" % - "));
  Serial.println(CalculateAQI(air_quality_score_1));
  Serial.print("Humidity element was : ");
  Serial.print((hum_score_1 / 100));
  Serial.println( " of 0.25");
  Serial.print("Gas element was : ");
  Serial.print((gas_score_1 / 100));
  Serial.println(" of 0.75");

  Serial.print(F("Approx. Altitude = "));
  Serial.print(bme_1.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(F(" m"));

  Serial.println(F("***BME_2***"));
  Serial.print(F("Temperature = "));
  Serial.print(bme_2.temperature);
  Serial.println(F(" *C"));

  Serial.print(F("Pressure = "));
  Serial.print(bme_2.pressure / 100.0);
  Serial.println(F(" hPa"));

  Serial.print(F("Humidity = "));
  Serial.print(bme_2.humidity);
  Serial.println(F(" %"));

  Serial.print(F("Gas = "));
  Serial.print(bme_2.gas_resistance / 1000.0);
  Serial.println(F(" KOhms"));

  Serial.print(F("Air Quality = "));
  Serial.print(String(air_quality_score_2));
  Serial.print(F(" % - "));
  Serial.println(CalculateAQI(air_quality_score_2));
  Serial.print("Humidity element was : ");
  Serial.print((hum_score_2 / 100));
  Serial.println( " of 0.25");
  Serial.print("Gas element was : ");
  Serial.print((gas_score_2 / 100));
  Serial.println(" of 0.75");

  Serial.print(F("Approx. Altitude = "));
  Serial.print(bme_2.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(F(" m"));
  Serial.println();
  digitalWrite(LED_RED, LOW);
  delay(measurement_frequency);

}

float GetGasReference() {
  // Now run the sensor for a burn-in period, then use combination of relative humidity and gas resistance to estimate indoor air quality as a percentage.
  int readings = 10;
  //BME_1
  for (int i = 1; i <= readings; i++) { // read gas for 10 x 0.150mS = 1.5secs
    gas_reference_1 += bme_1.readGas();
  }
  float gas_reference_1 = gas_reference_1 / readings;
  //BME_2
  for (int i = 1; i <= readings; i++) { // read gas for 10 x 0.150mS = 1.5secs
    gas_reference_2 += bme_2.readGas();
  }
  float gas_reference_2 = gas_reference_2 / readings;
}

String CalculateAQI(float score) {  //calculates score of AQI into text to describe AQ
  String AQI_text;
  score = (100 - score) * 5;
  if      (score >= 301)                  AQI_text = "Hazardous";
  else if (score >= 201 && score <= 300 ) AQI_text = "Very Unhealthy";
  else if (score >= 176 && score <= 200 ) AQI_text = "Unhealthy";
  else if (score >= 151 && score <= 175 ) AQI_text = "Unhealthy for Sensitive Groups";
  else if (score >=  51 && score <= 150 ) AQI_text = "Moderate";
  else if (score >=  00 && score <=  50 ) AQI_text = "Good";
  return AQI_text;
}

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

Re: Connecting two BM680 sensors, RTC DS1307 via I2C on Arudino UNO

Post by dastels »

Nothing jumps out at me.

How you have them connected?

Can you post output from the code?

Dave

Post Reply
Please be positive and constructive with your questions and comments.

Return to “Arduino”